ConE 1.2.11 release
authorm2lahtel
Tue, 10 Aug 2010 14:29:28 +0300
changeset 3 e7e0ae78773e
parent 2 87cfa131b535
child 4 0951727b8815
child 6 5b32dc297d05
ConE 1.2.11 release
configurationengine/RELEASE.TXT
configurationengine/build-scripts/export_bat.py
configurationengine/build-scripts/install_cone.py
configurationengine/build-scripts/utils.py
configurationengine/build.xml
configurationengine/common.properties
configurationengine/debian/control
configurationengine/debian/copyright
configurationengine/dep-eggs/Jinja2-2.1.1-py2.5-win32.egg
configurationengine/dep-eggs/Jinja2-2.1.1-py2.6-win32.egg
configurationengine/doc/api/api.rst
configurationengine/doc/api/howto.rst
configurationengine/doc/api/plugin.rst
configurationengine/doc/api/public.rst
configurationengine/doc/cli/common.rst
configurationengine/doc/cli/compare.rst
configurationengine/doc/cli/export.rst
configurationengine/doc/cli/fix.rst
configurationengine/doc/cli/initvariant.rst
configurationengine/doc/cli/rootflatten.rst
configurationengine/doc/cli/validate.rst
configurationengine/doc/conf.py
configurationengine/doc/development.rst
configurationengine/doc/extref.rst
configurationengine/doc/index.rst
configurationengine/doc/intro.rst
configurationengine/doc/plugins/commandml-plugin/commandml.rst
configurationengine/doc/plugins/convertprojectplugin.rst
configurationengine/doc/plugins/dev-plugin/confml-validation-classes.jpg
configurationengine/doc/plugins/dev-plugin/diagrams.uml
configurationengine/doc/plugins/dev-plugin/example-plugin.rst
configurationengine/doc/plugins/dev-plugin/impl-validation-classes.jpg
configurationengine/doc/plugins/dev-plugin/index.rst
configurationengine/doc/plugins/dev-plugin/model-validation.uml
configurationengine/doc/plugins/dev-plugin/plugin-interface.rst
configurationengine/doc/plugins/dev-plugin/plugin_classes.jpg
configurationengine/doc/plugins/dev-plugin/validation-example-plugin.rst
configurationengine/doc/plugins/dev-plugin/validation-plugin-index.rst
configurationengine/doc/plugins/general.rst
configurationengine/doc/plugins/imageml-plugin/examples/bmp_and_optional_mask.imageml
configurationengine/doc/plugins/imageml-plugin/examples/multi_input.imageml
configurationengine/doc/plugins/imageml-plugin/examples/simple.imageml
configurationengine/doc/plugins/imageml-plugin/examples/with_refs.imageml
configurationengine/doc/plugins/imageml-plugin/imageml-example-project.zip
configurationengine/doc/plugins/imageml-plugin/imageml-plugin.rst
configurationengine/doc/plugins/imageml-plugin/imageml.jpg
configurationengine/doc/plugins/index.rst
configurationengine/doc/plugins/plugins.uml
configurationengine/doc/plugins/ruleml-plugin/ruleplugin.rst
configurationengine/doc/plugins/templateml-plugin/templatemlplugin.rst
configurationengine/doc/xsd/confml2.xsd
configurationengine/linux.properties
configurationengine/source/cone.cmd
configurationengine/source/cone.sh
configurationengine/source/cone/__init__.py
configurationengine/source/cone/action/__init__.py
configurationengine/source/cone/action/configroot2flat.py
configurationengine/source/cone/action/fix.py
configurationengine/source/cone/action/loader.py
configurationengine/source/cone/action/tests/__init__.py
configurationengine/source/cone/action/tests/unittest_configroot2flat.py
configurationengine/source/cone/action/tests/unittest_fix.py
configurationengine/source/cone/action/tests/unittest_loader.py
configurationengine/source/cone/carbon/model.py
configurationengine/source/cone/carbon/persistentjson.py
configurationengine/source/cone/carbon/resourcemapper.py
configurationengine/source/cone/carbon/tests/__init__.py
configurationengine/source/cone/carbon/tests/runtests.py
configurationengine/source/cone/carbon/tests/unittest_mapping.py
configurationengine/source/cone/carbon/tests/unittest_model.py
configurationengine/source/cone/carbon/tests/unittest_resourcemapper.py
configurationengine/source/cone/confml/model.py
configurationengine/source/cone/confml/persistentconfml.py
configurationengine/source/cone/confml/tests/__init__.py
configurationengine/source/cone/confml/tests/data/multiselection.confml
configurationengine/source/cone/confml/tests/runtests.py
configurationengine/source/cone/confml/tests/testdata/read_write/basic_setting_types_test.confml
configurationengine/source/cone/confml/tests/testdata/read_write/configuration_version_test.confml
configurationengine/source/cone/confml/tests/testdata/read_write/data.confml
configurationengine/source/cone/confml/tests/testdata/read_write/empty_attributes_test.confml
configurationengine/source/cone/confml/tests/testdata/read_write/facets.confml
configurationengine/source/cone/confml/tests/testdata/read_write/feature1.confml
configurationengine/source/cone/confml/tests/testdata/read_write/name_id_mapping_test.confml
configurationengine/source/cone/confml/tests/testdata/read_write/view.confml
configurationengine/source/cone/confml/tests/testdata/seq_template/expected/complex_seq.confml
configurationengine/source/cone/confml/tests/testdata/seq_template/expected/complex_seq_with_nones.confml
configurationengine/source/cone/confml/tests/testdata/seq_template/expected/simple_seq.confml
configurationengine/source/cone/confml/tests/testdata/seq_template/expected/simple_seq_no_template.confml
configurationengine/source/cone/confml/tests/unittest_confmlxml.py
configurationengine/source/cone/confml/tests/unittest_implml.py
configurationengine/source/cone/confml/tests/unittest_mapping.py
configurationengine/source/cone/confml/tests/unittest_model.py
configurationengine/source/cone/confml/tests/unittest_persistentconfml.py
configurationengine/source/cone/core/tests/__init__.py
configurationengine/source/cone/core/tests/runtests.py
configurationengine/source/cone/core/tests/testdata/layered_res_test.zip
configurationengine/source/cone/core/tests/testdata/test_project.cpf
configurationengine/source/cone/core/tests/unittest_configuration.py
configurationengine/source/cone/core/tests/unittest_configuration_project_edit_data.py
configurationengine/source/cone/core/tests/unittest_configuration_project_export.py
configurationengine/source/cone/core/tests/unittest_configuration_project_import.py
configurationengine/source/cone/core/tests/unittest_configuration_project_on_filestorage.py
configurationengine/source/cone/core/tests/unittest_configuration_project_on_zipstorage.py
configurationengine/source/cone/public/_etree_wrapper.py
configurationengine/source/cone/public/_plugin_reader.py
configurationengine/source/cone/public/api.py
configurationengine/source/cone/public/container.py
configurationengine/source/cone/public/exceptions.py
configurationengine/source/cone/public/parsecontext.py
configurationengine/source/cone/public/plugin.py
configurationengine/source/cone/public/rules.py
configurationengine/source/cone/public/tests/Import.pk
configurationengine/source/cone/public/tests/__init__.py
configurationengine/source/cone/public/tests/runtests.py
configurationengine/source/cone/public/tests/test_defaults.cfg
configurationengine/source/cone/public/tests/testdata/layer1/implml/test.implml
configurationengine/source/cone/public/tests/testdata/view_tests/customisation/confml/data.confml
configurationengine/source/cone/public/tests/testdata/view_tests/customisation/confml/my_standard_view.confml
configurationengine/source/cone/public/tests/testdata/view_tests/customisation/root_standard.confml
configurationengine/source/cone/public/tests/testdata/view_tests/unit-test/confml/mailboxes.confml
configurationengine/source/cone/public/tests/testdata/view_tests/unit-test/confml/options_test.confml
configurationengine/source/cone/public/tests/testdata/view_tests/unit-test/confml/unit-test.confml
configurationengine/source/cone/public/tests/testdata/view_tests/unit-test/root.confml
configurationengine/source/cone/public/tests/testdata/view_tests/view_tests-cpf.confml
configurationengine/source/cone/public/tests/unittest_base.py
configurationengine/source/cone/public/tests/unittest_configuration.py
configurationengine/source/cone/public/tests/unittest_container.py
configurationengine/source/cone/public/tests/unittest_data.py
configurationengine/source/cone/public/tests/unittest_feature.py
configurationengine/source/cone/public/tests/unittest_layer.py
configurationengine/source/cone/public/tests/unittest_mapping.py
configurationengine/source/cone/public/tests/unittest_options.py
configurationengine/source/cone/public/tests/unittest_persistence.py
configurationengine/source/cone/public/tests/unittest_plugin_api.py
configurationengine/source/cone/public/tests/unittest_plugin_implcontainer.py
configurationengine/source/cone/public/tests/unittest_plugin_reader.py
configurationengine/source/cone/public/tests/unittest_problem.py
configurationengine/source/cone/public/tests/unittest_project.py
configurationengine/source/cone/public/tests/unittest_property.py
configurationengine/source/cone/public/tests/unittest_public_api.py
configurationengine/source/cone/public/tests/unittest_rules.py
configurationengine/source/cone/public/tests/unittest_rules_on_configuration.py
configurationengine/source/cone/public/tests/unittest_rules_simplecondition.py
configurationengine/source/cone/public/tests/unittest_settings.py
configurationengine/source/cone/public/tests/unittest_storage.py
configurationengine/source/cone/public/tests/unittest_utils.py
configurationengine/source/cone/public/tests/unittest_valueset.py
configurationengine/source/cone/public/tests/unittest_views.py
configurationengine/source/cone/public/tests/unittest_xml_parsing.py
configurationengine/source/cone/public/utils.py
configurationengine/source/cone/report/__init__.py
configurationengine/source/cone/report/generation_report.py
configurationengine/source/cone/report/report_util.py
configurationengine/source/cone/report/tests/project/layer1/confml/accessoryserver.confml
configurationengine/source/cone/report/tests/project/layer1/confml/feature1.confml
configurationengine/source/cone/report/tests/project/layer1/implml/accessoryserver_1020505A.implml
configurationengine/source/cone/report/tests/project/layer1/implml/test.implml
configurationengine/source/cone/report/tests/project/layer1/root.confml
configurationengine/source/cone/report/tests/project/root.confml
configurationengine/source/cone/report/tests/unittest_report.py
configurationengine/source/cone/runtests.py
configurationengine/source/cone/storage/authenticate.py
configurationengine/source/cone/storage/common.py
configurationengine/source/cone/storage/filestorage.py
configurationengine/source/cone/storage/metadata.py
configurationengine/source/cone/storage/stringstorage.py
configurationengine/source/cone/storage/tests/__init__.py
configurationengine/source/cone/storage/tests/fileres_test/test_getsize.txt
configurationengine/source/cone/storage/tests/runtests.py
configurationengine/source/cone/storage/tests/unittest_authenticate.py
configurationengine/source/cone/storage/tests/unittest_fileresource.py
configurationengine/source/cone/storage/tests/unittest_filestorage.py
configurationengine/source/cone/storage/tests/unittest_filestorage_layer.py
configurationengine/source/cone/storage/tests/unittest_filestorage_vs_zipstorage.py
configurationengine/source/cone/storage/tests/unittest_metadata.py
configurationengine/source/cone/storage/tests/unittest_resource.py
configurationengine/source/cone/storage/tests/unittest_stringstorage.py
configurationengine/source/cone/storage/tests/unittest_webstorage.py
configurationengine/source/cone/storage/tests/unittest_webstorage_carbon.py
configurationengine/source/cone/storage/tests/unittest_zipresource.py
configurationengine/source/cone/storage/tests/unittest_zipstorage.py
configurationengine/source/cone/storage/webstorage.py
configurationengine/source/cone/storage/zipstorage.py
configurationengine/source/cone/test.xml
configurationengine/source/cone/validation/__init__.py
configurationengine/source/cone/validation/builtinvalidators/__init__.py
configurationengine/source/cone/validation/builtinvalidators/confml.py
configurationengine/source/cone/validation/builtinvalidators/implml.py
configurationengine/source/cone/validation/builtinvalidators/tests/__init__.py
configurationengine/source/cone/validation/builtinvalidators/tests/runtests.py
configurationengine/source/cone/validation/builtinvalidators/tests/unittest_confmlfixer.py
configurationengine/source/cone/validation/builtinvalidators/tests/unittest_confmlvalidation.py
configurationengine/source/cone/validation/common.py
configurationengine/source/cone/validation/confml_xsd/XInclude.xsd
configurationengine/source/cone/validation/confml_xsd/XMLSchema.xsd
configurationengine/source/cone/validation/confml_xsd/confml.xsd
configurationengine/source/cone/validation/confml_xsd/confml2.xsd
configurationengine/source/cone/validation/confml_xsd/xlink.xsd
configurationengine/source/cone/validation/confml_xsd/xml.xsd
configurationengine/source/cone/validation/confmlvalidation.py
configurationengine/source/cone/validation/implml_xsd/default-impl-schema-template.xsd
configurationengine/source/cone/validation/implml_xsd/implml-template.xsd
configurationengine/source/cone/validation/implmlvalidation.py
configurationengine/source/cone/validation/parsecontext.py
configurationengine/source/cone/validation/problem_type_filter.py
configurationengine/source/cone/validation/schemavalidation.py
configurationengine/source/cone/validation/tests/__init__.py
configurationengine/source/cone/validation/tests/runtests.py
configurationengine/source/cone/validation/tests/testdata/model/confml/fixed_expected/duplicate_root.confml
configurationengine/source/cone/validation/tests/testdata/model/confml/fixed_expected/duplicate_settings1.confml
configurationengine/source/cone/validation/tests/testdata/model/confml/fixed_expected/duplicate_settings2.confml
configurationengine/source/cone/validation/tests/testdata/model/confml/single_files/data_without_feature.confml
configurationengine/source/cone/validation/tests/testdata/model/confml/single_files/duplicate_root.confml
configurationengine/source/cone/validation/tests/testdata/model/confml/single_files/duplicate_settings1.confml
configurationengine/source/cone/validation/tests/testdata/model/confml/single_files/duplicate_settings2.confml
configurationengine/source/cone/validation/tests/testdata/model/confml/single_files/min_max_length.confml
configurationengine/source/cone/validation/tests/testdata/model/confml/single_files_expected/data_without_feature.confml.txt
configurationengine/source/cone/validation/tests/testdata/model/confml/single_files_expected/duplicate_root.confml.txt
configurationengine/source/cone/validation/tests/testdata/model/confml/single_files_expected/min_max_length.confml.txt
configurationengine/source/cone/validation/tests/testdata/model/implml/expected/duplicate_tempvar_ref.implml.txt
configurationengine/source/cone/validation/tests/testdata/model/implml/project/Layer1/implml/duplicate_tempvar_ref.implml
configurationengine/source/cone/validation/tests/testdata/model/implml/project/Layer1/root.confml
configurationengine/source/cone/validation/tests/testdata/model/implml/project/root.confml
configurationengine/source/cone/validation/tests/testdata/schema/confml1/invalid/invalid_type.confml
configurationengine/source/cone/validation/tests/testdata/schema/confml1/valid/feature1.confml
configurationengine/source/cone/validation/tests/testdata/schema/confml1/valid/feature2.confml
configurationengine/source/cone/validation/tests/testdata/schema/confml1/valid/name_id_mapping_test.confml
configurationengine/source/cone/validation/tests/testdata/schema/confml2/invalid/invalid_type.confml
configurationengine/source/cone/validation/tests/testdata/schema/confml2/valid/basic_setting_types_test.confml
configurationengine/source/cone/validation/tests/testdata/schema/confml2/valid/file_folder_test.confml
configurationengine/source/cone/validation/tests/testdata/schema/confml2/valid/name_id_mapping_test.confml
configurationengine/source/cone/validation/tests/testdata/schema/confml2/valid/product_root.confml
configurationengine/source/cone/validation/tests/testdata/schema/confml2/valid/relevant_feature_test.confml
configurationengine/source/cone/validation/tests/testdata/schema/confml2/valid/sequence_setting_test.confml
configurationengine/source/cone/validation/tests/testdata/schema/confml2/valid/time_types_test.confml
configurationengine/source/cone/validation/tests/testdata/schema/confml2/valid/view.confml
configurationengine/source/cone/validation/tests/testdata/schema/implml/invalid/empty_temp_variable_sequence.implml
configurationengine/source/cone/validation/tests/testdata/schema/implml/invalid/output_root_dir_without_value.implml
configurationengine/source/cone/validation/tests/testdata/schema/implml/invalid/output_sub_dir_without_value.implml
configurationengine/source/cone/validation/tests/testdata/schema/implml/invalid/phase_without_value.implml
configurationengine/source/cone/validation/tests/testdata/schema/implml/invalid/setting_refs_override_without_value.implml
configurationengine/source/cone/validation/tests/testdata/schema/implml/invalid/tag_without_value.implml
configurationengine/source/cone/validation/tests/testdata/schema/implml/invalid/temp_variable_sequence_without_ref.implml
configurationengine/source/cone/validation/tests/testdata/schema/implml/invalid/temp_variable_without_ref.implml
configurationengine/source/cone/validation/tests/testdata/schema/implml/valid/dummy.dummy1ml
configurationengine/source/cone/validation/tests/testdata/schema/implml/valid/dummy.dummy2ml
configurationengine/source/cone/validation/tests/testdata/schema/implml/valid/empty.implml
configurationengine/source/cone/validation/tests/testdata/schema/implml/valid/empty_with_all_common_elements.implml
configurationengine/source/cone/validation/tests/testdata/schema/implml/valid/empty_with_condition.implml
configurationengine/source/cone/validation/tests/testdata/schema/implml/valid/empty_with_condition_and_value.implml
configurationengine/source/cone/validation/tests/testdata/schema/implml/valid/multi_impl_1.implml
configurationengine/source/cone/validation/tests/testdata/schema/implml/valid/multi_impl_2.implml
configurationengine/source/cone/validation/tests/testdata/schema/implml/valid/multi_impl_3.implml
configurationengine/source/cone/validation/tests/testdata/schema/implml/valid/multi_impl_4.implml
configurationengine/source/cone/validation/tests/testdata/schema/implml/valid/multi_impl_5.implml
configurationengine/source/cone/validation/tests/testdata/schema/implml/valid/nested_containers.implml
configurationengine/source/cone/validation/tests/unittest_confmlfixing.py
configurationengine/source/cone/validation/tests/unittest_confmlvalidation.py
configurationengine/source/cone/validation/tests/unittest_implmlvalidation.py
configurationengine/source/cone/validation/tests/unittest_problem_type_filter.py
configurationengine/source/cone/validation/tests/unittest_schemavalidation.py
configurationengine/source/dev-tools/depfea.cmd
configurationengine/source/dev-tools/deprfea.py
configurationengine/source/plugins/build_egg_info.py
configurationengine/source/plugins/common/ConeCommandPlugin/__init__.py
configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/commandml.py
configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/__init__.py
configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/project/assets/s60/implml/file2.commandml
configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/project/assets/s60/implml/file3.commandml
configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/project/tools/helloworld.py
configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/project/tools/print_hello.py
configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/runtests.py
configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/unittest_commandml_plugin.py
configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/unittest_commandml_utils.py
configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/unittest_parse_commandml.py
configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/unittest_read_temp_variable.py
configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/xsd/commandml.xsd
configurationengine/source/plugins/common/ConeCommandPlugin/setup.py
configurationengine/source/plugins/common/ConeContentPlugin/__init__.py
configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/contentml.py
configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/contentmlparser.py
configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/__init__.py
configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/confml/content.confml
configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/implml/empty_input_file_from_sequence.content
configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/implml/test_external_input.content
configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/family/product/content/test/test_CAP_letters.txt
configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/runtests.py
configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/testdata/emptydircopy/external_content.zip
configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/testdata/emptydircopy/project.zip
configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/unittest_confmlrefs.py
configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/unittest_content_copy.py
configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/unittest_content_copy_empty_dirs.py
configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/unittest_content_parseimpl.py
configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/unittest_content_plugin.py
configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/xsd/contentml.xsd
configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/xsd/contentml2.xsd
configurationengine/source/plugins/common/ConeContentPlugin/setup.py
configurationengine/source/plugins/common/ConeLegacyRulePlugin/__init__.py
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/__init__.py
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/__init__.py
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/accesspoint_id_counter.py
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/layer_utils.py
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/shortcuts_conversion.py
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/__init__.py
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/layerproject/layer1/confml/test.confml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/layerproject/layer1/implml/test1.ruleml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/layerproject/layer1/root.confml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/layerproject/layer2/confml/test.confml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/layerproject/layer2/root.confml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/layerproject/layer3/confml/test.confml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/layerproject/layer3/root.confml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/layerproject/layer4/confml/test.confml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/layerproject/layer4/root.confml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/layerproject/layer5/confml/test.confml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/layerproject/layer5/root.confml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/layerproject/root.confml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/ruleproject/ctd/confml/CTD_commsdat.confml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/ruleproject/ctd/root.confml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/ruleproject/layer1/.metadata
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/ruleproject/layer1/confml/ap.confml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/ruleproject/layer1/confml/commsdatcreator.confml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/ruleproject/layer1/confml/testdata.confml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/ruleproject/layer1/implml/accesspoint_id_counter.ruleml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/ruleproject/layer1/root.confml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/ruleproject/layer2/.metadata
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/ruleproject/layer2/confml/data.confml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/ruleproject/layer2/root.confml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/ruleproject/root.confml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/runtests.py
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/unittest_accesspoint_id_counter.py
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/unittest_layer_utils.py
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/relations.py
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/ruleml.py
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/rules.py
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/__init__.py
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/errorruleproject/test1/confml/testdata.confml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/errorruleproject/test1/implml/terminalexpression.ruleml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/errorruleproject/test1/root.confml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/errorruleproject/test2/confml/invalid_python_eval.confml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/errorruleproject/test2/implml/invalid_python_eval.ruleml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/errorruleproject/test2/root.confml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/errorruleproject/test3/confml/invalid_python_eval.confml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/errorruleproject/test3/implml/invalid_python_eval.ruleml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/errorruleproject/test3/implml/scripts/test_eval.py
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/errorruleproject/test3/root.confml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/errorruleproject/test4/confml/invalid_python_eval.confml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/errorruleproject/test4/implml/invalid_python_eval.ruleml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/errorruleproject/test4/root.confml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/errorruleproject/test5/confml/invalid_python_eval.confml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/errorruleproject/test5/implml/invalid_python_eval.ruleml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/errorruleproject/test5/implml/scripts/test_eval.py
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/errorruleproject/test5/root.confml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/errorruleproject/test6/confml/invalid_python_eval.confml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/errorruleproject/test6/implml/invalid_python_eval.ruleml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/errorruleproject/test6/root.confml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/rule/config_project/.metadata
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/rule/config_project/.project
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/rule/config_project/platforms/customsw/.metadata
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/rule/config_project/platforms/customsw/confml/actionpriorities.confml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/rule/config_project/platforms/customsw/implml/gsm.ruleml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/rule/config_project/platforms/customsw/root.confml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/ruleproject/rules/.metadata
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/ruleproject/rules/confml/arithmetic.confml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/ruleproject/rules/confml/commsdatcreator.confml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/ruleproject/rules/confml/comparison_operators.confml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/ruleproject/rules/confml/eval.confml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/ruleproject/rules/confml/filename_testdata.confml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/ruleproject/rules/confml/testdata.confml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/ruleproject/rules/implml/arithmetic.ruleml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/ruleproject/rules/implml/commsdat.ruleml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/ruleproject/rules/implml/comparison_operators.ruleml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/ruleproject/rules/implml/container_with_rules.ruleml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/ruleproject/rules/implml/eval.ruleml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/ruleproject/rules/implml/filename_rules.ruleml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/ruleproject/rules/implml/rules.ruleml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/ruleproject/rules/implml/scripts/test_eval.py
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/ruleproject/rules/root.confml
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/runtests.py
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/unittest_eval.py
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/unittest_parseruleml.py
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/unittest_rule_empty_plugin.py
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/unittest_rule_plugin.py
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/unittest_rule_plugin_errors.py
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/unittest_rules.py
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/xsd/ruleml.xsd
configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/xsd/ruleml2.xsd
configurationengine/source/plugins/common/ConeLegacyRulePlugin/setup.cfg
configurationengine/source/plugins/common/ConeLegacyRulePlugin/setup.py
configurationengine/source/plugins/common/ConeRulePlugin/__init__.py
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/__init__.py
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/accesspoint_id_counter.py
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/layer_utils.py
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/shortcuts_conversion.py
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/__init__.py
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/base/confml/test_feature.confml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/base/content/layer7/foo.txt
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/base/content/layer9/bar.txt
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/base/content/layer9/foo.txt
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/base/content/test.txt
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/base/implml/base.templateml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/base/implml/layer1.templateml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/base/implml/layer10.content
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/base/implml/layer11.implml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/base/implml/layer2.templateml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/base/implml/layer3.templateml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/base/implml/layer4.content
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/base/implml/layer5.content
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/base/implml/layer6.implml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/base/implml/layer7.implml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/base/implml/layer8.implml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/base/implml/layer9.implml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/base/implml/uses_layers_test.ruleml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/base/root.confml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/layer1/confml/data.confml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/layer1/root.confml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/layer10/confml/data.confml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/layer10/content/layer10/foo.txt
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/layer10/root.confml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/layer11/confml/data.confml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/layer11/root.confml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/layer2/confml/data.confml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/layer2/root.confml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/layer3/confml/data.confml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/layer3/root.confml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/layer4/confml/data.confml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/layer4/root.confml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/layer5/confml/data.confml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/layer5/root.confml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/layer6/confml/data.confml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/layer6/root.confml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/layer7/confml/data.confml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/layer7/root.confml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/layer8/confml/data.confml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/layer8/root.confml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/layer9/confml/data.confml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/layer9/root.confml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/root.confml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layerproject/foo/bar/customer/custvariant_123_xyz/configurator/confml/test.confml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layerproject/foo/bar/customer/custvariant_123_xyz/configurator/root.confml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layerproject/foo/bar/customer/custvariant_123_xyz/manual/confml/test.confml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layerproject/foo/bar/customer/custvariant_123_xyz/manual/root.confml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layerproject/foo/bar/rnd/confml/test.confml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layerproject/foo/bar/rnd/root.confml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layerproject/foobar_root.confml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layerproject/layer1/confml/test.confml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/ruleproject/layer2/confml/data.confml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/runtests.py
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/unittest_accesspoint_id_counter.py
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/unittest_layer_utils.py
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/relations.py
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/ruleml.py
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/__init__.py
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test1/implml/terminalexpression.ruleml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test2/implml/invalid_python_eval.ruleml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test3/implml/invalid_python_eval.ruleml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test4/implml/invalid_python_eval.ruleml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test5/implml/invalid_python_eval.ruleml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test6/implml/invalid_python_eval.ruleml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/confml/eval.confml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/confml/testdata.confml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/implml/arithmetic.ruleml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/implml/commsdat.ruleml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/implml/comparison_operators.ruleml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/implml/container_with_rules.ruleml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/implml/eval.ruleml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/implml/eval_generation_context.ruleml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/implml/filename_rules.ruleml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/implml/rules.ruleml
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/implml/scripts/test_eval_generation_context.py
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/runtests.py
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/unittest_eval.py
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/unittest_parseruleml.py
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/unittest_rule_empty_plugin.py
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/unittest_rule_plugin.py
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/unittest_rule_plugin_errors.py
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/unittest_rules.py
configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/xsd/ruleml3.xsd
configurationengine/source/plugins/common/ConeRulePlugin/setup.py
configurationengine/source/plugins/common/ConeTemplatePlugin/setup.py
configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/templatemlplugin.py
configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/__init__.py
configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/create_dict_test/expected_list.txt
configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/create_dict_test/expected_tree.txt
configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/Layer1/implml/access_context.templateml
configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/Layer1/implml/feat_tree_iteration_test.templateml
configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/Layer1/implml/file1.templateml
configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/Layer1/implml/invalid_ref.templateml
configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/Layer1/implml/newline.templateml
configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/runtests.py
configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/unittest_templatemlplugin.py
configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/xsd/templateml.xsd
configurationengine/source/plugins/common/integration-test/__init__.py
configurationengine/source/plugins/common/integration-test/export_standalone.py
configurationengine/source/plugins/common/integration-test/runtests.py
configurationengine/source/plugins/common/integration-test/testdata/generate/expected/test.txt
configurationengine/source/plugins/common/integration-test/testdata/generate/project/custom/implml/unicode_rule_test.ruleml
configurationengine/source/plugins/common/integration-test/testdata/generate/project/custom/implml/xcreate_file.implml
configurationengine/source/plugins/common/integration-test/testdata/templateml_test_project/layer/confml/feature1.confml
configurationengine/source/plugins/common/integration-test/testdata/templateml_test_project/layer/implml/output_test.implml
configurationengine/source/plugins/common/integration-test/testdata/templateml_test_project/layer/root.confml
configurationengine/source/plugins/common/integration-test/testdata/templateml_test_project/root.confml
configurationengine/source/plugins/common/integration-test/testdata/uses_layers_test_expected.txt
configurationengine/source/plugins/common/integration-test/unittest_generate.py
configurationengine/source/plugins/common/runtests.py
configurationengine/source/plugins/example/ConeExamplePlugin/__init__.py
configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/exampleml_impl.py
configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/exampleml_model.py
configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/exampleml_reader.py
configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/exampleml_validators.py
configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/__init__.py
configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/gen_expected/multitest1_1.txt
configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/gen_expected/multitest1_2.txt
configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/gen_expected/multitest2_1.txt
configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/gen_expected/multitest2_2.txt
configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/gen_expected/some/dir/out1.txt
configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/gen_expected/some/dir2/out2.txt
configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/gen_expected/test.txt
configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/project/Layer/confml/test.confml
configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/project/Layer/implml/multitest.implml
configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/project/Layer/implml/test.exampleml
configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/project/Layer/root.confml
configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/project/root.confml
configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/runtests.py
configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/testdata/generation/expected/multitest1_1.txt
configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/testdata/generation/expected/multitest1_2.txt
configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/testdata/generation/expected/multitest2_1.txt
configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/testdata/generation/expected/multitest2_2.txt
configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/testdata/generation/expected/some/dir/out1.txt
configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/testdata/generation/expected/some/dir2/out2.txt
configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/testdata/generation/expected/test.txt
configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/testdata/generation/project/Layer/confml/test.confml
configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/testdata/generation/project/Layer/implml/multitest.implml
configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/testdata/generation/project/Layer/implml/test.exampleml
configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/testdata/generation/project/Layer/root.confml
configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/testdata/generation/project/root.confml
configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/testdata/validation/expected/invalid_encoding.exampleml.txt
configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/testdata/validation/expected/invalid_refs.exampleml.txt
configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/testdata/validation/project/Layer1/confml/invalid_encoding.confml
configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/testdata/validation/project/Layer1/implml/invalid_encoding.exampleml
configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/testdata/validation/project/Layer1/implml/invalid_refs.exampleml
configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/testdata/validation/project/Layer1/root.confml
configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/testdata/validation/project/root.confml
configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/testdata/validation/schema/invalid/missing_output_file.exampleml
configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/testdata/validation/schema/valid/test.exampleml
configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/unittest_exampleml_generation.py
configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/unittest_exampleml_impl.py
configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/unittest_exampleml_reader.py
configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/unittest_exampleml_validation.py
configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/xsd/exampleml.xsd
configurationengine/source/plugins/example/ConeExamplePlugin/setup.py
configurationengine/source/plugins/example/ConeExampleValidatorPlugin/examplevalidatorplugin/__init__.py
configurationengine/source/plugins/example/ConeExampleValidatorPlugin/examplevalidatorplugin/tests/__init__.py
configurationengine/source/plugins/example/ConeExampleValidatorPlugin/examplevalidatorplugin/tests/runtests.py
configurationengine/source/plugins/example/ConeExampleValidatorPlugin/examplevalidatorplugin/tests/testdata/expected.txt
configurationengine/source/plugins/example/ConeExampleValidatorPlugin/examplevalidatorplugin/tests/testdata/test.confml
configurationengine/source/plugins/example/ConeExampleValidatorPlugin/examplevalidatorplugin/tests/unittest_validation.py
configurationengine/source/plugins/example/ConeExampleValidatorPlugin/examplevalidatorplugin/validators.py
configurationengine/source/plugins/example/ConeExampleValidatorPlugin/setup.cfg
configurationengine/source/plugins/example/ConeExampleValidatorPlugin/setup.py
configurationengine/source/plugins/example/integration-test/__init__.py
configurationengine/source/plugins/example/integration-test/runtests.py
configurationengine/source/plugins/example/integration-test/testdata/generate/project/Layer/implml/multitest.implml
configurationengine/source/plugins/example/integration-test/unittest_generate.py
configurationengine/source/plugins/example/runtests.py
configurationengine/source/plugins/nose_unittests.cfg
configurationengine/source/plugins/plugin_utils.py
configurationengine/source/plugins/runtests.py
configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/crml_impl.py
configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/crml_model.py
configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/crml_reader.py
configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/crml_validators.py
configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/crml_writer.py
configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/__init__.py
configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/0000000E.txt
configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected_deltacenrep/00000002.txt
configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected_deltacenrep/00000003.txt
configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected_deltacenrep/00000005.txt
configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected_deltacenrep/00000006.txt
configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/deltacenrep_iby.implml
configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer2/confml/data.confml
configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer2/root.confml
configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/root2.confml
configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/runtests.py
configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/unittest_crml_comparator.py
configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/unittest_crml_impl.py
configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/unittest_crml_model.py
configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/unittest_crml_reader.py
configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/unittest_crml_validation.py
configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/unittest_crml_writer.py
configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/unittest_txt_generation.py
configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/validation_expected/00000002_invalid_refs.crml.txt
configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/validation_expected/00000003_duplicate_uids.crml.txt
configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/validation_project/Layer1/confml/duplicate_uids.confml
configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/validation_project/Layer1/confml/invalid_capabilities.confml
configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/validation_project/Layer1/confml/multiple_access_definitions.confml
configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/validation_project/Layer1/implml/00000002_invalid_refs.crml
configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/validation_project/Layer1/implml/00000003_duplicate_uids.crml
configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/validation_project/Layer1/implml/00000004_invalid_capabilities.crml
configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/validation_project/Layer1/implml/00000005_multiple_access_definitions.crml
configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/validation_project/Layer1/root.confml
configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/validation_project/root.confml
configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/xsd/crml.xsd
configurationengine/source/plugins/symbian/ConeCRMLPlugin/__init__.py
configurationengine/source/plugins/symbian/ConeCRMLPlugin/setup.py
configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/confflattener.py
configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/genconfmlplugin.py
configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/__init__.py
configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root1/endline_crlf.txt
configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root1/endline_lf.txt
configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root2/endline_crlf.txt
configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root2/endline_lf.txt
configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root3/endline_crlf.txt
configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root3/endline_lf.txt
configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root4/endline_crlf.txt
configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root4/endline_lf.txt
configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer1/implml/line_ending_conversion_crlf.gcfml
configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer1/implml/line_ending_conversion_lf.gcfml
configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/assets/s60/implml/commsdatcreator_01.gcfml
configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/runtests.py
configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/unittest_confflattener.py
configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/unittest_gcfml_plugin.py
configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/unittest_generation.py
configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/unittest_xslttransformer.py
configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/xsd/gcfml.xsd
configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/xslttransformer.py
configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/setup.py
configurationengine/source/plugins/symbian/ConeHCRPlugin/__init__.py
configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/hcr_writer.py
configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/hcrml_parser.py
configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/hcrrepository.py
configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/header_writer.py
configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/__init__.py
configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/generate_repo.py
configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/runtests.py
configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/unittest_hcr_header.py
configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/unittest_hcrml_impl.py
configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/unittest_hcrml_reader.py
configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/unittest_hcrml_writer.py
configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/unittest_hcrrepository.py
configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/unittest_read_write_record.py
configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/unittest_read_write_repository.py
configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/unittest_reader.py
configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/unittest_writer.py
configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/xsd/hcrml.xsd
configurationengine/source/plugins/symbian/ConeHCRPlugin/setup.py
configurationengine/source/plugins/symbian/ConeImagePlugin/__init__.py
configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/__init__.py
configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/generators.py
configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/imageml.py
configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/__init__.py
configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/implml/startupmif_animation_with_version.imageml
configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/runtests.py
configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/unittest_generators.py
configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/unittest_imageml_parseimpl.py
configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/unittest_imageml_plugin.py
configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/xsd/imageml.xsd
configurationengine/source/plugins/symbian/ConeImagePlugin/setup.py
configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/convertproject.py
configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/__init__.py
configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/.metadata
configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/confml/family_x.confml
configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/product_x/confml/product_x.confml
configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/product_x/language/Euro/confml/VariantData_product_x_Euro.confml
configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/product_x/language/French/confml/VariantData_product_x_French.confml
configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/product_x/language/German/confml/VariantData_product_x_German.confml
configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/product_x/language/Greek/confml/VariantData_product_x_Greek.confml
configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/test/implml/create_project.convertprojectml
configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/test3/implml/create_project.convertprojectml
configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/platform1_root.confml
configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/platform3_root.confml
configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/platforms/platform1/root.confml
configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/platforms/platform3_feas_only/confml/feature2.confml
configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/platforms/platform3_feas_only/implml/feature2_ABCD0000.crml
configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/platforms/platform3_feas_only/root.confml
configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/product_x_Euro_root.confml
configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/product_x_French_root.confml
configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/product_x_German_root.confml
configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/product_x_Greek_root.confml
configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/confml_data/root.confml
configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/convert.confml
configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/convertpluginlayer/implml/create_project.convertprojectml
configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/family_x/product_x/product_x.confml
configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/family_x/product_x/root.confml
configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/project/assets/s60/implml/file1.convertprojectml
configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/runtests.py
configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/unittest_convertprojectml_plugin.py
configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/xsd/convertprojectml.xsd
configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/setup.py
configurationengine/source/plugins/symbian/ConeThemePlugin/setup.py
configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/maketheme.py
configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/__init__.py
configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/test_pkg/themepackage2.pkg
configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/runtests.py
configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/unittest_theme_container.py
configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/unittest_theme_function.py
configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/unittest_theme_plugin.py
configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/unittest_theme_resource.py
configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/theme_container.py
configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/theme_resource.py
configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/xsd/thememl.xsd
configurationengine/source/plugins/symbian/integration-test/__init__.py
configurationengine/source/plugins/symbian/integration-test/runtests.py
configurationengine/source/plugins/symbian/integration-test/testdata/crml_dc_expected/crml_dc.html
configurationengine/source/plugins/symbian/integration-test/testdata/deltacenrep/deltacenrep_expected/deltacenreps/00000002.txt
configurationengine/source/plugins/symbian/integration-test/testdata/deltacenrep/deltacenrep_expected/deltacenreps/00000003.txt
configurationengine/source/plugins/symbian/integration-test/testdata/deltacenrep/deltacenrep_expected/deltacenreps/00000005.txt
configurationengine/source/plugins/symbian/integration-test/testdata/deltacenrep/deltacenrep_expected/deltacenreps/00000006.txt
configurationengine/source/plugins/symbian/integration-test/testdata/deltacenrep/deltacenrep_expected/include/deltacenreps.iby
configurationengine/source/plugins/symbian/integration-test/testdata/deltacenrep/normalcenrep_expected/content/private/10202BE9/00000002.txt
configurationengine/source/plugins/symbian/integration-test/testdata/deltacenrep/normalcenrep_expected/content/private/10202BE9/00000003.txt
configurationengine/source/plugins/symbian/integration-test/testdata/deltacenrep/normalcenrep_expected/content/private/10202BE9/00000005.txt
configurationengine/source/plugins/symbian/integration-test/testdata/deltacenrep/normalcenrep_expected/content/private/10202BE9/00000006.txt
configurationengine/source/plugins/symbian/integration-test/testdata/deltacenrep/project/Layer1/confml/bitmask_test.confml
configurationengine/source/plugins/symbian/integration-test/testdata/deltacenrep/project/Layer1/confml/crml_ints.confml
configurationengine/source/plugins/symbian/integration-test/testdata/deltacenrep/project/Layer1/confml/crml_reals.confml
configurationengine/source/plugins/symbian/integration-test/testdata/deltacenrep/project/Layer1/confml/feature1.confml
configurationengine/source/plugins/symbian/integration-test/testdata/deltacenrep/project/Layer1/confml/feature2.confml
configurationengine/source/plugins/symbian/integration-test/testdata/deltacenrep/project/Layer1/implml/00000001_feature1.crml
configurationengine/source/plugins/symbian/integration-test/testdata/deltacenrep/project/Layer1/implml/00000002_feature2.crml
configurationengine/source/plugins/symbian/integration-test/testdata/deltacenrep/project/Layer1/implml/00000003_bitmask_test.crml
configurationengine/source/plugins/symbian/integration-test/testdata/deltacenrep/project/Layer1/implml/00000005_crml_ints.crml
configurationengine/source/plugins/symbian/integration-test/testdata/deltacenrep/project/Layer1/implml/00000006_crml_reals.crml
configurationengine/source/plugins/symbian/integration-test/testdata/deltacenrep/project/Layer1/implml/deltacenrep_iby.implml
configurationengine/source/plugins/symbian/integration-test/testdata/deltacenrep/project/Layer1/root.confml
configurationengine/source/plugins/symbian/integration-test/testdata/deltacenrep/project/Layer2/confml/data.confml
configurationengine/source/plugins/symbian/integration-test/testdata/deltacenrep/project/Layer2/root.confml
configurationengine/source/plugins/symbian/integration-test/testdata/deltacenrep/project/root.confml
configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_last_layer/content/animations/anim1.mbm
configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_last_layer/content/animations/anim2.mif
configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_last_layer/content/data/sequence_setting_test.txt
configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_last_layer/content/data/sounds/test.mp3
configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_last_layer/content/private/10202BE9/10000000.txt
configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_last_layer/content/private/10202BE9/12341001.txt
configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_last_layer/content/private/10202BE9/12341002.txt
configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_last_layer/content/private/10202BE9/20000000.txt
configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_last_layer/content/private/10207114/import/12340001/themepackage.mbm
configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_last_layer/content/private/10207114/import/12340001/themepackage.mif
configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_last_layer/content/private/10207114/import/12340001/themepackage.skn
configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_last_layer/content/private/10207114/import/12340002/themepackage.mbm
configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_last_layer/content/private/10207114/import/12340002/themepackage.mif
configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_last_layer/content/private/10207114/import/12340002/themepackage.skn
configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_last_layer/content/resource/skins/12340001/themepackage.mbm
configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_last_layer/content/resource/skins/12340001/themepackage.mif
configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_last_layer/content/resource/skins/12340002/themepackage.mbm
configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_last_layer/content/resource/skins/12340002/themepackage.mif
configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_last_layer/content/sound_folder/test2.mp3
configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_last_layer/hcr_test.h
configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_rofs2/content/data/sequence_setting_test.txt
configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_rofs2/content/private/100059C9/cenrep_rfs.txt
configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_rofs2/content/private/10202BE9/10000000.txt
configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_rofs2/content/private/10202BE9/12341000.txt
configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_rofs2/content/private/10202BE9/12341001.txt
configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_rofs2/content/private/10202BE9/12341002.txt
configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_rofs2/content/private/10202BE9/12341003.txt
configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_rofs2/content/private/10202BE9/20000000.txt
configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_rofs2/content/private/10202BE9/ABCD0000.txt
configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/custom/implml/configure_bitmask.ruleml
configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/custom/implml/sound.implml
configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/custom/implml/unicode_rule_test.ruleml
configurationengine/source/plugins/symbian/integration-test/unittest_crml_dc.py
configurationengine/source/plugins/symbian/integration-test/unittest_generate.py
configurationengine/source/plugins/symbian/runtests.py
configurationengine/source/runtests.py
configurationengine/source/scripts/__init__.py
configurationengine/source/scripts/compare_api_report_template.html
configurationengine/source/scripts/compare_ci_report_template.html
configurationengine/source/scripts/compare_data_report_template.html
configurationengine/source/scripts/cone.ini
configurationengine/source/scripts/cone_base.html
configurationengine/source/scripts/cone_common.py
configurationengine/source/scripts/cone_defaults.cfg
configurationengine/source/scripts/cone_subaction.py
configurationengine/source/scripts/cone_tool.py
configurationengine/source/scripts/conesub_compare.py
configurationengine/source/scripts/conesub_export.py
configurationengine/source/scripts/conesub_fix.py
configurationengine/source/scripts/conesub_generate.cfg
configurationengine/source/scripts/conesub_generate.py
configurationengine/source/scripts/conesub_import_browserbookmarks.py.old
configurationengine/source/scripts/conesub_info.py
configurationengine/source/scripts/conesub_initvariant.py
configurationengine/source/scripts/conesub_merge.py
configurationengine/source/scripts/conesub_packvariant.py
configurationengine/source/scripts/conesub_report.py
configurationengine/source/scripts/conesub_update.py
configurationengine/source/scripts/conesub_validate.py
configurationengine/source/scripts/configroot2flat.py
configurationengine/source/scripts/crml_dc_report_template.html
configurationengine/source/scripts/gen_report_template.html
configurationengine/source/scripts/generation_report.py
configurationengine/source/scripts/imaker_variantdir.cfg
configurationengine/source/scripts/info_api_report_template.html
configurationengine/source/scripts/info_content_report_template.html
configurationengine/source/scripts/info_impl_report_template.html
configurationengine/source/scripts/info_value_report_template.csv
configurationengine/source/scripts/info_value_report_template.html
configurationengine/source/scripts/logging.ini
configurationengine/source/scripts/popup.js
configurationengine/source/scripts/report_util.py
configurationengine/source/scripts/setup.py
configurationengine/source/scripts/tablefilter.js
configurationengine/source/scripts/tests/__init__.py
configurationengine/source/scripts/tests/generation_test_project/base/implml/impl_override_test.templateml
configurationengine/source/scripts/tests/generation_test_project/custom/implml/conditional_container.implml
configurationengine/source/scripts/tests/generation_test_project/custom/implml/impl_override_test.templateml
configurationengine/source/scripts/tests/generation_test_project/custom/implml/missing_file_in_report_test.implml
configurationengine/source/scripts/tests/generation_test_project/custom/implml/seq_tempvar.implml
configurationengine/source/scripts/tests/generation_test_project/custom/implml/simple_tempvars.implml
configurationengine/source/scripts/tests/generation_test_project/what_output.txt
configurationengine/source/scripts/tests/runtests.py
configurationengine/source/scripts/tests/scripttest_common.py
configurationengine/source/scripts/tests/template.csv
configurationengine/source/scripts/tests/test_template/template2.csv
configurationengine/source/scripts/tests/test_variant.cpf
configurationengine/source/scripts/tests/testdata/compare/expected/data_p1r1_vs_p1r4.txt
configurationengine/source/scripts/tests/testdata/export/duplicate_root.confml
configurationengine/source/scripts/tests/testdata/export/layer1/confml/duplicate_settings1.confml
configurationengine/source/scripts/tests/testdata/export/layer1/content/foo.txt
configurationengine/source/scripts/tests/testdata/export/layer1/root.confml
configurationengine/source/scripts/tests/testdata/export/layer2/confml/duplicate_settings2.confml
configurationengine/source/scripts/tests/testdata/export/layer2/implml/jeee.implml
configurationengine/source/scripts/tests/testdata/export/layer2/root.confml
configurationengine/source/scripts/tests/testdata/generate/error_test_project/layer1/implml/rules_with_errors.implml
configurationengine/source/scripts/tests/testdata/generate/error_test_project/layer1/root.confml
configurationengine/source/scripts/tests/testdata/generate/error_test_project/root.confml
configurationengine/source/scripts/tests/testdata/generate/expected/content/template_string_condition_true.txt
configurationengine/source/scripts/tests/testdata/generate/expected/impl_override_test.txt
configurationengine/source/scripts/tests/testdata/generate/expected/overridden_output/output_rootdir_test.txt
configurationengine/source/scripts/tests/testdata/generate/expected/overridden_output/test_subdir/output_rootdir_test.txt
configurationengine/source/scripts/tests/testdata/generate/expected_report.html
configurationengine/source/scripts/tests/testdata/generate/impl_container/expected/data_root.confml/output_test.txt
configurationengine/source/scripts/tests/testdata/generate/impl_container/expected/data_root.confml/test.txt
configurationengine/source/scripts/tests/testdata/generate/impl_container/project/base_root.confml
configurationengine/source/scripts/tests/testdata/generate/impl_container/project/data/confml/data.confml
configurationengine/source/scripts/tests/testdata/generate/impl_container/project/data/root.confml
configurationengine/source/scripts/tests/testdata/generate/impl_container/project/data_root.confml
configurationengine/source/scripts/tests/testdata/generate/impl_container/project/layer/confml/test.confml
configurationengine/source/scripts/tests/testdata/generate/impl_container/project/layer/implml/eval_generation_context.ruleml
configurationengine/source/scripts/tests/testdata/generate/impl_container/project/layer/implml/scripts/test_eval_generation_context.py
configurationengine/source/scripts/tests/testdata/generate/impl_container/project/layer/implml/test.implml
configurationengine/source/scripts/tests/testdata/generate/impl_container/project/layer/root.confml
configurationengine/source/scripts/tests/testdata/generate/layer_filtering_project/assets/base/confml/test_feature.confml
configurationengine/source/scripts/tests/testdata/generate/layer_filtering_project/assets/base/implml/base.templateml
configurationengine/source/scripts/tests/testdata/generate/layer_filtering_project/assets/base/implml/layer1.templateml
configurationengine/source/scripts/tests/testdata/generate/layer_filtering_project/assets/base/implml/layer2.templateml
configurationengine/source/scripts/tests/testdata/generate/layer_filtering_project/assets/base/implml/layer3.templateml
configurationengine/source/scripts/tests/testdata/generate/layer_filtering_project/assets/base/implml/rule_test.implml
configurationengine/source/scripts/tests/testdata/generate/layer_filtering_project/assets/base/root.confml
configurationengine/source/scripts/tests/testdata/generate/layer_filtering_project/assets/layer1/confml/data.confml
configurationengine/source/scripts/tests/testdata/generate/layer_filtering_project/assets/layer1/root.confml
configurationengine/source/scripts/tests/testdata/generate/layer_filtering_project/assets/layer2/confml/data.confml
configurationengine/source/scripts/tests/testdata/generate/layer_filtering_project/assets/layer2/root.confml
configurationengine/source/scripts/tests/testdata/generate/layer_filtering_project/assets/layer3/confml/data.confml
configurationengine/source/scripts/tests/testdata/generate/layer_filtering_project/assets/layer3/root.confml
configurationengine/source/scripts/tests/testdata/generate/layer_filtering_project/root.confml
configurationengine/source/scripts/tests/testdata/info/expected/api_report.html
configurationengine/source/scripts/tests/testdata/info/expected/content_report.html
configurationengine/source/scripts/tests/testdata/info/expected/impl_report.html
configurationengine/source/scripts/tests/testdata/info/expected/impl_report_with_containers.html
configurationengine/source/scripts/tests/testdata/info/expected/value_report.csv
configurationengine/source/scripts/tests/testdata/info/expected/value_report_custom.html
configurationengine/source/scripts/tests/testdata/info/expected/value_report_langpacks.html
configurationengine/source/scripts/tests/testdata/info/expected/value_report_multi_mixed.html
configurationengine/source/scripts/tests/testdata/info/expected/value_report_single.html
configurationengine/source/scripts/tests/testdata/info/expected/value_report_single_with_view.html
configurationengine/source/scripts/tests/testdata/info/expected/value_report_special_chars.csv
configurationengine/source/scripts/tests/testdata/info/no_active_root.cpf
configurationengine/source/scripts/tests/testdata/info/value_report_project/asset1_root.confml
configurationengine/source/scripts/tests/testdata/info/value_report_project/asset2_root.confml
configurationengine/source/scripts/tests/testdata/info/value_report_project/csv_test_root.confml
configurationengine/source/scripts/tests/testdata/info/value_report_project/family_root.confml
configurationengine/source/scripts/tests/testdata/info/value_report_project/product/language/langpack_02/confml/data.confml
configurationengine/source/scripts/tests/testdata/info/value_report_project/product_langpack_01_root.confml
configurationengine/source/scripts/tests/testdata/info/value_report_project/product_langpack_03_root.confml
configurationengine/source/scripts/tests/testdata/info/value_report_project/product_root.confml
configurationengine/source/scripts/tests/testdata/info/value_report_project/variant_root.confml
configurationengine/source/scripts/tests/testdata/initvariant/expected.zip
configurationengine/source/scripts/tests/testdata/initvariant/expected2.zip
configurationengine/source/scripts/tests/testdata/initvariant/expected3.zip
configurationengine/source/scripts/tests/testdata/initvariant/test_project.zip
configurationengine/source/scripts/tests/testdata/initvariant/variant.cpf
configurationengine/source/scripts/tests/testdata/merge/last_layer_expected.zip
configurationengine/source/scripts/tests/testdata/merge/last_layer_rename_expected.zip
configurationengine/source/scripts/tests/testdata/merge/last_layer_variant_v1_expected.zip
configurationengine/source/scripts/tests/testdata/merge/last_layer_variant_v1_v2_expected.zip
configurationengine/source/scripts/tests/testdata/merge/last_layer_variant_v2_expected.zip
configurationengine/source/scripts/tests/testdata/merge/multiple_last_layers_expected.zip
configurationengine/source/scripts/tests/testdata/merge/test_variant_v1.cpf
configurationengine/source/scripts/tests/testdata/merge/test_variant_v2.cpf
configurationengine/source/scripts/tests/testdata/packvariant/expected/packvariant.zip
configurationengine/source/scripts/tests/testdata/packvariant/project/Layer1/confml/basic_setting_types_test.confml
configurationengine/source/scripts/tests/testdata/packvariant/project/Layer1/confml/bitmask_test.confml
configurationengine/source/scripts/tests/testdata/packvariant/project/Layer1/confml/feature1.confml
configurationengine/source/scripts/tests/testdata/packvariant/project/Layer1/confml/feature2.confml
configurationengine/source/scripts/tests/testdata/packvariant/project/Layer1/confml/file_folder_test.confml
configurationengine/source/scripts/tests/testdata/packvariant/project/Layer1/confml/imaker_api.confml
configurationengine/source/scripts/tests/testdata/packvariant/project/Layer1/confml/sequence_setting_test.confml
configurationengine/source/scripts/tests/testdata/packvariant/project/Layer1/confml/time_types_test.confml
configurationengine/source/scripts/tests/testdata/packvariant/project/Layer1/confml/view.confml
configurationengine/source/scripts/tests/testdata/packvariant/project/Layer1/content/default_file.txt
configurationengine/source/scripts/tests/testdata/packvariant/project/Layer1/content/override_test.txt
configurationengine/source/scripts/tests/testdata/packvariant/project/Layer1/content/seq/def1_file.txt
configurationengine/source/scripts/tests/testdata/packvariant/project/Layer1/content/seq/def2_file.txt
configurationengine/source/scripts/tests/testdata/packvariant/project/Layer1/implml/bitmask_test.templateml
configurationengine/source/scripts/tests/testdata/packvariant/project/Layer1/implml/feature1_1.templateml
configurationengine/source/scripts/tests/testdata/packvariant/project/Layer1/implml/feature1_2.templateml
configurationengine/source/scripts/tests/testdata/packvariant/project/Layer1/implml/feature1_sequence.templateml
configurationengine/source/scripts/tests/testdata/packvariant/project/Layer1/implml/feature2.templateml
configurationengine/source/scripts/tests/testdata/packvariant/project/Layer1/implml/time_types_test.templateml
configurationengine/source/scripts/tests/testdata/packvariant/project/Layer1/root.confml
configurationengine/source/scripts/tests/testdata/packvariant/project/Layer2/confml/data.confml
configurationengine/source/scripts/tests/testdata/packvariant/project/Layer2/content/layer2_file.txt
configurationengine/source/scripts/tests/testdata/packvariant/project/Layer2/content/seq/layer2_file.txt
configurationengine/source/scripts/tests/testdata/packvariant/project/Layer2/content/seq/layer2_file2.txt
configurationengine/source/scripts/tests/testdata/packvariant/project/Layer2/root.confml
configurationengine/source/scripts/tests/testdata/packvariant/project/Layer3/confml/data.confml
configurationengine/source/scripts/tests/testdata/packvariant/project/Layer3/content/override_test.txt
configurationengine/source/scripts/tests/testdata/packvariant/project/Layer3/content/seq/layer3_file.txt
configurationengine/source/scripts/tests/testdata/packvariant/project/Layer3/root.confml
configurationengine/source/scripts/tests/testdata/packvariant/project/Layer4/confml/data.confml
configurationengine/source/scripts/tests/testdata/packvariant/project/Layer4/confml/layer4_feature.confml
configurationengine/source/scripts/tests/testdata/packvariant/project/Layer4/confml/view.confml
configurationengine/source/scripts/tests/testdata/packvariant/project/Layer4/content/seq/layer4_file.txt
configurationengine/source/scripts/tests/testdata/packvariant/project/Layer4/root.confml
configurationengine/source/scripts/tests/testdata/packvariant/project/Layer5/root.confml
configurationengine/source/scripts/tests/testdata/packvariant/project/root1.confml
configurationengine/source/scripts/tests/testdata/packvariant/project/root2.confml
configurationengine/source/scripts/tests/testdata/packvariant/project/root3.confml
configurationengine/source/scripts/tests/testdata/packvariant/project/root4.confml
configurationengine/source/scripts/tests/testdata/packvariant/project/root5.confml
configurationengine/source/scripts/tests/testdata/packvariant/project/testprod/custvariant/configurator/confml/data.confml
configurationengine/source/scripts/tests/testdata/packvariant/project/testprod/custvariant/configurator/root.confml
configurationengine/source/scripts/tests/testdata/packvariant/project/testprod/custvariant/manual/confml/data.confml
configurationengine/source/scripts/tests/testdata/packvariant/project/testprod/custvariant/manual/root.confml
configurationengine/source/scripts/tests/testdata/packvariant/project/testprod_custvariant_root.confml
configurationengine/source/scripts/tests/testdata/report/expected/both.txt
configurationengine/source/scripts/tests/testdata/report/expected/rofs3.txt
configurationengine/source/scripts/tests/testdata/report/expected/uda.txt
configurationengine/source/scripts/tests/testdata/report/template.txt
configurationengine/source/scripts/tests/testdata/validate/expected/invalid_config_report.txt
configurationengine/source/scripts/tests/testdata/validate/expected/invalid_file_report.txt
configurationengine/source/scripts/tests/testdata/validate/expected/report.xml
configurationengine/source/scripts/tests/testdata/validate/expected/report_multiple_filters.txt
configurationengine/source/scripts/tests/testdata/validate/expected/report_only_confml.txt
configurationengine/source/scripts/tests/testdata/validate/expected/report_only_implml.txt
configurationengine/source/scripts/tests/testdata/validate/expected/report_only_model.txt
configurationengine/source/scripts/tests/testdata/validate/expected/report_only_schema.txt
configurationengine/source/scripts/tests/testdata/validate/expected/valid_config_report.txt
configurationengine/source/scripts/tests/testdata/validate/project/assets/invalid/confml/broken.confml
configurationengine/source/scripts/tests/testdata/validate/project/assets/invalid/confml/invalid_element.confml
configurationengine/source/scripts/tests/testdata/validate/project/assets/invalid/confml/invalid_type.confml
configurationengine/source/scripts/tests/testdata/validate/project/assets/invalid/confml/model_level_validation_test.confml
configurationengine/source/scripts/tests/testdata/validate/project/assets/invalid/implml/broken.implml
configurationengine/source/scripts/tests/testdata/validate/project/assets/invalid/implml/duplicate_tempvar_ref.implml
configurationengine/source/scripts/tests/testdata/validate/project/assets/invalid/implml/invalid_attribute.implml
configurationengine/source/scripts/tests/testdata/validate/project/assets/invalid/root.confml
configurationengine/source/scripts/tests/testdata/validate/project/assets/valid/confml/basic_setting_types_test.confml
configurationengine/source/scripts/tests/testdata/validate/project/assets/valid/root.confml
configurationengine/source/scripts/tests/testdata/validate/project/errors_root.confml
configurationengine/source/scripts/tests/testdata/validate/project/no_errors_root.confml
configurationengine/source/scripts/tests/testdata/validate/template.txt
configurationengine/source/scripts/tests/unittest_compare.py
configurationengine/source/scripts/tests/unittest_cone.py
configurationengine/source/scripts/tests/unittest_export.py
configurationengine/source/scripts/tests/unittest_generate.py
configurationengine/source/scripts/tests/unittest_info.py
configurationengine/source/scripts/tests/unittest_initvariant.py
configurationengine/source/scripts/tests/unittest_merge.py
configurationengine/source/scripts/tests/unittest_packvariant.py
configurationengine/source/scripts/tests/unittest_report.py
configurationengine/source/scripts/tests/unittest_update.py
configurationengine/source/scripts/tests/unittest_validate.py
configurationengine/source/scripts/validation_report_template.html
configurationengine/source/scripts/validation_report_template.xml
configurationengine/source/setup.py
configurationengine/source/testautomation/testautomation/base_testcase.py
configurationengine/source/testautomation/testautomation/build_egg_info.py
configurationengine/source/testautomation/testautomation/plugin_utils.py
configurationengine/source/testautomation/testautomation/setup.py
configurationengine/source/testautomation/testautomation/tests/__init__.py
configurationengine/source/testautomation/testautomation/tests/runtests.py
configurationengine/source/testautomation/testautomation/utils.py
configurationengine/update_svn_revision.py
configurationengine/windows.properties
--- a/configurationengine/RELEASE.TXT	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/RELEASE.TXT	Tue Aug 10 14:29:28 2010 +0300
@@ -1,82 +1,193 @@
 
 
-                         ConE the Configuration Engine
-                              Version cone-1.1.5
-                            Release Notes, 11.1.2010
+                         ConE - the Configuration Engine
+                              Version cone-1.2.11
+                            Release Notes, 10.08.2010
 
 Release notes:
 =============
-== Version Cone-1.1.5 ==
- * Stories:
-     - #792: Change ConE licenses from SFL to EPL
-     - #80: As a variant engineer I want to merge my configuration so that "old" content is removed
-     - #639: As a variant engineer I want that color depth argument for bmconv and mifconv is configurable
-     - #703: As a SW developer I want to merge my confml and implml to global configuration project easily so that I don't need to manually copy the files and update the root files.
-     - #765: As a user I want to configure cone logging output so that I can use the cone logs more efficiently
-     - #785: CommandML does not support tag elements
- * Bug fixes:
-     - #814: ERROR: Content folder in vascos "dummy" layer is not added to CPF when adding layer with -a option
-     - #763: Selection setting option map does not work properly when option map element is used
-     - #193: Different configurations open on the same project return the same setting values
-     - #737: ConE merge produces incorrect output (layer root contains all data)
-     - #762: ConE: option mapping does not store the mapKey/mapValue to confml file when confml output is written
-     - #764: ConE must not assume that the executive process will have write access to workdir
-     - #820: MultiSelection value setting does not work correctly
- 
-== Version Cone-1.1.4 ==
- * Stories:
-     - #663: As a variant engineer I want to get resource's size in ruleml.
-     - #700: As a variant engineer I want to have a rule which automatically sets correct color depth so that I don't need to manually do that.
- * Bug fixes:
-     - #701: ConE crml: cenrep txt generation with sid & capabilities produces incorrect output
+
+== Version Cone-1.2.11 ==
+* Stories
+ * #1012 As a user I want to get information whether the setting has been changed in the layer usign regex for layer name so that only needed rules are run
+ * #1022 As a RHEL 64-bit user I want to run ConE without any extra steps
+ * #1013 As a user I want use environment variables when defining convertprojectml paths
+ * #1033 Name-ID mapping with file/folder settings as mapKey or mapValue should default to using localPath
+ * #929 ConE support for confml specification 2.88 / 2.90
+ * #1035 As a cone user I want to define the data update policy so, that it would be possible to add the configuration as the first include to the target configuration
+
+* Bug fixes
+ * #1031 Copying of empty directories does not work with ContentML
+ * #1026 Contentml plugin gives memory error on big content files.
+ * #1007 As a user I want to be able to export vasco langpack customization root as such without filtering so that it works (Verifying and Code reviews)
+ * #1021 ContentML throws exception when localpath is empty
+ * #1027 Makefile generation gives error message with empty CPF and creates UDA always
+
+== Version Cone-1.2.10 ==
+* Bug fixes
+  * #999 Makefile generation does not work
+  * #1015 Merge conesub_update.py patch to trunk
+  * #1014 ContentML external input doesn't work with network drives.
+
+== Version Cone-1.2.9 ==
+* Stories
+  * #948 As a user I want run a custom script on top of cone api to investigate deprecate features from Carbon confmls
+  * #975 As a user I want to set the value of a tempFeature from the cone generate commandline with --set=TempFea=1
+  * #979 As a cone user I want to store the rule execution outputs to a confml file so that I can use the rule output configuration in some other context
+  * #994 RuleML filtering bug
+  * #995 As a ConE user I want to get the list of generation output to separate “what” list so that I can create a zip file with WinZip (using winzip include)
+  * #997 PRODBUG: # (sharp/hash) in title name causes reference
+  * #998 Extending support of ticket #948 implementation
+  * #1004 ConE export fails if option name or value is missing
+
+* Bug fixes
+  * #984 RuleML logging error the first sequence item is not shown in the log
+  * #989 Modifying sequence values via default view doesn't save the data correctly
+  * #996 Execution of /source/scripts/tests/unittest_configroot2flat.py fails in packed bat.
+  * #1001 Implementation container condition does not work if value is None
+  * #1006 Error: Initvariant merges also AMPI custvariant layers
 
-== Version Cone-1.1.3 ==
- * Stories:
-     - #696: Factory Settings cannot be restored as phone resets every time the security code is inserted
-     - #698: cone.cmd returns 0 even if ConE execution fails
- * Bug fixes:
-     - #699: Remove target:core tag from existing implementations so that no content is by default generated to core image.
+== Version Cone-1.2.8 ==
+* Bug fixes
+  * #1002 ConE execution conflicts EC image creation because of pyc file creation
+
+== Version Cone-1.2.7 ==
+* Stories
+  * #991 As a cone developer I want to configure the script interface of cone command line client
+
+* Bug fixes 
+  * #980 ConE --run-action=fix leaves old options in merged ConfML
+  * #976 An incorrectly defined rule element causes the entire implml file to fail
+  * #985 uses_layer() method doesn't work correctly in all cases
+  * #988 Name-ID mapping does not work if the source setting is not of string type
+  * #990 cone.cmd does not preserve caret characters (^) correctly
+  * #993 ConE in wk18 release does not generate all cenrep files for S60 asset
+
+== Version Cone-1.2.6 ==
+
+* Features:
+  * #928 As a user I want to create a rule that resolves is there any uda content in the generated layers
+  * #933 As a user I want to get image type as parameter from imaker so that factorydmprofiles can be customized
+  * #977 Remove the temp features from the refs with no output from the generation report
 
-== Version Cone-1.1.2 ==
+* Bug fixes:
+  * #955 NUAGE: Read error with readOnly attribute in View
+
+== Version Cone-1.2.5 ==
+* Features:
+ * #925 As a user I want to name cone generation report after CPF name
+ * #927 Rules are not working as implementations in generation report.
+ * #934 As a variant engineer I want to use Initvariant for initialization of new variant based on existing one
+ * #936 Study and integrate Jani's packvariant solution
+ * #943 As a developer I want to see validation information in S60 dashboard
+ * #944 As a user I want to filter out content files via command line paratemeters when exporting configuration so that the export size is smaller
+
+* Errors:
+ * #852 Generation report does not work with --all-layers
+ * #921 Commandml condition problem with temp variables
+ * #924 Ruleml tag filtering error
+ * #956 Destination Netvork fix to accesspoint_id_counter.py
+
+== Version Cone-1.2.4 ==
+
+== Stories ==
+ * #916 As vasco I need extra flag to create svgs to mif so that I would show startup images on my screen
+
+== Bug fixes ==
 
-== Version Cone-1.1.2 RC2 ==
-   * Bugfixes:
-    - Fixed template plug-in bug fix
-   
-== Version Cone-1.1.2 RC1 ==
+ * #921 Commandml condition problem with temp variables
+ * #923 ConE documentation errors
+ * #941 Casting None error in model.set_value_case()
+
+== Version Cone-1.2.3 ==
 
-    * Stories:
-     - #588: As a user I want to run the same command on several configurations in a batch mode
-     - #611: As a product integrator I want to have info report in csv format so that importing to Excel is easy to made
-     - #612: As a product integrator I want to see possible values for certain setting so that default values template is easy to made
-     - #643: Impml harmonization with container concept
-     - #652: Content plugin refactoring to enable better use
+== Stories ==
+ * #690 As a Variant Engineer I want to read imageml documentation
+ * #789 Value report should show if a setting value is set in a specific configuration
+ * #900 As a user I want to have configuration name visible instead of configuration root name in the default settng document
+ * #913 As a cone rule script writer I want to know the output folder of the generation so that I can generate a output file inside the rule script1
+ * #931 As a user I want to define name for layer root files in convert project so that the layer name can be shown in nuage
+ 
+== Bug fixes ==
+ * #192 Values inside sequence setting values are not cast to the correct type
+ * #683 Generation report reports a file as not generated if it is the output of an implementation filtered out of the generation by a condition
+ * #914 ConE way of creating temp files is racy and not good for server usage
+ * #919 Error: ConE container conditions do not work correctly with data comparison on different data types
+ * #932 Wildcards are working only in the beginning of filename in convertprojectml
+ 
+== Version Cone-1.2.2 ==
+Major features
+ * Bug fixes 1.2, to mainly fix bugs found in real build environments (parallel building, etc). 
 
-    * Bug fixes:
-     - #657: Project.create_configuration takes forever with big configuration project
-     - #659: Content plugins copy operation does not do anything if the file attribute in input has capital letter
-     - #660: plugins get increased to an insane amount!
+== Stories ==
+ * #860 CI interface compare report
+
+== Bug fixes ==
+ * #917 Error: Cone generate fails when parameters to paths are given with \path syntax
+ * #878 Helium 6.0.x: ConE errors in image creation
+
+== Version Cone-1.2.1 ==
+Major features
+ * Bug fixes and small new features to ConE 1.2.1 
+
+== Stories ==
+ * #830 NUAGE: As a customisation engineer I want to override property elements in a view so that the properties can be extended / overriden
+ * #846 As a variant engineer I want to easily merge a customer variant from a CPF back into the configuration project
+ * #743 EPIC: Automatic validation with ConE
+ * #851 Exporting CPFs to path creates that path
+ * #884 As a user I want to generate certain layers based on the layer naming so that variant creation manual layer is included automatically when needed
+ * #898 As a variant engineer I want to specifiy line change in templateml file for each template so that I can write either unix or windows files.
 
-== Version Cone-1.1.1 RC4 ==
- * Bugfixes:
-    - cone.cmd fix
-    
-== Version Cone-1.1.1 RC3 ==
- * Bugfixes:
-    - GenConfML plugin to use LXML instead of 4Suite
-    - Changed installation system to make the installation into a sub-directory depending on the current Python version (e.g. cone/2.5/lib/ instead of cone/lib/ etc.)
-    - Changed cone.cmd so that it chooses the correct base directory based on the Python version
-    - Added dep-eggs for Python 2.6
-    - Updated setuptools to version 0.6c11 from 0.6c9
-    - PYTHONCASEOK=1 added to cone.cmd
+Bug fixes 
+ * #861 NUAGE: Template/sequence problem
+ * #864 NUAGE: File setting problem in template part
+ * #876 Configuration version does not get read/written to confml output
+ * #877 Empty attributes of elements are removed in read/write test
+ * #207 set_value(value) method for sequence features modifies its parameter
 
-== Version Cone-1.1.1 RC2 ==
- * Bugfixes:
-  * #640: Tag definitions in TemplateML namespace do not work
-  * #645: Report generation fails if the changed data contains references to non-existent settings
-  * #648: TemplateML plug-in does not list output files correctly
-  * #589: Change ImageML get_refs() to report references used in determining input  
-== Version Cone-1.1.1 RC1 ==
+== Version Cone-1.2.0 ==
+* Features:
+	* #40: As a variant engineer/Sw integrator I want to check data compatibility of certain configuration so that I can be sure that my configuration is valid.
+	* #42: As a variant engineer I want to create operator cache using ConE so that content is visible already before image has been created
+	* #84: EPIC: Cenrep changes related cenrep version 2 and PREQ2112
+	* #96: As a variant engineer I need to enter variantID and variant version as a commandline parameter for the variant in case not included in the CPF
+	* #120: ConE view inclusion support
+	* #130: iMaker: Support baseporting team in iMaker - Cone HCR integration.
+	* #559: As a customization designer I want have only delta cenreps in ROFS3 so that re-creation of ROFS3 images in PR update is minimized.
+	* #584: As a variant engineer I want to be able to override implementation file in later layers so that public confml definition is easier.
+	* #636: Export action does not export ConfML files correctly
+	* #692: Value report generation fails if the view references non-existent settings
+	* #693: Value report generation fails if the specified view file does not directly contain the view
+	* #702: As a SW developer I want to validate my ConfML and Implml file schemas using ConE
+	* #705: Change rule plugin due to engine changes
+	* #74: 6NUAGE: As a cone developer I want to access view overridden and original attributes so that I can know which attributes are set in view level
+	* #747: As a user I want to see different schema validation as different error types so that I can filter them
+	* #792: Change ConE licenses from SFL to EPL
+	* #794: Preliminary model-level validation framework design
+	* #797: Productization and merging model level validation to ConE 1.2 release
+	* #826: ConE Linux delivery
+	* #858: Refs changed by rule execution should be visible to other implementations immediately
+	* #859: Common ImplML elements should be inherited correctly to sub-implementations
+	* #879: As a user I want to filter errors in the validation report so that I can find my errors easily
+* Bug fixes:
+	* #156: SchemaLocation attribute in Configuration element is invalid
+	* #791: Writing FeatureLink objects to confml file fails
+	* #799: As a customisation engineer I want to override option lists in a view so that the option list can be extended / overriden
+	* #829: ConE must not assume that the executive process will have write access to workdir: change the usage of os.rename to use shutil.move
+	* #831: Defining several mailbox feature elements under same group overrides the previously defined mailboxes in a view
+	* #832: ConE log file parameter causes error if filename contains \x
+	* #833: As a ConE API user I want to use all Confml feature xml schema facets consistently so that I can always trust that I get a certain type value
+	* #834: As a user I want read/write length attribute of a confml feature/setting
+	* #835: As a user I want to set desc and name attributes via constructor to a Confml sequence setting so that I can create it easily
+	* #836: NUAGE: As a ConE API user I want to read/write the id of any confml element so that the id can be accessed via the API
+	* #837: The ConfmlSequenceSetting template does not return ConfmlFile element data when it is fetched from confml
+	* #854: Filtering based on setting references does not work correctly with ImplContainers
+	* #855: ThemeML does not work in ImplML containers
+	* #857: Template plug-in does not do ref-based filtering correctly
+	* #866: Python version checking in cone.cmd might cause errors if multiple cone.cmd are executed at the same time.
+	* #587: Cone.cmd contains strange line
+
+== Version Cone-1.2.0DEV ==
  * Features:
    * Support for new webstorage (Carbon extapi)
      * Export features and data. Supports exporting of features and data from carbon to Configuration project and confml files.
@@ -86,8 +197,30 @@
      is not a valid confml ref. e.g. refs withs dots or any unicode characters.
      * Selection type feature cannot be created with the Carbon extapi (Creation of groups fails).
      * Directory separators '/' in configuration names will break the loading of configurations.
-     * Carbon allows only references in lower case, which is contradicting current confml specification. 
-== Version Cone-1.1.1 ==
+     * Carbon allows only references in lower case, which is contradicting current confml specification.
+ * Stories:
+  * #746 : As a cone developer I want to access view overridden and original attributes
+           so that I can know which attributes are set in view level
+
+== Version Cone-1.1.1 RC4 ==
+ * Bugfixes:
+    - cone.cmd fix
+== Version Cone-1.1.1 RC3 ==
+ * Bugfixes:
+    - GenConfML plugin to use LXML instead of 4Suite
+    - Changed installation system to make the installation into a sub-directory depending on the current Python version (e.g. cone/2.5/lib/ instead of cone/lib/ etc.)
+    - Changed cone.cmd so that it chooses the correct base directory based on the Python version
+    - Added dep-eggs for Python 2.6
+    - Updated setuptools to version 0.6c11 from 0.6c9
+    - PYTHONCASEOK=1 added to cone.cmd
+== Version Cone-1.1.1RC2 ==
+ * Bugfixes:
+  * #640: Tag definitions in TemplateML namespace do not work
+  * #645: Report generation fails if the changed data contains references to non-existent settings
+  * #648: TemplateML plug-in does not list output files correctly
+  * #589: Change ImageML get_refs() to report references used in determining input  
+ 
+== Version Cone-1.1.0 ==
   * New features
     * Templateml plugin
     * Command plugin
--- a/configurationengine/build-scripts/export_bat.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/build-scripts/export_bat.py	Tue Aug 10 14:29:28 2010 +0300
@@ -30,13 +30,12 @@
 assert os.path.exists(PLUGIN_SOURCE_ROOT)
 assert os.path.exists(TESTAUTOMATION_ROOT)
 
-sys.path.append(PLUGIN_SOURCE_ROOT)
-import plugin_utils
+
 
 sys.path.append(TESTAUTOMATION_ROOT)
 import testautomation
 from testautomation.copy_dir import copy_dir
-
+from testautomation import plugin_utils
 import utils
 utils.setup_logging('export_bat.log')
 
@@ -124,7 +123,7 @@
     # --------------------------------------
     
     log.info("Exporting plug-in integration test files...")
-    subpaths_by_package = plugin_utils.find_plugin_package_subpaths('integration-test', PLUGIN_PACKAGE)
+    subpaths_by_package = plugin_utils.find_plugin_package_subpaths(PLUGIN_SOURCE_ROOT, 'integration-test', PLUGIN_PACKAGE)
     for package_name, tests_path in subpaths_by_package:
         log.debug("  Package: %s" % package_name)
         log.debug("  Path:    %s" % tests_path)
--- a/configurationengine/build-scripts/install_cone.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/build-scripts/install_cone.py	Tue Aug 10 14:29:28 2010 +0300
@@ -24,15 +24,30 @@
 
 ROOT_PATH = os.path.abspath(os.path.dirname(__file__))
 
+# The sub-directory of the main install directory where all required libraries
+# etc. are installed
+INSTALL_SUBDIR = 'configurationengine'
+
+# The sub-directory for required libraries, platform-specific
+if sys.platform == "win32":
+    PLATFORM_SUBDIR = 'win'
+else:
+    PLATFORM_SUBDIR = 'linux'
+
+PYTHON_EXECUTABLE = 'python'
+
 SOURCE_ROOT = os.path.abspath(os.path.join(ROOT_PATH, '../source'))
 assert os.path.isdir(SOURCE_ROOT)
 SCRIPTS_SOURCE_ROOT = os.path.abspath(os.path.join(ROOT_PATH, '../source/scripts'))
 assert os.path.isdir(SCRIPTS_SOURCE_ROOT)
 PLUGIN_SOURCE_ROOT = os.path.abspath(os.path.join(ROOT_PATH, '../source/plugins'))
 assert os.path.isdir(PLUGIN_SOURCE_ROOT)
+TESTAUTOMATION_ROOT = os.path.abspath(os.path.join(SOURCE_ROOT, 'testautomation'))
+assert os.path.isdir(TESTAUTOMATION_ROOT)
 
+sys.path.insert(0, TESTAUTOMATION_ROOT)
 sys.path.append(PLUGIN_SOURCE_ROOT)
-import plugin_utils
+from testautomation import plugin_utils
 
 # Temporary directory where ConE eggs are built into
 TEMP_CONE_EGG_DIR = os.path.join(ROOT_PATH, 'install-temp/cone-eggs')
@@ -48,20 +63,20 @@
     """
     paths = [SOURCE_ROOT,
              SCRIPTS_SOURCE_ROOT]
-    plugin_paths = plugin_utils.find_plugin_sources_by_package(plugin_package)
+    plugin_paths = plugin_utils.find_plugin_sources_by_package(PLUGIN_SOURCE_ROOT, plugin_package)
     paths.extend(plugin_paths)
     
     log.debug("ConE egg source paths:\n%s" % '\n'.join(paths))
     return paths
     
 
-def build_cone_eggs(source_paths):
+def build_cone_eggs(source_paths, python_executable):
     log.info("Cleaning temporary ConE egg dir...")
     utils.recreate_dir(TEMP_CONE_EGG_DIR)
     
     log.info("Building ConE eggs...")
     for source_path in source_paths:
-        ok = utils.build_egg(source_path, TEMP_CONE_EGG_DIR)
+        ok = utils.build_egg(source_path, TEMP_CONE_EGG_DIR, python_executable)
         if not ok:
             raise BuildFailedError()
 
@@ -74,18 +89,21 @@
         log.debug("Copying eggs from '%s'..." % source_dir)
         for name in os.listdir(source_dir):
             if name.endswith('.egg'):
-                utils.copy_file(
-                    source_path = os.path.join(source_dir, name),
-                    target_path = TEMP_LIB_EGG_DIR)
+                if PLATFORM_SUBDIR == 'linux' and name.startswith('setuptools-0.6c11'):
+                    continue
+                else:
+                    utils.copy_file(
+                        source_path = os.path.join(source_dir, name),
+                        target_path = TEMP_LIB_EGG_DIR)
    
     dep_dirs_by_package = [(None, os.path.join(ROOT_PATH, '../dep-eggs'))]
-    dep_dirs_by_package.extend(plugin_utils.find_plugin_package_subpaths('dep-eggs', plugin_package))
+    dep_dirs_by_package.extend(plugin_utils.find_plugin_package_subpaths(PLUGIN_SOURCE_ROOT, 'dep-eggs', plugin_package))
     
     for package_name, dep_dir in dep_dirs_by_package:
         copy_eggs(dep_dir)
 
 def init_target_dir(target_dir, python_version):
-    BASE_DIR = os.path.normpath(os.path.join(target_dir, 'cone', python_version))
+    BASE_DIR = os.path.normpath(os.path.join(target_dir, INSTALL_SUBDIR, PLATFORM_SUBDIR, python_version))
     LIB_DIR     = os.path.join(BASE_DIR, 'lib')
     SCRIPT_DIR  = os.path.join(BASE_DIR, 'scripts')
     
@@ -102,7 +120,8 @@
     LIB_DIR, SCRIPT_DIR = init_target_dir(target_dir, python_version)
     
     # Collect the eggs to install
-    eggs = ['setuptools'] # Setuptools are needed also
+    eggs = ['setuptools'] # Setuptools are needed
+        
     for name in os.listdir(TEMP_CONE_EGG_DIR):
         if name.endswith('.egg'):
             eggs.append(TEMP_CONE_EGG_DIR + '/' + name)
@@ -111,18 +130,24 @@
     for egg in eggs:
         log.debug(egg)
         
-        if sys.platform == "win32":
-            platform_args = ["--always-copy"]
+        if PLATFORM_SUBDIR == 'win': 
+            command = ['easy_install-%s' % python_version,
+                       '--allow-hosts None',
+                       '--find-links install-temp/dep-eggs',
+                       '--install-dir "%s"' % LIB_DIR,
+                       '--script-dir "%s"' % SCRIPT_DIR,
+                       '--site-dirs "%s"' % LIB_DIR,
+                       '--always-copy',
+                       '--always-unzip']
         else:
-            platform_args = ["--no-deps"]
-                    
-        command = ['easy_install',
-                   '--allow-hosts None',
-                   '--find-links install-temp/dep-eggs',
-                   '--install-dir "%s"' % LIB_DIR,
-                   '--script-dir "%s"' % SCRIPT_DIR,
-                   '--site-dirs "%s"' % LIB_DIR]
-        command.extend(platform_args)
+            command = ['easy_install-%s' % python_version,
+                       '--allow-hosts None',
+                       '--find-links install-temp/dep-eggs',
+                       '--install-dir "%s"' % LIB_DIR,
+                       '--script-dir "%s"' % SCRIPT_DIR,
+                       '--site-dirs "%s"' % LIB_DIR,
+                       '--always-unzip']
+
         command.append('"' + egg + '"')
         command = ' '.join(command)
         
@@ -131,7 +156,7 @@
         if not ok:
             raise BuildFailedError()
 
-def develop_install_cone_sources(source_paths, target_dir, python_version):
+def develop_install_cone_sources(source_paths, target_dir, python_version, python_executable):
     log.info("Installing ConE sources in develop mode...")
     LIB_DIR, SCRIPT_DIR = init_target_dir(target_dir, python_version)
     
@@ -139,7 +164,7 @@
     try:
         for source_path in source_paths:
             os.chdir(source_path)
-            command = ['python setup.py develop',
+            command = ['%s setup.py develop' % python_executable,
                    '--allow-hosts None',
                    '--find-links "%s"' % os.path.normpath(os.path.join(ROOT_PATH, 'install-temp/dep-eggs')),
                    '--install-dir "%s"' % LIB_DIR,
@@ -154,10 +179,11 @@
     finally:
         os.chdir(orig_workdir)
 
-def perform_build(target_dir, plugin_package, install_type, python_version):
-    log.info("Target directory: %s" % target_dir)
-    log.info("Plug-in package:  %r" % plugin_package)
-    log.info("Python version:   %s" % python_version)
+def perform_build(target_dir, plugin_package, install_type, python_version, python_executable):
+    log.info("Target directory:  %s" % target_dir)
+    log.info("Plug-in package:   %r" % plugin_package)
+    log.info("Python version:    %s" % python_version)
+    log.info("Python executable: %s" % python_executable)
 
     # Retrieve dependencies to the correct location
     retrieve_dep_eggs(plugin_package)
@@ -169,26 +195,29 @@
     if not os.path.exists(target_dir):
         os.makedirs(target_dir)
     
+    if install_type == 'build':
+        build_cone_eggs(source_paths, python_executable)
     if install_type == 'install':
-        build_cone_eggs(source_paths)
+        build_cone_eggs(source_paths, python_executable)
         install_cone_eggs(target_dir, python_version)
     else:
-        develop_install_cone_sources(source_paths, target_dir, python_version)
+        develop_install_cone_sources(source_paths, target_dir, python_version, python_executable)
     
     # Copy RELEASE.txt
     utils.copy_file(
         source_path = os.path.join(SOURCE_ROOT, '..', 'RELEASE.TXT'),
-        target_path = os.path.join(target_dir, 'cone', 'RELEASE.TXT'))
+        target_path = os.path.join(target_dir, INSTALL_SUBDIR, 'RELEASE.TXT'))
     
     # Copy cone.cmd or cone.sh, depending on the platform
     if sys.platform == "win32":
-        filename = "cone.cmd"
+        sourcefile = targetfile = "cone.cmd"
     else:
-        filename = "cone.sh"
-    log.info("Copying %s" % filename)
+        sourcefile = "cone.sh"
+        targetfile = "cone"
+    log.info("Copying %s" % sourcefile)
     utils.copy_file(
-        source_path = os.path.join(SOURCE_ROOT, filename),
-        target_path = target_dir)
+        source_path = os.path.join(SOURCE_ROOT, sourcefile),
+        target_path = os.path.join(target_dir, targetfile))
 
 def main():
     parser = optparse.OptionParser()
@@ -200,26 +229,33 @@
     parser.add_option("-i", "--install-type",\
                       help="The installation type, can be 'install' (the default) or 'develop'.",\
                       default='install')
+    parser.add_option("--python-executable",\
+                      help="The Python executable to run type, defaults to 'python'.",\
+                      default='python')
     (options, args) = parser.parse_args()
     if options.target_dir is None:
         parser.error("Target directory must be given")
-    if options.install_type not in ('install', 'develop'):
+    if options.install_type not in ('install', 'build', 'develop'):
         parser.error("Invalid install type ('%s')" % options.install_type)
-    
-    if not utils.run_command("python --help"):
-        log.critical("Could not run 'python'. Please make sure that you "\
-                     "have Python installed and in your path.")
+        
+    if not utils.run_command("%s --help" % options.python_executable):
+        log.critical("Could not run '%s'. Please make sure that you "\
+                     "have Python installed and in your path." % options.python_executable)
         return 1
     
-    if not utils.run_command("easy_install --help"):
-        log.critical("Could not run 'easy_install'. Please make sure that you "\
-                     "have setuptools installed and the Python scripts directory in your path.")
+    python_version = utils.get_python_version(options.python_executable)
+    
+    easy_install_cmd = "easy_install-%s" % python_version
+    if not utils.run_command("%s --help" % easy_install_cmd):
+        log.critical("Could not run '%s'. Please make sure that you "\
+                     "have setuptools installed and the Python scripts directory in your path."\
+                     % easy_install_cmd)
         return 1
     
-    python_version = utils.get_python_version()
+    
     
     try:
-        perform_build(options.target_dir, options.plugin_package, options.install_type, python_version)
+        perform_build(options.target_dir, options.plugin_package, options.install_type, python_version, options.python_executable)
     except BuildFailedError:
         return 1
     
--- a/configurationengine/build-scripts/utils.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/build-scripts/utils.py	Tue Aug 10 14:29:28 2010 +0300
@@ -43,7 +43,7 @@
     else:
         os.makedirs(path)
 
-def build_egg(source_dir, target_dir):
+def build_egg(source_dir, target_dir, python_executable='python'):
     """
     Build an egg file from the given source directory (must contain a setup.py)
     into the given target directory.
@@ -53,7 +53,7 @@
     orig_workdir = os.getcwd()
     os.chdir(source_dir)
     try:
-        cmd = 'python setup.py bdist_egg --dist-dir "%s"' % target_dir
+        cmd = '%s setup.py bdist_egg --dist-dir "%s"' % (python_executable, target_dir)
         return run_command(cmd)
     finally:
         os.chdir(orig_workdir)
@@ -65,12 +65,13 @@
         os.makedirs(target_dir)
     shutil.copy2(source_path, target_path)
 
-def get_python_version():
+def get_python_version(executable='python'):
     """
-    Return the version of the Python that is run when the command 'python'
-    is run (not the Python where this script is executing).
+    Return the version of the Python that is run when the given Python
+    executable is run (not the Python where this script is executing).
+    @param executable: The Python executable to run, defaults to 'python'.
     """
-    p = subprocess.Popen('python -c "import sys; print sys.version[:3]"', stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
+    p = subprocess.Popen('%s -c "import sys; print sys.version[:3]"' % executable, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
     out, err = p.communicate()
     if p.returncode != 0:
         log.critical("Failed to get python version")
--- a/configurationengine/build.xml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/build.xml	Tue Aug 10 14:29:28 2010 +0300
@@ -2,269 +2,401 @@
  * Configuration Engine (ConE) main build file
  * This ant build.xml will build, install and test ConE and its plugins
  ****************************************************************************-->
-<project name="ConE"
-         default="install">
-  <property file="common.properties" />
-  <property file="linux.properties" />
-  <property file="windows.properties" />
-  <property environment="env" />
-  <!--
+
+<project name="ConE" default="install">
+    <property file="common.properties"/>
+    <property file="linux.properties" />
+    <property file="windows.properties" />
+    <property environment="env"/>
+
+    <!--
     Build properties, intended to be overridden from the command line
     where necessary.
-
+	
     E.g. ant install -Dbuild.build_path=C:/my/install/path -Dbuild.plugin_package=symbian
     -->
-  <property name="build.plugin_package"
-            value="common" />
-  <property name="build.base_path"
-            value="build" />
-  <property name="build.cone_install_path"
-            value="${build.base_path}/cone" />
-  <property name="build.bat_export_path"
-            value="${build.base_path}/bat" />
-  <property name="build.cone_pack_path"
-            value="${build.base_path}/dist" />
-  <property name="build.bat_pack_path"
-            value="${build.base_path}/dist" />
-  <property name="build.cone_install_path_abs"
-            location="${build.cone_install_path}" />
-  <property name="build.bat_export_path_abs"
-            location="${build.bat_export_path}" />
-  <property name="build.cone_pack_path_abs"
-            location="${build.cone_pack_path}" />
-  <property name="build.bat_pack_path_abs"
-            location="${build.bat_pack_path}" />
-  <property name="os.linux"
-            value="Linux" />
-  <property name="os.windows"
-            value="Windows 2003, Windows XP, Windows vista" />
-  <condition property="os_is_linux">
-    <os name="${os.linux}" />
-  </condition>
-  <target name="info">
-    <echoproperties />
-  </target>
-  <!-- Aliases -->
-  <target name="install"
-          depends="install-cone" />
-  <target name="develop"
-          depends="develop-cone" />
-  <target name="test"
-          depends="run-bat" />
-  <target name="doc"
-          depends="doc-all" />
-  <target name="clean">
-    <delete dir="${build.cone_install_path_abs}" />
-    <delete dir="${build.bat_export_path_abs}" />
-    <delete dir="${build.cone_pack_path_abs}" />
-    <delete dir="${build.bat_pack_path_abs}" />
-  </target>
-  <target name="svnversion">
-    <!--
+	<property name="drive" value="" />
+	<condition property="build.base_path" value="${drive}/build" else="build">
+        <and>		
+            <not>
+			    <equals arg1="${drive}" arg2="" />
+		    </not>
+            <not>
+                <os name="${os.linux.name}" />
+            </not>
+        </and>
+	</condition>
+	<condition property="build_scripts_dir" value="${drive}/${common.build_scripts_dir}" else="${common.build_scripts_dir}">
+        <and>		
+            <not>
+			    <equals arg1="${drive}" arg2="" />
+		    </not>
+            <not>
+                <os name="${os.linux.name}" />
+            </not>
+        </and>
+	</condition>
+	
+    <property name="build.plugin_package" value="common"/>
+    <!-- <property name="build.base_path" value="build"/> -->
+    <property name="build.cone_install_path" value="${build.base_path}/cone"/>
+    <property name="build.bat_export_path" value="${build.base_path}/bat"/>
+    <property name="build.cone_pack_path" value="${build.base_path}/dist"/>
+    <property name="build.bat_pack_path" value="${build.base_path}/dist"/>
+
+    <property name="build.cone_install_path_abs" location="${build.cone_install_path}"/>
+    <property name="build.bat_export_path_abs" location="${build.bat_export_path}"/>
+    <property name="build.cone_pack_path_abs" location="${build.cone_pack_path}"/>
+    <property name="build.bat_pack_path_abs" location="${build.bat_pack_path}"/>
+    <!--
+    <property name="os.linux.name" value="Linux" />
+    <property name="os.windows" value="Windows 2003, Windows XP, Windows vista" />
+    -->    
+    <property name="pythonversion" value="" />
+
+	<condition property="os_is_linux">
+		<os name="${os.linux.name}" />
+	</condition>
+    <condition property="pythonversion_defined">
+        <not>
+            <equals arg1="${pythonversion}" arg2="" />
+        </not>
+    </condition>
+	<condition property="drive_defined">
+        <not>
+            <equals arg1="${drive}" arg2="" />
+        </not>
+    </condition>
+	<!-- Set properties based on OS -->
+	<condition property="cmd_name" value="${os.linux.cmdname}" else="${os.windows.cmdname}">
+		<os name="${os.linux.name}" />
+	</condition>
+	<condition property="cmd_switch" value="${os.linux.cmdswitch}" else="${os.windows.cmdswitch}">
+		<os name="${os.linux.name}" />
+	</condition>
+	<condition property="env_path" value="${env.PATH}" else="${env.Path}">
+		<os name="${os.linux.name}" />
+	</condition>
+	<!-- Set properties based on cmd line arguments -->
+	<condition property="full_path_linux" value="${os.linux.userbin}:${env_path}" else="${env_path}">	
+        <not>
+		    <equals arg1="${pythonversion}" arg2="" />
+	    </not>
+	</condition>
+	<condition property="full_path_windows" value="${os.windows.pythonlocationbase}${pythonversion};${os.windows.pythonlocationbase}${pythonversion}/Scripts;${env_path}" else="${env_path}">
+		<not>
+			<equals arg1="${pythonversion}" arg2="" />
+		</not>
+	</condition>
+	<condition property="full_path" value="${full_path_linux}" else="${full_path_windows}">
+		<os name="${os.linux.name}" />
+	</condition>
+    <condition property="create_symlink">
+        <and>
+            <os name="${os.linux.name}" />
+            <not>
+                <equals arg1="${pythonversion}" arg2="" />
+            </not>
+        </and>
+    </condition>
+	
+	<!-- Targets -->
+    <target name="info">
+        <echoproperties/>
+    </target>
+
+    <!-- Aliases -->
+    <target name="install" depends="install-cone"/>
+    <target name="develop" depends="develop-cone"/>
+    <target name="test" depends="run-bat"/>
+    <target name="doc" depends="doc-all"/>
+
+    <target name="clean">
+        <delete dir="${build.cone_install_path_abs}"/>
+        <delete dir="${build.bat_export_path_abs}"/>
+        <delete dir="${build.cone_pack_path_abs}"/>
+        <delete dir="${build.bat_pack_path_abs}"/>
+    </target>
+
+
+    <target name="svnversion">
+        <!--
         Call the revision update script without the revision argument
         so that the revision is reverted back to "" (this should make
         it so that the working copy has no modifications and the
         revision will be e.g. "1234" instead of "1234M".
         -->
-    <echo>Revert SVN revision in source/cone/__init__.py</echo>
-    <exec executable="python">
-      <arg value="update_svn_revision.py" />
-      <arg value="source/cone/__init__.py" />
-    </exec>
-    <echo>Determine current working copy revision</echo>
-    <exec executable="svnversion"
-          failifexecutionfails="false">
-      <redirector outputproperty="svn.version" />
-    </exec>
-    <echo>SVN revision: ${svn.version}</echo>
-  </target>
-  <target name="svninitupdate"
-          depends="svnversion">
-    <echo>Update SVN revision in __init__.py</echo>
-    <exec executable="python">
-      <arg value="update_svn_revision.py" />
-      <arg value="source/cone/__init__.py" />
-      <arg value="${svn.version}" />
-    </exec>
-  </target>
-  <target name="install-cone"
-          depends="svninitupdate">
-    <!--
+        <echo>Revert SVN revision in source/cone/__init__.py</echo>
+        <exec executable="python">
+            <arg value="update_svn_revision.py"/>
+            <arg value="source/cone/__init__.py"/>
+        </exec>
+
+        <echo>Determine current working copy revision</echo>
+        <exec executable="svnversion" failifexecutionfails="false">
+            <redirector outputproperty="svn.version"/>
+        </exec>
+        
+        <echo>SVN revision: ${svn.version}</echo>
+    </target>
+
+    <target name="svninitupdate" depends="svnversion">
+      <echo>Update SVN revision in __init__.py</echo>
+      <exec executable="python">
+        <arg value="update_svn_revision.py"/>
+        <arg value="source/cone/__init__.py"/>
+        <arg value="${svn.version}"/>
+      </exec>
+    </target>
+
+	<target name="_mount-drive" unless="os_is_linux" if="drive_defined">
+		<echo message="Mounting drive ${drive} on Windows" />
+		<exec executable="cmd">
+			<arg value="/c" />
+			<arg value="subst /D ${drive}" />
+		</exec>
+		<exec executable="cmd">
+			<arg value="/c" />
+			<arg value="subst ${drive} ." />
+		</exec>
+	</target>
+	
+    <target name="install-cone" depends="svninitupdate">
+        <!--
         <echo>$${build.cone_install_path}:     ${build.cone_install_path}</echo>
         <echo>$${build.cone_install_path_abs}: ${build.cone_install_path_abs}</echo>
         -->
-    <!-- Run the install script in build-scripts/ -->
-    <exec executable="python"
-          dir="${common.build_scripts_dir}"
-          failonerror="true">
-      <arg line='install_cone.py --target-dir="${build.cone_install_path_abs}" --plugin-package="${build.plugin_package}"' />
-    </exec>
-    <!-- Revert the SVN revision so that it doesn't mark the working copy as modified needlessly -->
-    <echo>Revert SVN revision in source/cone/__init__.py</echo>
-    <exec executable="python">
-      <arg value="update_svn_revision.py" />
-      <arg value="source/cone/__init__.py" />
-    </exec>
-  </target>
-  <!--
-    Target for installing ConE so that it supports two Python versions.
+		
+		<!-- Linux: set the correct python version -->		
+		<antcall target="_create-python-version-symlink" />
+		<!-- Windows: mount drive -->
+		<antcall target="_mount-drive" />
+		
+        <echo message="OS: ${os.name}" />
+		<echo message="Python version:" />
+		<exec executable="${cmd_name}">
+            <env key="PATH" path="${full_path}" />
+            <arg value="${cmd_switch}" />
+            <arg value="python --version"/>
+        </exec>
+		
+		<!-- Run the install script in build-scripts/ -->
+		<echo message="Run ConE install script" />
+		<exec executable="${cmd_name}" dir="${build_scripts_dir}" failonerror="true">
+			<env key="PATH" value="${full_path}" />
+			<arg value="${cmd_switch}" />
+			<arg value='python install_cone.py --target-dir="${build.cone_install_path_abs}" --plugin-package="${build.plugin_package}"'/>
+		</exec>
+		
+        <!-- Revert the SVN revision so that it doesn't mark the working copy as modified needlessly -->
+        <echo>Revert SVN revision in source/cone/__init__.py</echo>
+        <exec executable="python">
+            <arg value="update_svn_revision.py"/>
+            <arg value="source/cone/__init__.py"/>
+        </exec>
+        <echo message="Done" />
+    </target>
+
+    <target name="build-cone" depends="svninitupdate">
+        <!-- Linux: set the correct python version -->      
+        <antcall target="_create-python-version-symlink" />
+        <!-- Windows: mount drive -->
+        <antcall target="_mount-drive" />
+        
+        <echo message="OS: ${os.name}" />
+        <echo message="Python version:" />
+        <exec executable="${cmd_name}">
+            <env key="PATH" path="${full_path}" />
+            <arg value="${cmd_switch}" />
+            <arg value="python --version"/>
+        </exec>
+        
+        <!-- Run the install script in build-scripts/ -->
+        <echo message="Run ConE install script" />
+        <exec executable="${cmd_name}" dir="${build_scripts_dir}" failonerror="true">
+            <env key="PATH" value="${full_path}" />
+            <arg value="${cmd_switch}" />
+            <arg value='python install_cone.py -i build --target-dir="${build.cone_install_path_abs}" --plugin-package="${build.plugin_package}"'/>
+        </exec>
+        
+        <!-- Revert the SVN revision so that it doesn't mark the working copy as modified needlessly -->
+        <echo>Revert SVN revision in source/cone/__init__.py</echo>
+        <exec executable="python">
+            <arg value="update_svn_revision.py"/>
+            <arg value="source/cone/__init__.py"/>
+        </exec>
+        <echo message="Done" />
+    </target>
+
+    <!--
+    Internal target for installing ConE on Windows so that it supports
+    two Python versions.
     
     Depends on two properties: build.dualversioninstall.path1 and
     build.dualversioninstall.path2 that must be set to the values of the PATH
     environment that contains the locations of the two Python installations.
     -->
-  <target name="install-cone-dualversion"
-          depends="svninitupdate">
-    <!-- Run the install script using the first Python version-->
-    <echo>Installing with first Python version (PATH=${build.dualversioninstall.path1})</echo>
-    <exec executable="python"
-          dir="${common.build_scripts_dir}"
-          failonerror="true">
-      <env key="PATH"
-           value="${build.dualversioninstall.path1}" />
-      <arg line='install_cone.py --target-dir="${build.cone_install_path_abs}" --plugin-package="${build.plugin_package}"' />
-    </exec>
-    <!-- Run the install script using the second Python version-->
-    <echo>Installing with second Python version (PATH=${build.dualversioninstall.path2})</echo>
-    <exec executable="python"
-          dir="${common.build_scripts_dir}"
-          failonerror="true">
-      <env key="PATH"
-           value="${build.dualversioninstall.path2}" />
-      <arg line='install_cone.py --target-dir="${build.cone_install_path_abs}" --plugin-package="${build.plugin_package}"' />
-    </exec>
-    <!-- Revert the SVN revision so that it doesn't mark the working copy as modified needlessly -->
-    <echo>Revert SVN revision in source/cone/__init__.py</echo>
-    <exec executable="python">
-      <arg value="update_svn_revision.py" />
-      <arg value="source/cone/__init__.py" />
-    </exec>
-  </target>
-  <target name="develop-cone">
-    <!-- Run the install script in build-scripts/ -->
-    <exec executable="python"
-          dir="${common.build_scripts_dir}"
-          failonerror="true">
-      <arg line='install_cone.py --target-dir="${build.cone_install_path_abs}" --plugin-package="${build.plugin_package}" --install-type develop' />
-    </exec>
-  </target>
-  <!--
+    <target name="_install-cone-dualversion-win" depends="svninitupdate" unless="os_is_linux">
+        <!-- Run the install script using the first Python version-->
+        <echo>Installing with first Python version (PATH=${build.dualversioninstall.path1})</echo>
+        <exec executable="python" dir="${build_scripts_dir}" failonerror="true">
+            <env key="PATH" value="${build.dualversioninstall.path1}"/>
+            <arg line='install_cone.py --target-dir="${build.cone_install_path_abs}" --plugin-package="${build.plugin_package}"'/>
+        </exec>
+        
+        <!-- Run the install script using the second Python version-->
+        <echo>Installing with second Python version (PATH=${build.dualversioninstall.path2})</echo>
+        <exec executable="python" dir="${build_scripts_dir}" failonerror="true">
+            <env key="PATH" value="${build.dualversioninstall.path2}"/>
+            <arg line='install_cone.py --target-dir="${build.cone_install_path_abs}" --plugin-package="${build.plugin_package}"'/>
+        </exec>
+        
+        <!-- Revert the SVN revision so that it doesn't mark the working copy as modified needlessly -->
+        <echo>Revert SVN revision in source/cone/__init__.py</echo>
+        <exec executable="python">
+            <arg value="update_svn_revision.py"/>
+            <arg value="source/cone/__init__.py"/>
+        </exec>
+    </target>
+    
+    <!--
+    Internal target for installing ConE on Linux so that it supports
+    two Python versions.
+    
+    Depends on two properties: build.dualversioninstall.executable1 and
+    build.dualversioninstall.executable1 that must be set to the Python
+    executables to run the installation (e.g. python2.5 and python2.6)
+    -->
+    <target name="_install-cone-dualversion-linux" depends="svninitupdate" if="os_is_linux">
+        <echo>Installing with first Python version (executable=${build.dualversioninstall.executable1})</echo>
+        <exec executable="python" dir="${build_scripts_dir}" failonerror="true">
+            <arg line='install_cone.py --target-dir="${build.cone_install_path_abs}" --plugin-package="${build.plugin_package}" --python-executable="${build.dualversioninstall.executable1}"'/>
+        </exec>
+        
+        <echo>Installing with second Python version (executable=${build.dualversioninstall.executable2})</echo>
+        <exec executable="python" dir="${build_scripts_dir}" failonerror="true">
+            <arg line='install_cone.py --target-dir="${build.cone_install_path_abs}" --plugin-package="${build.plugin_package}" --python-executable="${build.dualversioninstall.executable2}"'/>
+        </exec>
+        
+        <!-- Revert the SVN revision so that it doesn't mark the working copy as modified needlessly -->
+        <echo>Revert SVN revision in source/cone/__init__.py</echo>
+        <exec executable="python">
+            <arg value="update_svn_revision.py"/>
+            <arg value="source/cone/__init__.py"/>
+        </exec>
+    </target>
+    
+    <target name="install-cone-dualversion" depends="_install-cone-dualversion-win,_install-cone-dualversion-linux"/>
+    
+    <target name="develop-cone">
+        <!-- Run the install script in build-scripts/ -->
+        <exec executable="python" dir="${build_scripts_dir}" failonerror="true">
+            <arg line='install_cone.py --target-dir="${build.cone_install_path_abs}" --plugin-package="${build.plugin_package}" --install-type develop'/>
+        </exec>
+    </target>
+
+    <!--
     Internal pack target for packing the ConE installation.
     The actual dependencies to cone-install and cone-install-dualversion are
     specified in the actual targets below.
     -->
-  <target name="_pack">
-    <!--
+    <target name="_pack">
+        <!--
         <echo>$${build.cone_pack_path}:     ${build.cone_pack_path}</echo>
         <echo>$${build.cone_pack_path_abs}: ${build.cone_pack_path_abs}</echo>
         -->
-    <echo message="Creating zip file" />
-    <mkdir dir="${build.cone_pack_path_abs}" />
-    <tstamp>
-      <format property="lastbuild"
-              pattern="yyyyMMddHHmmss" />
-    </tstamp>
-    <zip destfile="${build.cone_pack_path_abs}/ConE-${common.version}-${build.plugin_package}-${lastbuild}-${svn.version}.zip">
-      <fileset dir="${build.cone_install_path_abs}" />
-    </zip>
-  </target>
-  <!-- Actual pack targets -->
-  <target name="pack"
-          depends="install-cone">
-    <antcall target="_pack" />
-  </target>
-  <target name="pack-dualversion"
-          depends="install-cone-dualversion">
-    <antcall target="_pack" />
-  </target>
-  <target name="export-bat">
-    <!--
-        <echo>$${build.bat_export_path}:     ${build.bat_export_path}</echo>
-        <echo>$${build.bat_export_path_abs}: ${build.bat_export_path_abs}</echo>
-        -->
-    <!-- Run the export script in build-scripts/ -->
-    <exec executable="python"
-          dir="${common.build_scripts_dir}"
-          failonerror="true">
-      <arg value="export_bat.py" />
-      <arg value='--target-dir="${build.bat_export_path_abs}"' />
-      <arg value='--plugin-package="${build.plugin_package}"' />
-    </exec>
-  </target>
-  <target name="pack-bat"
-          depends="export-bat">
-    <echo message="Creating zip file" />
-    <mkdir dir="${build.bat_pack_path_abs}" />
-    <zip destfile="${build.bat_pack_path_abs}/ConE-BAT-${build.plugin_package}.zip">
-      <fileset dir="${build.bat_export_path_abs}" />
-    </zip>
-  </target>
-  <target name="run-bat"
-          depends="install-cone,export-bat">
-    <echo message="Moving ConE installation under BAT..." />
-    <move todir="${build.bat_export_path_abs}/cone">
-      <fileset dir="${build.cone_install_path_abs}" />
-    </move>
-    <echo message="Running tests..." />
-    <exec executable="python"
-          dir="${build.bat_export_path_abs}">
-      <arg value="runtests.py" />
-    </exec>
-  </target>
-  <target name="run-all-tests">
-    <echo message="Run all tests" />
-    <echo message="OS: ${os.name}" />
-    <echo message="Python version: ${pythonversion}" />
-    <subant buildpath="."
-            target="run-all-tests-linux" />
-    <subant buildpath="."
-            target="run-all-tests-windows" />
-  </target>
-  <target name="run-all-tests-linux"
-          if="os_is_linux">
-    <echo message="Change Python version" />
-    <echo message="ln -s -f /usr/bin/${pythonversion} ${os.linux.userbin}/python" />
-    <exec executable="ln">
-      <arg value="-s" />
-      <arg value="-f" />
-      <arg value="/usr/bin/${pythonversion}" />
-      <arg value="${os.linux.userbin}/python" />
-    </exec>
-    <echo message="Python version:" />
-    <exec executable="sh"
-          dir="./source">
-      <env key="PATH"
-           path="${os.linux.userbin}:${env.PATH}" />
-      <arg value="-c" />
-      <arg value="python --version" />
-    </exec>
-    <echo message="Run tests" />
-    <exec executable="sh"
-          dir="./source">
-      <env key="PATH"
-           path="${os.linux.userbin}:${env.PATH}" />
-      <arg value="-c" />
-      <arg value="python runtests.py --with-nose" />
-    </exec>
-  </target>
-  <target name="run-all-tests-windows"
-          unless="os_is_linux">
-    <echo message="Change Python version" />
-    <echo message="Python version:" />
-    <exec executable="cmd">
-      <env key="PATH"
-           path="${os.windows.pythonlocationbase}${pythonversion};${os.windows.pythonlocationbase}${pythonversion}/Scripts;${env.PATH}" />
-      <arg value="/c" />
-      <arg value="python --version" />
-    </exec>
-    <echo message="Run tests" />
-    <exec executable="cmd"
-          dir="./source">
-      <env key="PATH"
-           path="${os.windows.pythonlocationbase}${pythonversion};${os.windows.pythonlocationbase}${pythonversion}/Scripts;${env.PATH}" />
-      <arg value="/c" />
-      <arg value="python runtests.py --with-nose" />
-    </exec>
-  </target>
-  <import file="generatedoc-build.xml" />
+
+        <echo message="Creating zip file"/>
+        <mkdir dir="${build.cone_pack_path_abs}"/>
+
+        <tstamp>
+               <format property="lastbuild" pattern="yyyyMMddHHmmss"/>
+        </tstamp>
+
+        <zip destfile="${build.cone_pack_path_abs}/ConE-${common.version}-${build.plugin_package}-${lastbuild}-${svn.version}.zip">
+            <fileset dir="${build.cone_install_path_abs}"/>
+        </zip>
+    </target>
+    
+    <!-- Actual pack targets -->
+    <target name="pack" depends="install-cone">
+        <antcall target="_pack"/>
+    </target>
+    <target name="pack-dualversion" depends="install-cone-dualversion">
+        <antcall target="_pack"/>
+    </target>
+
+
+    <target name="export-bat">
+    	<!-- Linux: set the correct python version -->		
+		<antcall target="_create-python-version-symlink" />
+        <!-- Run the export script in build-scripts/ -->
+        <exec executable="${cmd_name}" dir="${build_scripts_dir}" failonerror="true">
+            <env key="PATH" value="${full_path}" />
+            <arg value="${cmd_switch}" />
+			<arg value='python export_bat.py --target-dir="${build.bat_export_path_abs}" --plugin-package="${build.plugin_package}"'/>
+        </exec>
+    </target>
+
+    <target name="pack-bat" depends="export-bat">
+        <echo message="Creating zip file"/>
+        <mkdir dir="${build.bat_pack_path_abs}"/>
+
+        <zip destfile="${build.bat_pack_path_abs}/ConE-BAT-${build.plugin_package}.zip">
+            <fileset dir="${build.bat_export_path_abs}"/>
+        </zip>
+    </target>
+    
+	<!-- Linux: Create a symbolic link to the Python version used -->
+    <target name="_create-python-version-symlink" if="create_symlink">
+		<echo message="Change Python version on Linux" />
+        <echo message="Deleting old symlink"/>        
+        <delete file="${os.linux.userbin}/python" />
+        <echo message="ln -s -f /usr/bin/${pythonversion} ${os.linux.userbin}/python" />
+        <exec executable="ln">
+		    <arg value="-s" />
+		    <arg value="-f" />
+		    <arg value="/usr/bin/${pythonversion}" />
+		    <arg value="${os.linux.userbin}/python" />
+	    </exec>
+    </target>
+
+    <target name="run-bat" depends="install-cone, export-bat">
+        <echo message="Running BAT tests..."/>
+  
+        <echo message="Moving ConE installation under BAT..."/>
+        <move todir="${build.bat_export_path_abs}/cone">
+            <fileset dir="${build.cone_install_path_abs}"/>
+        </move>
+		
+		<exec executable="${cmd_name}" dir="${build.bat_export_path_abs}">
+            <env key="PATH" path="${full_path}" />
+            <arg value="${cmd_switch}" />
+            <arg value="python runtests.py --with-nose"/>
+        </exec>
+    </target>
+
+
+    <target name="run-all-tests" depends="build-cone">
+		<echo message="Run all tests" />
+		<echo message="OS: ${os.name}" />
+		<!-- Linux: Set the correct Python version -->
+		<antcall target="_create-python-version-symlink" />
+		
+		<echo message="Python version:" />
+		<exec executable="${cmd_name}" dir="./source">
+			<env key="PATH" path="${full_path}" />
+			<arg value="${cmd_switch}" />
+			<arg value="python --version" />
+		</exec>
+		<echo message="Run tests" />
+		<exec executable="${cmd_name}" dir="./source">
+			<env key="PATH" path="${full_path}" />
+			<env key="PYTHONPATH" path="${cone_python_path}" />
+			<arg value="${cmd_switch}" />
+			<arg value="python runtests.py" />
+		</exec>
+    </target>
+	
+    <import file="generatedoc-build.xml"/>
 </project>
--- a/configurationengine/common.properties	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/common.properties	Tue Aug 10 14:29:28 2010 +0300
@@ -4,8 +4,10 @@
  ****************************************************************************-->
 
 # ConE version that is added to the produced ZIP file
-common.version = 1.1
+common.version = 1.2.11
 
 common.build_scripts_dir = build-scripts
 
 document.output        =docbuild
+build.plugin_package = symbian
+cone_python_path = ./source;./source/testautomation;./source/plugins/common/ConeCommandPlugin;./source/plugins/common/ConeLegacyRulePlugin;./source/plugins/common/ConeRulePlugin;./source/plugins/common/ConeTemplatePlugin;./source/plugins/symbian/ConeCRMLPlugin;./source/plugins/common/ConeContentPlugin;./source/plugins/example/ConeExamplePlugin;./source/plugins/symbian/ConeGenconfmlPlugin;./source/plugins/symbian/ConeHCRPlugin;./source/plugins/symbian/ConeProjectConverterPlugin;./source/plugins/symbian/ConeThemePlugin;./source/plugins/symbian/ConeImagePlugin;
\ No newline at end of file
--- a/configurationengine/debian/control	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/debian/control	Tue Aug 10 14:29:28 2010 +0300
@@ -5,7 +5,7 @@
 Build-Depends: debhelper (>= 5), python (>=2.4), python-central, python-setuptools
 Standards-Version: 3.7.2
 XS-Python-Version: >= 2.4
-Homepage: http://developer.symbian.org/wiki/index.php/Software_Configuration_Middleware
+Homepage: http://developer.symbian.org/wiki/index.php/Software_Configuration_Middleware/ConE
 
 Package: python-cone
 Architecture: all
--- a/configurationengine/debian/copyright	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/debian/copyright	Tue Aug 10 14:29:28 2010 +0300
@@ -1,7 +1,7 @@
 This package was debianized by Zoltan Andrasi <zoltan.andrasi@nokia.com> on
 Thu, 11 Dec 2008 11:57:50 +0200.
 
-It was downloaded from http://developer.symbian.org/wiki/index.php/Software_Configuration_Middleware
+It was downloaded from http://developer.symbian.org/wiki/index.php/Software_Configuration_Middleware/ConE
 
 Upstream Author(s):
 
Binary file configurationengine/dep-eggs/Jinja2-2.1.1-py2.5-win32.egg has changed
Binary file configurationengine/dep-eggs/Jinja2-2.1.1-py2.6-win32.egg has changed
--- a/configurationengine/doc/api/api.rst	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/doc/api/api.rst	Tue Aug 10 14:29:28 2010 +0300
@@ -1,5 +1,8 @@
-Cone API
+
+.. _cone-api:
+ConE API
 ========
+
 The Cone API consists of submodules that contain the actual api implementations. The modules are splitted according to the purpose of use. 
 * public api is the main public interface that Cone offers.
 * plugin api is the interface which defines all plugin extension base classes and a general plugin framework.
@@ -7,7 +10,7 @@
 modules:
 
 .. toctree::
-
+    :maxdepth: 3
+    
     public
     plugin
-    howto
--- a/configurationengine/doc/api/howto.rst	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/doc/api/howto.rst	Tue Aug 10 14:29:28 2010 +0300
@@ -1,15 +1,22 @@
+.. _cone-api-howto:
+
 How to use cone APIs
 ====================
 
 The ConE public usage is described here with few common use cases as HowTo guides. 
 
+* See `Cone API epydoc <../epydoc/index.html>`_ for reference guide of api functions.
+
 How to open a Configuration project
 -----------------------------------
 
+* See reference of `Project class <../epydoc/cone.public.api.Project-class.html>`_
+
 To open a project with ConE the api offers a Storage and Project classes. The Storage is the storage 
 agostic implemenetation for cpf/zip, filestorage and soon also a webstorage. To access anything in ConE 
 you must a project open. 
 
+
 .. code-block:: python 
 
     from cone.public import api,exceptions
@@ -33,6 +40,8 @@
 How to access and manipulate Configurations
 -------------------------------------------
 
+* See reference of `Configuration class <../epydoc/cone.public.api.Configuration-class.html>`_
+
 A Configuration normally is presented inside the Configuration project as a .confml file. So when you
 are accessing configurations your are actually accessing confml files. The project offers funtionality to 
 get,add, remove configurations, which acts on root configurations inside the given project.
@@ -92,8 +101,51 @@
     myconfig = prj.get_configuration('myconfig.confml')
     myconfig.include_configuration('../data.confml')
 
+
+How to set / write metadata to a Configuration root file
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The metadata element is currently confml model specific, so you need to import the confml.model to enable metadata writing.
+The ConfmlMeta element is desinged so that it can contain several ConfmlMetaProperty elements, each of which can be in 
+different xml namespaces.
+
+.. code-block:: python
+
+    from cone.public import api
+    from cone.confml import model
+    
+    store  = api.Storage.open(".","w")
+    prj = api.Project(store)
+    config = prj.create_configuration("test_meta.confml")
+    
+    prop1 = model.ConfmlMetaProperty("test", 'testing string')
+    prop2 = model.ConfmlMetaProperty("testName", 'testing string2', \
+                                     "http://www.nokia.com/xml/cpf-id/1", \
+                                     attrs={"name":"name1", "value": "value1"})            
+    prop3 = model.ConfmlMetaProperty("configuration-property", None, \
+                                     "http://www.nokia.com/xml/cpf-id/1", \
+                                     attrs={"name":"sw_version", "value": "1.0.0"})            
+    metaelem = model.ConfmlMeta([prop1, prop2, prop3])
+    
+    config.meta = metaelem
+    config.save()
+    prj.close()
+
+The output file *test_meta.confml* should look like this..
+
+.. code-block:: xml
+
+    <configuration name="test_meta_confml" xmlns="http://www.s60.com/xml/confml/2" ...>
+      <meta xmlns:cv="http://www.nokia.com/xml/cpf-id/1">
+        <test>testing string</test>
+        <cv:testName name="name1" value="value1">testing string2</cv:testName>
+        <cv:configuration-property name="sw_version" value="1.0.0" />
+      </meta>
+    </configuration>
+
 Feature Access and manipulation
 -------------------------------
+* See reference of `Feature class <../epydoc/cone.public.api.Feature-class.html>`_
 
 How to add a Feature to Configuration
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -131,6 +183,12 @@
     prj.close()
 
 
+Feature acces via Views 
+-----------------------
+* See reference of `View class <../epydoc/cone.public.api.View-class.html>`_
+* See reference of `Group class <../epydoc/cone.public.api.Group-class.html>`_
+* See reference of `FeatureLink class <../epydoc/cone.public.api.FeatureLink-class.html>`_
+
 How to get a Feature from Configuration
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -269,6 +327,61 @@
     prj.save()
     prj.close()
 
+
+How to Create a View
+^^^^^^^^^^^^^^^^^^^^
+
+.. code-block:: python
+
+    from cone.public import api
+    from cone.confml import model
+    
+    store  = api.Storage.open(".","w")
+    prj = api.Project(store)
+    """ First create the configuration with two features """
+    if prj.is_configuration("test_override.confml"):
+        config = prj.get_configuration("test_override.confml")
+    else:
+        config = prj.create_configuration("test_override.confml")
+    fea1 = config.create_feature("foo", name="foo name")
+    fea2 = fea1.create_feature("bar", name="bar name")
+    
+    """ Create the view and group to it """
+    view = config.create_view('testview')
+    group = view.create_group('group1')
+    
+    """ 
+    Create a featurelink.
+    Note! the featurelink now overrides the name attribute of the original feature.
+    """
+    link = group.create_featurelink('foo', name="foo name overridden")
+    """ override the description attribute of the view link """
+    link.desc = "override desc" 
+    config.save()
+
+How to Get a view and test attribute overrides
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+In this example we assume that the previous example was stored to a file *test_override.confml*.
+
+.. code-block:: python
+
+    from cone.public import api
+    from cone.confml import model
+    
+    store  = api.Storage.open(".","w")
+    prj = api.Project(store)
+    config = prj.get_configuration("test_override.confml")
+    """ get the view and a feature from it """
+    view = config.get_view('testview')
+    fea = view.get_feature('group1.foo')
+    """ assert that the feature attributes have been overridden in the view """ 
+    assert(fea.has_attribute('name'))
+    assert(fea.has_attribute('desc'))
+    assert(fea.has_attribute('minLength') == False)
+    assert(fea._obj.name == 'foo name')
+    prj.close()
+
+
 Data access and manipulation
 ----------------------------
 The data access inside a configuration is possible, but basically this can be avoided by manipulating the values 
--- a/configurationengine/doc/api/plugin.rst	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/doc/api/plugin.rst	Tue Aug 10 14:29:28 2010 +0300
@@ -1,91 +1,24 @@
-Plugin API
-===============
-
-.. module:: cone.public.plugin
-   :platform: Unix, Windows
-   :synopsis: Configuration interface.
-.. moduleauthor:: Teemu Rytkonen <teemu.rytkonen@nokia.com>
+.. _plugin-api:
 
-The Plugin api is intended for extending the ConE functionality with plugins that can be for example 
-implementation or relation plugins. See :ref:`plugin-howto`
-
-.. image:: cone_plugin_api.png
-
-Classes
--------
-
-.. class:: ImplBase(ref, configuration)
-
-The ImplBase class is intended for deriving any implementation plugin in ConE. A single ImplBase 
-instance is created by ConE for each implml file inside a given Configuration. 
+Extending ConE with plugin API
+==============================
 
-See :ref:`plugin-howto`
- 
-    .. method:: list_output_files()
-  
-    The list_output_files should return a list of output files with path, with the current configuration.
-    This mechanism should enable listing of all output files before without actually generating them.
-
-    .. method:: generate()
-  
-    The plugin instance is supposed to generate its output with the call of generate(). 
+The Plugin api is intended for extending the ConE functionality with plugins.
+Currently there are two ways to extend the functionality:
 
-    .. method:: has_ref(refs)
-  
-    This method receives a list as an attribute and is supposed to return True|False. True if this 
-    particular plugin instance has a reference to a Feature inside the given refs list. Otherwise False. 
-
-.. class:: ImplSet
-
-The ImplSet is a sets.Set object for a set of ImplBase instances. The main purpose of ImplSet 
-is to allow operations to a set of ImplBase instances, such as generate, filter, etc. 
-
-.. class:: ImplFactory
-
-ImplFactory is a constructor class for the plugin instances.
+1. Adding support for new implementation languages
+2. Extending ConfML or ImplML validation
 
-    .. method:: get_impl_by_ext(cls, ext)
-  
-    Get the class name by file extension. 
-    
-
-    .. method:: get_impl_by_filename(cls, ref, configuration)
+Usually a plug-in that provides a new implementation language also provides
+validation for it.
 
-    Get the class name by filename.
-
-.. class:: Relation(left, right)
-
-    .. method:: execute()
-  
-    Executes the rule initiated for this Relation.
-
+Developing a ConE plugin
+------------------------
+* See `Cone API epydoc <../epydoc/index.html>`_ for reference guide.
 
-	Relation is a base class for all Relation implementations. The purpose of a Relation instance is to offer a verb or an 
-	action that can be used in a rule. A rule in this context means a textual relation between two or more :class:`Feature`'s.
-	For example a Depends class could be used to define dependencies between two :class:`Feature`
-  
-	::
-	
-		example rule
-	  	A depends B
-	
-	Where A and B are :class:`Feature` references.
+.. toctree::
+    :maxdepth: 3
 
-.. class:: RelationContainer
-	
-	RelationContainer is a container object that derives Relation interface, but is meant for storing a set of :class:`Relation`
-	objects. It can be used to execute a set of rules read to the container.
-
-.. class:: RelationFactory
-
-    .. method:: get_by_name(name)
-  
-    returns a :class:`Relation` if the class that matches the name is found. 
-
-	The RelationFactory is intended to be used when the rules are read from some persistent storage. When a rule is found from 
-	:class:`Configuration` ConE will try to create a :class:`Relation` instance of the rule, by trying to get class 
-	by :meth:`RelationFactory.get_by_name` and create an instance of that class.
-	
-
-
-
+    ../plugins/dev-plugin/plugin-interface
+    ../plugins/dev-plugin/index
+    ../plugins/dev-plugin/validation-plugin-index
\ No newline at end of file
--- a/configurationengine/doc/api/public.rst	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/doc/api/public.rst	Tue Aug 10 14:29:28 2010 +0300
@@ -1,147 +1,21 @@
-Public API
-**********
-Cone public API is the main interface of Cone.
-
-.. image:: cone_public_api.png
+.. _cone-public-api:
 
-
-.. module:: cone.public.api
-   :platform: Unix, Windows
-   :synopsis: Configuration interface.
-.. moduleauthor:: Teemu Rytkonen <teemu.rytkonen@nokia.com>
+Using ConE public API
+=====================
 
-Classes
--------
-.. class:: ObjectContainer
+Cone public API is the main interface of Cone. 
 
-	ObjectContainer is a base class for all Configuration related elements. It is container class for a tree structure, 
-	where it can contain other ObjectContainer objects. So basically you can create B-tree type of hiararchy with it. 
-	
-	The main functionality of ObjectContainer is that **all children of an object container are accessible as members** 
-	of the container.
-	
-	.. _example_member_access:
-	
-	Example of ObjectContainer member access:
-	
-	``objcontainer.configuration.get_name()``
-	
+Developing with ConE API
+------------------------ 
+The ConE public API is described most accurately in the generated api documentation, which can be used as a reference guide.
 
-	.. method:: _add(child)
-	
-	Add a ObjectContainer instance to this object. Checks with internal function :meth:`__supported_type__` if the given 
-	child is a supported class for this object.
-	
-	.. method:: _add_to_path(path,child)
-	
-	Add a ObjectContainer instance to a specific node under this object. It creates any missing nodes between this object 
-	and the path. For example __add_to_path__("foo.fii", obj), would create two nodes (foo and under it fii) if they are 
-	missing (Uses internal :meth:`__default_class__` to retrieve the class which is created in this case). 
-	
-	.. method:: _remove(path)
-	
-	Remove a child from given path.
-	
-	.. method:: _get(path)
-	
-	get a child from given path.
-	
-	.. method:: _list()
-	
-	Get a list of names of immediate children of this ObjectContainer instance.
-	
-	.. method:: _objects()
-	
-	Get a list of immediate children objects of this ObjectContainer instance.
-	
-	.. method:: _traverse(filters)
-	
-	Get a list of children objects of this ObjectContainer instance, by filtering them with filters. This will cause a 
-	recursive _traverse method call to all children of the ObjectContainer.
-	
-	.. method:: _path(toparent=None)
-	
-	Return the path to this object up to the toparent object. When toparent=None this will 
-	return a full path to the object in the ObjectContainer hierarhcy.
-	
-	.. method:: _supported_type(obj)
-	
-	A method that is supposed to be overridden by the deriving classed if they need to change, which classes can be added 
-	under each class. 
-	Return True if the type of the obj is supported.
-	
-	.. method:: _default_class(obj)
-	
-	A method that is supposed to be overridden by the deriving classed if they need to change, what class is 
-	the default class that is created with __add_to_path__ when objects are missing.
-	Return a class.
-
-  
-.. class:: Base
+* See `Cone API epydoc <../epydoc/index.html>`_ reference guide.
 
-	Base class for all :class:`~cone.public.api.Configuration` and its child objects. 
-  
-	.. method:: get_ref()
-	
-	return the ref of this object.
-	
-	.. method:: get_namepace()
-	
-	return the namespace of this object.
-	
-.. class:: Project
-
-	Project is a container for Configuration's.
+Example usage of ConE public API
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+The below section is a example orientated desciption of ConE public api usage. 
 
-.. class:: Configuration
-  
-	ConE Configuration is the main interface for all configuration related activities. It is the main interface of ConE 
-	itself as ConE is eventually a python interface to a configuration project. 
-	 
-Configuration as a Container
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-	    
-	The Configuration instance itself in ConE is actually just a container for a bunch of different elements. These elements can practically be any elements that exist in a 
-	Configuration Project. 
-	
-	* :class:`~cone.public.api.Configuration` 
-	* :class:`~cone.public.api.View`
-	* :class:`~cone.public.api.Feature` 
-	* :class:`~cone.public.api.Resource` 
-	* :class:`~cone.public.plugin.Relation` 
-	* :class:`~cone.public.api.Data` 
-  
-.. class:: Feature
-	    
-	Feature element is the base class for any Configurable item in a Configuration Project.
-
-.. class:: View
+.. toctree::
 
-	A :class:`~cone.public.api.Configuration` can contain one or more View elements, which basically can define different type of tree structure of Feature elements that exist in the Configuration.
-	A View element can contain :class:`~cone.public.api.Group` and :class:`FeaturePoxy` elements.
-
-.. class:: Group
-
-	Group element can be child element of a :class:`~View`. It can include other Groups and :class:`~FeaturePoxy` elements to define a View hierarhcy.
-
-.. class:: FeatureProxy
-    
-	FeatureProxy element is a linking object inside View that has its own ref, name, etc but it basically just 
-	points to an actual :class:`Feature` instance.
-
-.. class:: Data
+    howto
 
-	Data element defines a data value for a :class:`Feature` element. The Data elements can be defined in a 
-	:class:`Configuration` and single configurable :class:`Feature` can have multiple data definitions, in different 
-	configurations. The new definition always overrides the previous one. However the entire data definition hierarchy 
-	is stored and is available from the Cone API.
-	
-.. class:: Storage
-
-	Storage offers platform and persistence independent interface to store :class:`Resource` elements (data files, 
-	configuration files, etc).
-
-.. class:: Resource
-	
-	Resource is an instance of single storable element. Basically on normal filesystem this would be same as one file.
-	
--- a/configurationengine/doc/cli/common.rst	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/doc/cli/common.rst	Tue Aug 10 14:29:28 2010 +0300
@@ -1,3 +1,5 @@
+.. _cone-cli:
+
 Cone command line interface
 ===========================
 
@@ -19,45 +21,48 @@
     cone --help
   
 And you will get something like this as output::
-
-    Usage: cone_tool.py [action] [options].
+    
+    Usage: ConE [action] [options].
+    
+    
+    Use ConE [action] -h to get action specific help.
     
     Available actions
-        info
-        compare
-        merge
-        export
-        generate
-        update
+    Main actions for one or more configurations.
+        compare : Compare two configurations
+        fix : Run automatic fixes for configurations.
+        generate : Generate a configuration.
+        report : Create report of existing report data.
+        update : Update/set values to features in configuration(s).
+        validate : Validate a configuration, or individual confml/imp
     
-    Use cone_tool.py [action] -h to get action specific help.
     
-    Options:
-      --version                         show program's version number and exit
-      -h, --help                        show this help message and exit 
-      -c CONFIG, --configuration=CONFIG  Define the name of the configuration for the action
-      -v LEVEL, --verbose=LEVEL          Print error, warning and information on system out. 
-                                            Possible choices:
-                                                NONE 0
-                                                CRITICAL 1 
-                                                ERROR 2 
-                                                WARNING 3 
-                                                INFO 4 
-                                                DEBUG 5 
-                                            Default is 3.
-      -p STORAGE, --project=STORAGE      Defines the location of current project. Default is the current working directory.
+    Actions related to the configuration project maintenance.
+        export : Export configurations.
+        info : Get information about project / configurations.
+        merge : Merge a configuration/layer to the project.
+    
+    
+    extensions:
+        initvariant : Initialize a variant from a cpf.
+        packvariant : Pack (zip) the variant layers of a configuration.
+        rootflatten : Configuration root flattener.
 
 
 ConE actions
 ------------
 .. toctree::
-    :maxdepth: 2
+    :maxdepth: 1
 
-    info
+    generate
+    fix
     compare
+    report
+    update
+    validate
+    export
     merge
-    export
-    generate
-    update
-    report
+    info
+    initvariant
+    rootflatten
 
--- a/configurationengine/doc/cli/compare.rst	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/doc/cli/compare.rst	Tue Aug 10 14:29:28 2010 +0300
@@ -13,9 +13,12 @@
     >cd configproject_root
     >cone compare -s configuration_root1.confml -t configuration_root2.confml
 
-By default the output is generated under current folder to compare.html (use switch --report=FILENAME
+The output is generated under current folder.
+By default the compare type is data comparison to data_comparison.html (use switch --report=FILENAME
 to change the output file).
 
+* Example output `Data comparison report <../_static/data_comparison.html>`_
+
 **Compare configurations between the current storage and some remote storage**:
 
 The target configuration can also include remote storage path, which must be separated from the 
@@ -31,6 +34,23 @@
     >cd configproject_root
     >cone compare -s configuration_root1.confml -t \config_project2;configuration_root2.confml --report-type api
 
+* Example output `API comparison report <../_static/api_comparison.html>`_
+
+**Compare Customisation interface to a product configuration interface**
+
+The **ci** comparison is created for specific comparison of Customisation interface to a product configuration interface. Its purpose is to find out differences between the CI and actual developer confmls (for example in assets/s60 layer). It compares the source configuration to target and reports differences and source features that are missing from target configuration. 
+
+Use the --report-type switch make an ci (CustomisationInterface) comparison.::
+
+    >cd configproject_root
+    >cone compare -s customisation\CustomisationInterface\ci_root.confml -t vasco_langpack_01_root.confml --report-type=ci
+    Writing report to ci_comparison.html
+    Generated report to 'ci_comparison.html'
+    Done.
+
+* Example output `CI comparison report <../_static/ci_comparison.html>`_
+
+
 **Compare configurations using a custom template**
 
 Use the --template switch to specify a custom template file.::
@@ -87,9 +107,12 @@
     --report-type=TYPE  The type of the report to generate. This is a
                         convenience switch for setting the used template.
                         Possible values:
-                        api  - Report changes in feature definitions
+                        api - Report changes in feature definitions
+                        ci - Report changes in CustomisationInterface definitions
+                        crml_dc - Report CRML data compatibility issues
+                        crml_dc_csv - Report CRML data compatibility issues
+                        (CSV format)
                         data - Report changes in data values
-                        crml_dc - Report CRML data compatibility issues
     --impl-filter=PATTERN
                         The pattern used for filtering implementations for the
                         comparison. See the switch --impl in action generate
--- a/configurationengine/doc/cli/export.rst	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/doc/cli/export.rst	Tue Aug 10 14:29:28 2010 +0300
@@ -3,12 +3,12 @@
 Running action export
 Usage: cone export [options]
 
-The export functionality exports configurations from the current project to a remote project. Default value for the current project is the currently working directory. A project can be either a folder or a CPF/ZIP file.
+The export functionality exports configurations from the current project to a remote project. Default value for the current project is the currently working directory. A project can be either a folder or a CPF/ZIP file or even a Carbon webstorage (via ExtAPI).
 
 Examples
 --------
 
-**Export a configuration from folder to a zip file**::
+**Export a configuration from configuration project folder to a zip file**::
 
     >cd configproject_root
     >cone export -c configuration_root.confml --remote=exported.zip
@@ -39,17 +39,24 @@
     >cd configproject_root
     >cone export --remote http://carbonqa.nokia.com/extapi -c configuration_root.confml 
 
+**Export a configuration and run a action during the export**::
+ConE can also run separate actions during the exporting for example to fix model level errors if possible. To run for example the fix step during export you can use --run-action=fix attribute.
+
+    >cd configproject_root
+    >cone export -c configuration_root.confml --remote=../export_folder --run-action=fix
 
 
 Options list
 ------------
+Options:
   --version             show program's version number and exit
   -h, --help            show this help message and exit
   --print-settings      Print all the default settings from the current
                         setting container.
   --print-supported-impls
                         Print all supported ImplML XML namespaces and file
-                        extension.
+                        extensions.
+  --print-runtime-info  Print runtime information about ConE.
   -v LEVEL, --verbose=LEVEL
                         Print error, warning and information on system out.
                         Possible choices: Default is 3.
@@ -60,24 +67,66 @@
                         INFO          4
                         DEBUG         5
   --log-file=FILE       Location of the used log file. Default is 'cone.log'
+  --log-config=FILE     Location of the used logging configuration file.
+                        Default is 'logging.ini'
+  --username=USERNAME   Username for webstorage operations. Not needed for
+                        filestorage or cpf storage. If the username
+                        is not given, the tool will use the logged in
+                        username. Example: cone export -p webstorage_url -r .
+                        -c sample.confml --username=admin --password=abc123.
+  --password=PASSWORD   Password for webstorage operations. Not needed for
+                        filestorage or cpf storage. If the password
+                        is not given, the tool will prompt for password if
+                        needed.
   -c CONFIG, --configuration=CONFIG
-                        defines the name of the configuration for the action
+                        Defines the name of the configuration for the action,
+                        can be specified multiple times to include multiple
+                        configurations.
+  --config-wildcard=WILDCARD
+                        Wildcard pattern for including configurations, e.g.
+                        product_langpack_*_root.confml
+  --config-regex=REGEX  Regular expression for including configurations, e.g.
+                        product_langpack_\d{2}_root.confml
   -p STORAGE, --project=STORAGE
                         defines the location of current project. Default is
                         the current working directory.
 
   Export options:
-    The export functionality is meant to export configurations between
-    current project (defined with -p) to an remote project (defined with
-    -r). Default value for the current project is the currently working
-    directory. A project can be either a folder or a cpf/zip file.
+    The export action is intended for exporting configurations from one
+    project (storage) to another. A project can be a folder, a CPF or ZIP
+    file, or a Carbon web storage URL.
+    Two different ways of exporting are supported:
+    1. Exporting multiple configurations into one new project using
+    --remote
+    2. Exporting configurations into a number of new projects using
+    --export-dir
 
     -r STORAGE, --remote=STORAGE
-                        defines the location of remote storage. Default name
-                        for remote storage is the source configuration name
-    -a SET, --add=SET   Add a configuration layer to the given configuration
-                        as last element.The add operation can be used several
+                        Defines the location of remote storage. All
+                        configurations included using --configuration,
+                        --config-wildcard and --config-regex are exported into
+                        the storage. If the remote storage location is not
+                        given, the default location is determined based on the
+                        first included source configuration name. E.g.
+                        'example.confml' would be exported into 'example.cpf'
+    --export-dir=EXPORT_DIR
+                        Defines the directory where each included
+                        configuration is exported as a new project.
+    --export-format=EXPORT_FORMAT
+                        Defines the format into which projects are exported
+                        when using --export-dir. Possible values are 'cpf'
+                        (the default) and 'dir'.
+    -a CONFIG, --add=CONFIG
+                        Adds a configuration layer to the given configuration
+                        as last element. The add operation can be used several
                         times in a single command and it can create even an
-                        empty layer.Example --add foo/root.confml --add bar
+                        empty layer. Example --add foo/root.confml --add bar
                         /root-confml.
-    --exclude-folders   Excludes empty folders from .cpf export
+    --run-action=PLUGIN
+                        Adds a execution of extra step that can manipulate the
+                        configuration before it is exported to external
+                        storage. The --run-action operation can be used
+                        several times in a single command and it will execute
+                        the actions in given order.Example --run-action=fix,
+                        which would execute fix action during export.
+    --exclude-folders   Excludes empty folders from export
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/cli/fix.rst	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,81 @@
+ConE fix action
+================
+Running action fix
+Usage: cone fix [options]
+
+The fix functionality is meant for running possible automatic fixes to problems which validation reports.
+
+Examples
+--------
+
+**Fix a configuration**::
+
+    >cd configproject_root
+    >cone fix -c configuration_root.confml
+
+or use the option -p|--project to point to the configuration project root::
+
+    >cone fix --project=configproject_root -c configuration_root.confml
+
+**Print a list of available fix classes**::
+
+    >cone fix --print-available-fixes
+    
+    Running action fix
+    Available fixers:
+    <class 'cone.validation.builtinvalidators.confml.DuplicateFeatureFixer'>:
+        A Fix class for duplicate features that merges all setting under a duplicate feature
+        to the first instance of the feature and removes the duplicates.
+        
+Options list
+------------
+  --version             show program's version number and exit
+  -h, --help            show this help message and exit
+  --print-settings      Print all the default settings from the current
+                        setting container.
+  --print-supported-impls
+                        Print all supported ImplML XML namespaces and file
+                        extensions.
+  --print-runtime-info  Print runtime information about ConE.
+  -v LEVEL, --verbose=LEVEL
+                        Print error, warning and information on system out.
+                        Possible choices: Default is 3.
+                        NONE (all)    0
+                        CRITICAL      1
+                        ERROR         2
+                        WARNING       3
+                        INFO          4
+                        DEBUG         5
+  --log-file=FILE       Location of the used log file. Default is 'cone.log'
+  --log-config=FILE     Location of the used logging configuration file.
+                        Default is 'logging.ini'
+  --username=USERNAME   Username for webstorage operations. Not needed for
+                        filestorage or cpf storage. If the username
+                        is not given, the tool will use the logged in
+                        username. Example: cone export -p webstorage_url -r .
+                        -c sample.confml --username=admin --password=abc123.
+  --password=PASSWORD   Password for webstorage operations. Not needed for
+                        filestorage or cpf storage. If the password
+                        is not given, the tool will prompt for password if
+                        needed.
+  -c CONFIG, --configuration=CONFIG
+                        Defines the name of the configuration for the action
+  -p STORAGE, --project=STORAGE
+                        defines the location of current project. Default is
+                        the current working directory.
+
+  Fix options:
+    The fix action is intended for performing fixes on a
+    configuration.
+
+    --print-available-fixes
+                        Print all configuration fixer objects available.
+    --exclude-filter=EXCLUDE_FILTER
+                        Exclude problems by given filter. Examples: --exclude-
+                        filter=schema, --exclude-filter=schema.implml,
+                        --exclude-filter=schema.confml, --exclude-
+                        filter=schema.implml.ruleml
+    --include-filter=INCLUDE_FILTER
+                        Include problems by given filter.Examples: --include-
+                        filter=schema.implml, --include-
+                        filter=schema.implml.ruleml
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/cli/initvariant.rst	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,98 @@
+ConE initvariant action
+=======================
+
+The *initvariant* action is intended for merging a variant CPF back into the
+configuration project. It is basically a special-purpose merge action that
+merges all customer variant layers (layers with ``custvariant*`` in their path
+name) and renames them based on the given variant ID and variant name
+(``custvariant_<id>_<name>``).
+
+Examples
+--------
+
+**Merging a variant CPF using variant ID and name**::
+
+    > cd configproject_root
+    > cone initvariant -r variant.cpf --variant-id 123 --variant-name foobar
+
+This will merge customer variant layers into the project. The configuration
+root into which they are merged is also determined automatically based on the
+supplied information. The automatically determined root file is named
+``<product-name>_custvariant_<variant-id>_<variant-name>_root.confml``,
+and the merged layers will have ``custvariant_<variant-id>_<variant-name>``
+as part of their layer path.
+E.g. the layer ``familyx/productx/customer/custvariant/configurator/root.confml``
+is merged as ``familyx/productx/customer/custvariant_123_foobar/configurator/root.confml``
+and the configuration root would be ``productx_custvariant_123_foobar_root.confml``.
+
+**Merging a variant CPF into a specific root file**::
+
+    > cd configproject_root
+    > cone initvariant -r variant.cpf --variant-id 123 -c foovariant.confml
+
+This does basically the same thing as the previous command, except that the
+configuration root into which the merge is done is explicitly specified. Also,
+the optional argument ``--variant-name`` is missing, so the layers will be merged
+as ``custvariant_<variant-id>``.
+
+Options list
+------------
+  --version             show program's version number and exit
+  -h, --help            show this help message and exit
+  --print-settings      Print all the default settings from the current
+                        setting container.
+  --print-supported-impls
+                        Print all supported ImplML XML namespaces and file
+                        extensions.
+  --print-runtime-info  Print runtime information about ConE.
+  -v LEVEL, --verbose=LEVEL
+                        Print error, warning and information on system out.
+                        Possible choices: Default is 3.
+                        NONE (all)    0
+                        CRITICAL      1
+                        ERROR         2
+                        WARNING       3
+                        INFO          4
+                        DEBUG         5
+  --log-file=FILE       Location of the used log file. Default is 'cone.log'
+  --log-config=FILE     Location of the used logging configuration file.
+                        Default is 'logging.ini'
+  --username=USERNAME   Username for webstorage operations. Not needed for
+                        filestorage or cpf storage. If the username
+                        is not given, the tool will use the logged in
+                        username. Example: cone export -p webstorage_url -r .
+                        -c sample.confml --username=admin --password=abc123.
+  --password=PASSWORD   Password for webstorage operations. Not needed for
+                        filestorage or cpf storage. If the password
+                        is not given, the tool will prompt for password if
+                        needed.
+  -p STORAGE, --project=STORAGE
+                        Defines the location of current project. Default is
+                        the current working directory.
+
+  Initvariant options:
+    The initvariant action is intended for merging a variant CPF back into
+    the configuration project. It merges all customer variant layers
+    (layers with custvariant* in their path name) and renames them based
+    on the variant ID and variant name ("custvariant_<id>_<name>").
+
+    -c CONFIG, --configuration=CONFIG
+                        Defines the name of the target configuration. By
+                        default the configuration file name is composed of
+                        product name, variant ID and variant name like this:
+                        <product>_custvariant_<id>_<name>_root.confml
+    -r STORAGE, --remote=STORAGE
+                        Defines the location of remote storage (CPF)
+    -s CONFIG, --sourceconfiguration=CONFIG
+                        Defines the name of the remote configuration inside
+                        the remote storage. Default is the active root of the
+                        remote project.
+    --variant-id=VARIANT_ID
+                        Variant ID, mandatory.
+    --variant-name=VARIANT_NAME
+                        Variant name, optional.
+    --product-name=PRODUCT_NAME
+                        Product name, taken from the configuration data by
+                        default (i.e. defaults to '${imakerapi.productname}')
+    --set-active-root   Set the newly created (or merged) configuration root
+                        as the project's active root after the merge is done.
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/cli/rootflatten.rst	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,52 @@
+ConE rootflatten action
+=======================
+
+The *rootflatten* action is intended to be a temporary solution for enabling 
+Configuration roots anywhere inside the project structure. The current 
+Configuration project specification (0.4) is defined to allow configuration roots
+only in the project root folder, so the root flatten will convert a file located
+in any subfolder of the project to root file under the project folder that follows 
+the Configuration project specification. 
+
+The configuration roots in the subfolders can use absolute includes to include other 
+configuration roots and / or layers.
+
+
+Examples
+--------
+
+**Create a flat configuration from a Country configuration**
+
+The configuration root could for example exist in family/product/country/`product_Euro2_ALPS_02_customisation_root.confml <../_static/country/product_Euro1_ALPS_01_customisation_root.confml>`_.
+So this configuration root includes another configuration and two extra layers. The script trusts that the normal SD naming convention is in use, where all layer root confml files 
+are just name root.confml (to know what is a configuration root and what is a layer). 
+
+Commands::
+
+    > cd configproject_root
+    > cone rootflatten -c family\product\country\product_Euro2_ALPS_02_customisation_root.confml
+    Running action rootflatten
+    Processing configurations ['family\\product\\country\\product_Euro1_ALPS_01_customisation_root.confml']
+    opened family\product\country\product_Euro1_ALPS_01_customisation_root.confml for flattening
+    Creating a new configuration root 'product_Euro1_ALPS_01_customisation_root.confml' for flattening
+
+After the conversion there will be a file with the same name in root where includes are flattened and meta data is merged. 
+ * See `product_Euro2_ALPS_02_customisation_root.confml <../_static/product_Euro1_ALPS_01_customisation_root.confml>`_
+
+
+Options list
+------------
+Options:
+  -h, --help            show this help message and exit
+  -c CONFIG, --configuration=CONFIG
+                        Defines the name of the configuration for the action,
+                        can be specified multiple times to include multiple
+                        configurations.
+  --config-wildcard=WILDCARD
+                        Wildcard pattern for including configurations, e.g.
+                        product_langpack_*_root.confml
+  --config-regex=REGEX  Regular expression for including configurations, e.g.
+                        product_langpack_\d{2}_root.confml
+  -p STORAGE, --project=STORAGE
+                        defines the location of current project. Default is
+                        the current working directory.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/cli/validate.rst	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,103 @@
+.. _cli-action-validate:
+
+ConE validate action
+====================
+
+The validate action can be used to validate individual ConfML and ImplML files,
+or an entire configuration. See also :ref:`validation-overview`.
+
+Examples
+--------
+
+**Validating a single ConfML file**::
+
+    cone validate --confml-file something.confml
+
+This will validate the specified ConfML file and generate a report in
+``validation_report.html`` using the default html report template. If you would like to 
+produce an xml report ``validation_report.xml`` (which is based on Diamonds format) use the following command instead::
+
+    cone validate --confml-file something.confml --report-type xml
+
+* Example output `Validation report for Diamonds <../_static/report.xml>`_
+
+**Validating multiple ConfML files**::
+
+    cone validate --confml-file file1.confml --confml-file file2.confml
+
+This will validate the list of specified ConfML files with --confml-file option. Several Implml files can be validated correspondingly with 
+--implml-file option.
+
+**Validating an entire configuration**::
+
+    cone validate --project myproject --configuration myconfig.confml
+
+This will find all ConfML and ImplML files in the configuration and validate
+them, generating a report into ``validation_report.html``. The command output
+might look something like this::
+    
+    C:\>cone validate --project myproject --configuration myconfig.confml
+    Running action validate
+    Project:       myproject
+    Configuration: myconfig.confml
+    Finding ConfML files in configuration...
+    282 ConfML file(s)
+    2 problem(s) while parsing
+    Performing XML schema validation on ConfML files...
+    40 problem(s)
+    Validating ConfML model...
+    34 problem(s)
+    Finding ImplML files in configuration...
+    Found 393 supported files
+    Performing XML schema validation on ImplML files...
+    7 problem(s)
+    Parsing implementations...
+    Validating implementations...
+    1 problem(s)
+    Total 84 problem(s) after filtering
+    Generating report...
+    Generated report to 'validation_report.html'
+
+
+**Validating only ConfML files in a configuration**::
+    
+    cone validate --project myproject --configuration myconfig.confml --include-filter *.confml
+
+This will run the same validation as in the previous example, except that
+ImplML files are not validated.
+
+**Validating only ImplML files in a configuration**::
+
+    cone validate --project myproject --configuration myconfig.confml --include-filter *.implml
+
+**Performing only schema validation**::
+
+    cone validate --project myproject --configuration myconfig.confml --include-filter schema
+
+Options list
+------------
+
+    --confml-file=FILE  Validate only the given single ConfML file.
+    --implml-file=FILE  Validate only the given single ImplML file.
+    --template=FILE     Template used in report generation. Example:
+                        --template report_template.html.
+    --report=FILE       Specifies the location of the validation report.
+                        Example --report report.html.
+    --report-type=TYPE  The type of the report to generate. This is a
+                        convenience switch for setting the used template. If 
+                        --template is given, this option has no effect.
+                        Possible values:
+                        xml - Generate an xml report
+                        html - Generate html report
+    --dump-schema-files=DIR
+                        Dump the XML schema files used for validation into the
+                        specified directory.
+    --exclude-filter=EXCLUDE_FILTER
+                        Exclude validation problems by given filter. Examples:
+                        --exclude-filter=schema, --exclude-
+                        filter=schema.implml, --exclude-filter=schema.confml,
+                        --exclude-filter=schema.implml.ruleml
+    --include-filter=INCLUDE_FILTER
+                        Include validation problems by given filter.Examples:
+                        --include-filter=schema.implml, --include-
+                        filter=schema.implml.ruleml
--- a/configurationengine/doc/conf.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/doc/conf.py	Tue Aug 10 14:29:28 2010 +0300
@@ -51,15 +51,15 @@
 
 # General substitutions.
 project = u'ConE'
-copyright = u'2008, Nokia Corporation and/or its subsidiary(-ies)'
+copyright = u'2008, Teemu Rytkönen'
 
 # The default replacements for |version| and |release|, also used in various
 # other places throughout the built documents.
 #
 # The short X.Y version.
-version = '1.1'
+version = '1.2'
 # The full version, including alpha/beta/rc tags.
-release = '1.1.5'
+release = '1.2.11DEV'
 
 # There are two options for replacing |today|: either, you set today to some
 # non-false value, then it is used:
--- a/configurationengine/doc/development.rst	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/doc/development.rst	Tue Aug 10 14:29:28 2010 +0300
@@ -1,32 +1,99 @@
-Cone development
-================
+.. _cone-development:
+
+Development with ConE
+=====================
 This page should describe all relevant information on any developer who has or will create any functionality on
 top of the ConE functionality.
 
-
-ConE is open source
--------------------
+ConE in SF
+----------
 
 ConE is a open source project (Currently under Eclipse Public License v1.0), which can take contributions from anyone interested in ConE. In future the ConE 
-will propably be split to two separate parts; core and plugins. The core of ConE is mainly the public interface
-and the storage agnostic functionality of ConE. This core part is intended to be more generic and functional on 
-any platform. The plugin part is meant for extensions of ConE that could be for example platform specific 
-implementation plugins that generate output files based on the configurations.
+will propably be split to two separate parts; ConE *core* and ConE *plugins*. 
+
+The core of ConE is mainly the public interface and the storage agnostic functionality of ConE. 
+This core part is intended to be more generic and functional on any platform. 
+
+The plugin part is meant for extensions of ConE that could be for example platform specific implementation plugins 
+that generate output files based on the configurations.
+
+
+Development environment
+-----------------------
+The development environment requires a set of python packages, which you mostly install with easy_install after 
+installation of setuptools. So you must install the necessary libraries in order to be able to do cone development. 
+The best way to test whether your development environment has everything that is required is to run all the unittest
+of cone (See :ref:`cone-development-test-running`). When everything works, your environment is properly 
+setup :)
+
+**Required Python packages**
+  - jinja2
+  - simplejson 
+  - lxml (at least version 2.2.2) run easy_install lxml==2.2.2
+  - nose (for running testing)
+  - epydoc (for documentation generation)
+  - sphinx (for documentation generation) 
+ 
+ 
+To install the above packages, run easy_install
 
 
-Developing ConE plugin
-----------------------
+easy_install call::
+
+    easy_install <package-name>
+    
+easy_install jinja2 package::
+    
+    easy_install jinja2
+  
+
+.. _cone-development-test-running:
+
+Running tests
+-------------
+The different packages inside cone have a tests subpackage which contains all the tests for that particular package. 
+Each package also contains a runtests.py file that runs all tests inside that package with `nose <http://somethingaboutorange.com/mrl/projects/nose/0.11.3/>`_. 
+
+The higher levels packages also contain a runtests.py which also collect all subpackage tests, so you can basically 
+run every test of cone source by running the runtests.py at the root of source directory.
+
+**Setting PYTHONPATH**
 
-See :ref:`plugin-howto`.
+The cone modules need to be set to the PYTHONPATH to enable test running. If you are using eclipse with PyDev as 
+developement environment, the PYTHONPATH should be automatically correct as the eclipse .project file is included 
+in version control.
+
+For command line testing you can run the testing_paths.cmd/testing_paths.sh to set the PYTHONPATH correctly. 
+After that you should be able to run individual test are all test with a normal python call .
+
+running all cone tests::
+    
+    cd source
+    python runtests.py
+    
+    
+running individual unittest example::
+    
+    cd source/cone/public/tests
+    python unittest_configuration.py
+
+running all module tests::
+    
+    cd source/cone/public/tests
+    python runtests.py
 
 
+running tests with nose::
+    
+    Tests can also be run with nose, effectively this is the same as running the runtests.py 
+    
+    cd source/cone/
+    nosetests --include=unittest
+
 Using ConE API
-==============
+--------------
 
 .. toctree::
     :maxdepth: 2
 
     api/api
-    rule
-
-
--- a/configurationengine/doc/extref.rst	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/doc/extref.rst	Tue Aug 10 14:29:28 2010 +0300
@@ -8,8 +8,10 @@
 
     configurationml085
 
-ConE API documentation
-----------------------
+.. _cone-api-epydoc:
+
+ConE API documentation (epydoc)
+-------------------------------
 
 * `Cone API epydoc <./epydoc/index.html>`_
 
--- a/configurationengine/doc/index.rst	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/doc/index.rst	Tue Aug 10 14:29:28 2010 +0300
@@ -8,7 +8,7 @@
 Contents:
 
 .. toctree::
-    :maxdepth: 2
+    :maxdepth: 3
 
     intro
     cli/common
@@ -16,6 +16,7 @@
     plugins/index
     extref
     imakercone
+    validation-overview
     
 Indices and tables
 ==================
--- a/configurationengine/doc/intro.rst	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/doc/intro.rst	Tue Aug 10 14:29:28 2010 +0300
@@ -7,26 +7,31 @@
 #. ConE plugin API (A plugin interface to add functionality to ConE)
 #. ConE command line interface (tools/utilities that use the API)
 
-ConE API
---------
+ConE API introduction
+---------------------
 The ConE API tries to offer a simple way to access the configurations inside the Configuration
 project. The concepts of confml and the Configuration project are quite complicated, but the API
 simplifies the project quite a bit to enable effective programming. Although the API aims for 
 simplicity, everything is made available via the API.
-The API is described in this document with python api documentation tool *epydoc*.  
+
+The API is described in :ref:`cone-api` with a :ref:`cone-api-howto` and with python api documentation tool *epydoc*. 
 
-ConE plugin API
----------------
+ConE plugin (extension) API
+---------------------------
 The purpose of the plugin API is to offer the possibility to expand the functionality of Configuration project. Normal use case
 is an implementation plugin which reads data from the configuration and transforms it into some other form 
-(e.g. centralrepository text file).
+(e.g. centralrepository text file). 
 
-ConE command line interface
----------------------------
+See :ref:`plugin-api`.
+
+ConE command line interface introduction
+----------------------------------------
 The main purpose of ConE is to offer the above APIs, but ConE installation as tool
 offers also set of command line utilities that can used to modify, read and utilize (generate other output files 
 with implementation plugins) from a Configuration project. These utilities lie on the cone-script package and 
-are described in the ConE command line interface section.
+are described in the ConE command line interface section. 
+
+See :ref:`cone-cli`
 
 Installation
 ------------
@@ -100,9 +105,8 @@
 
 Fetch the latest ConE build from our CruiseControl build server (works only in Nokia intranet):
   
-* Goto http://trwec021.nmp.nokia.com:8080/buildresults/cone-build
-* Click on the Build Artifacts to get the latest build. Older builds are also available for some time.
-* Download the zip file
+* Goto https://trace1.isource-nokia.nokia.com/trac/cone/wiki/ConeReleases
+* Download the release zip file from ConE releases.
 
 The ZIP file should contain a pre-built standalone installation described in the previous section.
 Simply unzip it where you please.
--- a/configurationengine/doc/plugins/commandml-plugin/commandml.rst	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/doc/plugins/commandml-plugin/commandml.rst	Tue Aug 10 14:29:28 2010 +0300
@@ -178,6 +178,12 @@
 	<argument value="--add-setting-file=c:\temp.txt" />
 	<argument value="${preinstallmeta.product}"/>
 
+NOTE! In CommandML localPath is handled as any other string, so don't expect the localPaths of file and folder settings
+to work directly. A localPath is just a string that references files and folders under the configuration project content
+(e.g. 'somedir/somefile.txt', which could physically be located under 'somelayer/content/somedir/somefile.txt').
+If you need an absolute path to the actual file, you need to obtain that yourself using the ConE API. You may
+also need to write the file to a temporary folder, since we might be generating from a CPF.
+
 <pipe> Element
 **************************
 
--- a/configurationengine/doc/plugins/convertprojectplugin.rst	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/doc/plugins/convertprojectplugin.rst	Tue Aug 10 14:29:28 2010 +0300
@@ -103,6 +103,119 @@
 Examples
 '''''''''
 
+Defining layer
+'''''''''
+.. code-block:: xml
+
+  <?xml version="1.0" encoding="UTF-8"?>
+  <convertprojectml xmlns="http://www.s60.com/xml/convertprojectml/1">		
+    <targetProject path=""/>
+    <layer path="assets/s60">
+      <folder path="implml">
+        <filter action="add" data="assets/s60/confml/*.crml"/>
+        <filter action="add" data="assets/s60/confml/*.gcfml"/>
+      </folder>
+      <file type="layer_root" path="root.confml">
+        <filter action="include_file" data="confml/*.confml"/>
+      </file>
+      <file type="configuration_root" path="s60_root.confml">
+        <filter action="include_layer" data="assets/s60/root.confml"/>
+      </file>	
+    </layer>
+  </convertprojectml>
+  
+Normally targetProject's **path** attribute is defined as empty. It means that the project is generated to ConE's normal output location which can be given as command line parameter (-o). 
+
+Convert project ML is constructed so that the highest data structure is **layer**. Layer has attribute **path**, which defines relative location to output path. Layer can contain one or more 
+**folders** and/or **files**. 
+
+Folder defines folder entry inside the layer and in file system level is a directory. Folder has **path** attribute which is relative to layer's path. Folder can contain **filters** which define 
+how folder's content is constructed. With action **add** data is copied to the folder from location which is defined in **data** attribute. 
+**Note** that the path in data attribute is relative to configuration project's root (normally \epoc32\rom\config). Example here copies  all crml and gcfml files from confml folder to impml folder.
+
+Layer can also define files. Each file has **type** which can be layer_root or configuration_root. The former one is creating layer root file to the path defined in **path** attribute, location is 
+relative to layers location. Action **include_file** defines a search pattern. In the example all files from layer's confml folder with extension confml are included in the layer's root file. This can
+be used to generate layer root files automatically in the build even when the exact content in filename level is not known. Configuration root files are always generated to the root of the 
+configuration project. Filter action **include_layer** defines configuration layer root files which are included to the configuration root.
+
+
+Defining metadata and configuration name
+'''''''''
+.. code-block:: xml
+
+  <?xml version="1.0" encoding="UTF-8"?>
+  <convertprojectml xmlns="http://www.s60.com/xml/convertprojectml/1">		
+    <targetProject path=""/>
+    <layer path="assets/s60">
+      <file type="configuration_root" path="s60_root.confml" configuration_name="My S60 Config">
+        <meta xmlns:cv="http://www.nokia.com/xml/cpf-id/1">
+          <version>001</version>
+          <cv:configuration-property name="sw_version" value="${convertproject.versioninfo}" />
+        </meta>
+        </file>	
+    </layer>
+  </convertprojectml>
+
+File element's **configuration_name** attribute can be used to override ConE's default configuration name. Value is written to ConfML file's configuration element to name attribute. **Meta** 
+structure defines ConfML metadata which is added to configuration root file. It supports normal ConfML metadata like in this example **version** and cv namespace metadata like **sw_version**. 
+Value of sw_version is fetched from ConfML setting **convertproject.versioninfo** at run time. Configuration_name and metadata are available to both layer and configuration root files.
+
+Creating loops
+'''''''''
+.. code-block:: xml
+
+  <?xml version="1.0" encoding="UTF-8"?>
+  <convertprojectml xmlns="http://www.s60.com/xml/convertprojectml/1">		
+    <targetProject path=""/>
+    <foreach variable="{TEMPLATE}" data="/epoc32/rom/config/language_packs">	
+      <layer path = language_packs/{TEMPLATE}">
+        <file type="layer_root" path="root.confml">
+          <filter action="include_file" data="confml/*.confml" remove_includes="true"/>
+        </file>
+        <file type="configuration_root" path="langpack_{TEMPLATE}_root.confml" configuration_name=" {TEMPLATE}">
+          <filter action="include_layer" data="assets/s60/root.confml"/>
+          <filter action="include_layer" data="assets/symbianos/root.confml"/>
+          <filter action="include_layer" data="language_packs/{TEMPLATE}/root.confml"/>
+        </file>
+	  </layer>
+  </foreach>
+  </convertprojectml>
+
+Loops can be defined in convert project ml using **foreach** structures. Attribute **data** defines path where from all the folder names  are scanned. Value of attribute **variable** is the 
+name of the folder e.g. if /epoc32/rom/config/language_packs contains folders *lp1*,* lp2* and *lp3* then variable has value lp1 in the first round,  lp2 in the second round and lp3 in the third round. 
+Meaning that in the first round layer path will be language_packs/lp1 and configuration root file name is langpack_lp1_root.confml, which includes language_packs/lp1/root.confml as the last layer root. 
+
+Extending configuration root information
+'''''''''
+.. code-block:: xml
+
+  <?xml version="1.0" encoding="UTF-8"?>
+  <convertprojectml xmlns="http://www.s60.com/xml/convertprojectml/1">		
+    <targetProject path=""/>
+    <foreach variable="{TEMPLATE}" data="/epoc32/rom/config/language_packs">	
+      <layer path = language_packs/{TEMPLATE}">
+        <file type="layer_root" path="root.confml">
+          <filter action="include_file" data="confml/*.confml" remove_includes="true"/>
+        </file>
+        <file type="configuration_root" path="langpack_{TEMPLATE}_root.confml" configuration_name=" {TEMPLATE}">
+          <filter action="include_layer" data="assets/s60/root.confml"/>
+          <filter action="include_layer" data="assets/symbianos/root.confml"/>
+          <filter action="include_layer" data="language_packs/{TEMPLATE}/root.confml"/>
+        </file>
+	  </layer>
+    <layer path="">		
+        <file type="configuration_root" path="langpack_lp1_root.confml">
+          <meta xmlns:cv="http://www.nokia.com/xml/cpf-id/1">
+            <cv:configuration-property name="based_on_ctr" value="abc123" />
+          </meta>
+        </file>
+    </layer>
+  </convertprojectml>
+
+The first part is exactly same as above. What has been added is a new layer which includes only one file generated in the example above. Example here adds extra metadata *'based_on_ctr** to
+the configuration root langpack_lp1_root.confml. Note that convert project ml works so that if there is no existing file then that is created in case file exists then it is updated. 
+
+
 XSD
 '''
 
Binary file configurationengine/doc/plugins/dev-plugin/confml-validation-classes.jpg has changed
--- a/configurationengine/doc/plugins/dev-plugin/diagrams.uml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/doc/plugins/dev-plugin/diagrams.uml	Tue Aug 10 14:29:28 2010 +0300
@@ -71,7 +71,7 @@
 <XPD:OBJ name="NameCompartment" type="UMLNameCompartmentView" guid="tdytcNfaxE6dLcteHN1B8AAA">
 <XPD:OBJ name="NameLabel" type="LabelView" guid="5pV++MiEqEOKb94vAbT4XQAA">
 <XPD:ATTR name="FontStyle" type="integer">1</XPD:ATTR>
-<XPD:ATTR name="Text" type="string">ImplContainer</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">ImplSet</XPD:ATTR>
 </XPD:OBJ>
 <XPD:OBJ name="StereotypeLabel" type="LabelView" guid="yaxWkeq5K0CCgd5PiKKC0wAA">
 <XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
@@ -400,7 +400,7 @@
 <XPD:ATTR name="Left" type="integer">264</XPD:ATTR>
 <XPD:ATTR name="Width" type="integer">178</XPD:ATTR>
 <XPD:ATTR name="Height" type="integer">53</XPD:ATTR>
-<XPD:ATTR name="Text" type="string">ImplContainer contains a number
+<XPD:ATTR name="Text" type="string">ImplSet contains a number
 of implementation instances and
 generates output using them.
 </XPD:ATTR>
@@ -510,7 +510,7 @@
 <XPD:ATTR name="Top" type="integer">384</XPD:ATTR>
 <XPD:ATTR name="Width" type="integer">202</XPD:ATTR>
 <XPD:ATTR name="Height" type="integer">83</XPD:ATTR>
-<XPD:ATTR name="Text" type="string">When an ImplContainer is created
+<XPD:ATTR name="Text" type="string">When an ImplSet is created
 on a Configuration,
 ImplFactory.get_impls_from_file()
 is used on all supported files to create
@@ -538,7 +538,7 @@
 <XPD:ATTR name="Top" type="integer">496</XPD:ATTR>
 <XPD:ATTR name="Width" type="integer">192</XPD:ATTR>
 <XPD:ATTR name="Height" type="integer">68</XPD:ATTR>
-<XPD:ATTR name="Text" type="string">ImplContainer.get_impls_from_file()
+<XPD:ATTR name="Text" type="string">ImplFactory.get_impls_from_file()
 in turn uses all registered reader
 classes to create the actual
 implementations.
@@ -571,40 +571,41 @@
 <XPD:ATTR name="Left" type="integer">568</XPD:ATTR>
 <XPD:ATTR name="Top" type="integer">16</XPD:ATTR>
 <XPD:ATTR name="Width" type="integer">190</XPD:ATTR>
-<XPD:ATTR name="Height" type="integer">38</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">53</XPD:ATTR>
 <XPD:ATTR name="Text" type="string">ImplBase and ReaderBase comprise
-the ConE plug-in interface
+the ConE plug-in interface for
+implementations.
 </XPD:ATTR>
 </XPD:OBJ>
 <XPD:OBJ name="OwnedViews[24]" type="UMLNoteLinkView" guid="rLbnX8lUnkuZIFnnqHyCMQAA">
 <XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
 <XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
-<XPD:ATTR name="Points" type="Points">569,139;645,53</XPD:ATTR>
+<XPD:ATTR name="Points" type="Points">569,141;638,68</XPD:ATTR>
 <XPD:REF name="Head">D2lNkx9zqkGIrORCziB2MwAA</XPD:REF>
 <XPD:REF name="Tail">KeRNcoIQK0KSH6AGF9UzjAAA</XPD:REF>
 </XPD:OBJ>
 <XPD:OBJ name="OwnedViews[25]" type="UMLNoteLinkView" guid="Va6jpciK90aWET6pzoYRiAAA">
 <XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
 <XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
-<XPD:ATTR name="Points" type="Points">727,152;672,53</XPD:ATTR>
+<XPD:ATTR name="Points" type="Points">726,152;677,68</XPD:ATTR>
 <XPD:REF name="Head">D2lNkx9zqkGIrORCziB2MwAA</XPD:REF>
 <XPD:REF name="Tail">2t2cUMI4f0SGZ3fMzCfV2QAA</XPD:REF>
 </XPD:OBJ>
 <XPD:OBJ name="OwnedViews[26]" type="UMLNoteView" guid="v84tCD/ORU6aA+sNvC8HbgAA">
 <XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
 <XPD:ATTR name="FillColor" type="string">$00DFFFFF</XPD:ATTR>
-<XPD:ATTR name="Left" type="integer">20</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">24</XPD:ATTR>
 <XPD:ATTR name="Top" type="integer">12</XPD:ATTR>
 <XPD:ATTR name="Width" type="integer">167</XPD:ATTR>
 <XPD:ATTR name="Height" type="integer">38</XPD:ATTR>
-<XPD:ATTR name="Text" type="string">ImplContainer is used when
+<XPD:ATTR name="Text" type="string">ImplSet is used when
 generating output using ConE.
 </XPD:ATTR>
 </XPD:OBJ>
 <XPD:OBJ name="OwnedViews[27]" type="UMLNoteLinkView" guid="luo/E4PDBEWDV/JjLqFzkgAA">
 <XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
 <XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
-<XPD:ATTR name="Points" type="Points">166,148;113,49</XPD:ATTR>
+<XPD:ATTR name="Points" type="Points">167,148;117,49</XPD:ATTR>
 <XPD:REF name="Head">v84tCD/ORU6aA+sNvC8HbgAA</XPD:REF>
 <XPD:REF name="Tail">EFzcsknNQ0O+rr8VseO9MAAA</XPD:REF>
 </XPD:OBJ>
@@ -798,9 +799,9 @@
 </XPD:OBJ>
 </XPD:OBJ>
 </XPD:OBJ>
-<XPD:ATTR name="#OwnedElements" type="integer">17</XPD:ATTR>
+<XPD:ATTR name="#OwnedElements" type="integer">16</XPD:ATTR>
 <XPD:OBJ name="OwnedElements[0]" type="UMLClass" guid="q11CD3et4kixnDRLW4nPdgAA">
-<XPD:ATTR name="Name" type="string">ImplContainer</XPD:ATTR>
+<XPD:ATTR name="Name" type="string">ImplSet</XPD:ATTR>
 <XPD:REF name="Namespace">NmvwO09X4Uu7xy6qNwdIDQAA</XPD:REF>
 <XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
 <XPD:REF name="Views[0]">EFzcsknNQ0O+rr8VseO9MAAA</XPD:REF>
@@ -935,11 +936,7 @@
 <XPD:ATTR name="Name" type="string">Configuration</XPD:ATTR>
 <XPD:REF name="Namespace">NmvwO09X4Uu7xy6qNwdIDQAA</XPD:REF>
 </XPD:OBJ>
-<XPD:OBJ name="OwnedElements[7]" type="UMLClass" guid="ZxYE1Q8ZZ0CKtQj/FNOQ7wAA">
-<XPD:ATTR name="Name" type="string">Jung, Yoontae</XPD:ATTR>
-<XPD:REF name="Namespace">NmvwO09X4Uu7xy6qNwdIDQAA</XPD:REF>
-</XPD:OBJ>
-<XPD:OBJ name="OwnedElements[8]" type="UMLClass" guid="rDKOyCdZEkCOx+oFSF1RfgAA">
+<XPD:OBJ name="OwnedElements[7]" type="UMLClass" guid="rDKOyCdZEkCOx+oFSF1RfgAA">
 <XPD:ATTR name="Name" type="string">SomeImplReader</XPD:ATTR>
 <XPD:REF name="Namespace">NmvwO09X4Uu7xy6qNwdIDQAA</XPD:REF>
 <XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
@@ -953,7 +950,7 @@
 <XPD:REF name="Associations[0]">eu5J5ZGSGUmZFfbh0cHFewAA</XPD:REF>
 <XPD:REF name="Associations[1]">AeNNCbWnPEKWIb774GWlfQAA</XPD:REF>
 </XPD:OBJ>
-<XPD:OBJ name="OwnedElements[9]" type="UMLRealization" guid="0MZJX1cCj0mQ/11HQ5cN7AAA">
+<XPD:OBJ name="OwnedElements[8]" type="UMLRealization" guid="0MZJX1cCj0mQ/11HQ5cN7AAA">
 <XPD:REF name="Namespace">NmvwO09X4Uu7xy6qNwdIDQAA</XPD:REF>
 <XPD:REF name="Client">JQvuxGbsdE2jFadShkxqKgAA</XPD:REF>
 <XPD:REF name="Supplier">g0zWWZA9xEWvFh0sRnmMqgAA</XPD:REF>
@@ -963,7 +960,7 @@
 <XPD:REF name="Views[2]">oxtgEPTKIkyuZW+/1ioAPAAA</XPD:REF>
 <XPD:REF name="Views[3]">C3LeagDb40ac4fqEDvNK5AAA</XPD:REF>
 </XPD:OBJ>
-<XPD:OBJ name="OwnedElements[10]" type="UMLRealization" guid="mo5tewceOUm0VDnSWRFvzgAA">
+<XPD:OBJ name="OwnedElements[9]" type="UMLRealization" guid="mo5tewceOUm0VDnSWRFvzgAA">
 <XPD:REF name="Namespace">NmvwO09X4Uu7xy6qNwdIDQAA</XPD:REF>
 <XPD:REF name="Client">rDKOyCdZEkCOx+oFSF1RfgAA</XPD:REF>
 <XPD:REF name="Supplier">lPra4OiszU2H/arMBBwTVgAA</XPD:REF>
@@ -973,7 +970,7 @@
 <XPD:REF name="Views[2]">cxdf5fynWEG7/Wzlz9wAZgAA</XPD:REF>
 <XPD:REF name="Views[3]">COnrVcktJUCdGcPafp3OSAAA</XPD:REF>
 </XPD:OBJ>
-<XPD:OBJ name="OwnedElements[11]" type="UMLAssociation" guid="zHN3b0KW5kCvSqS/RtHanwAA">
+<XPD:OBJ name="OwnedElements[10]" type="UMLAssociation" guid="zHN3b0KW5kCvSqS/RtHanwAA">
 <XPD:REF name="Namespace">NmvwO09X4Uu7xy6qNwdIDQAA</XPD:REF>
 <XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
 <XPD:REF name="Views[0]">qO84lDa9Q0qJdFLxAzRcQQAA</XPD:REF>
@@ -986,8 +983,8 @@
 <XPD:REF name="Participant">g0zWWZA9xEWvFh0sRnmMqgAA</XPD:REF>
 <XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
 <XPD:REF name="Views[0]">6HcxdQob+UOT1wCYJ4QeHgAA</XPD:REF>
-<XPD:REF name="Views[1]">MfI12JH1kkSbXGyVvMqqXQAA</XPD:REF>
-<XPD:REF name="Views[2]">tMamOzqFxk6hZeNgqluobwAA</XPD:REF>
+<XPD:REF name="Views[1]">tMamOzqFxk6hZeNgqluobwAA</XPD:REF>
+<XPD:REF name="Views[2]">MfI12JH1kkSbXGyVvMqqXQAA</XPD:REF>
 <XPD:REF name="Views[3]">/ARNc/hPvUmBl4qb/XiPqQAA</XPD:REF>
 </XPD:OBJ>
 <XPD:OBJ name="Connections[1]" type="UMLAssociationEnd" guid="YdiI7jGOKUSsfpXfOQgATwAA">
@@ -996,12 +993,12 @@
 <XPD:REF name="Participant">q11CD3et4kixnDRLW4nPdgAA</XPD:REF>
 <XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
 <XPD:REF name="Views[0]">ymxDIXyVUESDyLIcICrGWQAA</XPD:REF>
-<XPD:REF name="Views[1]">9JS131H/4US3bVVB0X+RIAAA</XPD:REF>
-<XPD:REF name="Views[2]">I8zAzIUs30G8GAyGAkzPOAAA</XPD:REF>
+<XPD:REF name="Views[1]">I8zAzIUs30G8GAyGAkzPOAAA</XPD:REF>
+<XPD:REF name="Views[2]">9JS131H/4US3bVVB0X+RIAAA</XPD:REF>
 <XPD:REF name="Views[3]">itBAlqtdlUK0IXNYnX3+mQAA</XPD:REF>
 </XPD:OBJ>
 </XPD:OBJ>
-<XPD:OBJ name="OwnedElements[12]" type="UMLAssociation" guid="FJ1X3D9c80uG5EgY7ATqzQAA">
+<XPD:OBJ name="OwnedElements[11]" type="UMLAssociation" guid="FJ1X3D9c80uG5EgY7ATqzQAA">
 <XPD:ATTR name="Name" type="string">creates</XPD:ATTR>
 <XPD:REF name="Namespace">NmvwO09X4Uu7xy6qNwdIDQAA</XPD:REF>
 <XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
@@ -1016,8 +1013,8 @@
 <XPD:REF name="Participant">rDKOyCdZEkCOx+oFSF1RfgAA</XPD:REF>
 <XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
 <XPD:REF name="Views[0]">hIeXX5pEhk+9J80xff/Z2QAA</XPD:REF>
-<XPD:REF name="Views[1]">Jn/ACJad8kOY5lGCpXLetQAA</XPD:REF>
-<XPD:REF name="Views[2]">USMA9tEXpkGY+pAIVRjLHAAA</XPD:REF>
+<XPD:REF name="Views[1]">USMA9tEXpkGY+pAIVRjLHAAA</XPD:REF>
+<XPD:REF name="Views[2]">Jn/ACJad8kOY5lGCpXLetQAA</XPD:REF>
 <XPD:REF name="Views[3]">WNomTSYdhk6j1wGMK0aBMQAA</XPD:REF>
 </XPD:OBJ>
 <XPD:OBJ name="Connections[1]" type="UMLAssociationEnd" guid="XFmHn8b6Sk2ycMUt8wH3vAAA">
@@ -1025,24 +1022,24 @@
 <XPD:REF name="Participant">JQvuxGbsdE2jFadShkxqKgAA</XPD:REF>
 <XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
 <XPD:REF name="Views[0]">vMwGVXrxPkCKOvOAPR6ytQAA</XPD:REF>
-<XPD:REF name="Views[1]">BAaRrPSiRkWfQQrnfeF5BQAA</XPD:REF>
-<XPD:REF name="Views[2]">b6bOArvlz0+mgsrQHIOI8wAA</XPD:REF>
+<XPD:REF name="Views[1]">b6bOArvlz0+mgsrQHIOI8wAA</XPD:REF>
+<XPD:REF name="Views[2]">BAaRrPSiRkWfQQrnfeF5BQAA</XPD:REF>
 <XPD:REF name="Views[3]">rACoLZEoXESlgVdLXl1ocQAA</XPD:REF>
 </XPD:OBJ>
 </XPD:OBJ>
-<XPD:OBJ name="OwnedElements[13]" type="UMLPackage" guid="4cKvVc5Dtk6rtkH3X3B9egAA">
+<XPD:OBJ name="OwnedElements[12]" type="UMLPackage" guid="4cKvVc5Dtk6rtkH3X3B9egAA">
 <XPD:ATTR name="Name" type="string">SomePlugin</XPD:ATTR>
 <XPD:REF name="Namespace">NmvwO09X4Uu7xy6qNwdIDQAA</XPD:REF>
 <XPD:ATTR name="#Views" type="integer">1</XPD:ATTR>
 <XPD:REF name="Views[0]">xW95yby7XEChYzUI8UtliAAA</XPD:REF>
 </XPD:OBJ>
-<XPD:OBJ name="OwnedElements[14]" type="UMLPackage" guid="Hwg8xLPVZkC6P9CDdGGF+AAA">
+<XPD:OBJ name="OwnedElements[13]" type="UMLPackage" guid="Hwg8xLPVZkC6P9CDdGGF+AAA">
 <XPD:ATTR name="Name" type="string">ConE</XPD:ATTR>
 <XPD:REF name="Namespace">NmvwO09X4Uu7xy6qNwdIDQAA</XPD:REF>
 <XPD:ATTR name="#Views" type="integer">1</XPD:ATTR>
 <XPD:REF name="Views[0]">Nppn0CUEP0Stsi3DAR1qEQAA</XPD:REF>
 </XPD:OBJ>
-<XPD:OBJ name="OwnedElements[15]" type="UMLAssociation" guid="C72p+KeoXkaRHqlZwhKDHgAA">
+<XPD:OBJ name="OwnedElements[14]" type="UMLAssociation" guid="C72p+KeoXkaRHqlZwhKDHgAA">
 <XPD:ATTR name="Name" type="string">uses</XPD:ATTR>
 <XPD:REF name="Namespace">NmvwO09X4Uu7xy6qNwdIDQAA</XPD:REF>
 <XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
@@ -1057,8 +1054,8 @@
 <XPD:REF name="Participant">q11CD3et4kixnDRLW4nPdgAA</XPD:REF>
 <XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
 <XPD:REF name="Views[0]">YQ4SH0PbkU6D2Ed6kFWZ3gAA</XPD:REF>
-<XPD:REF name="Views[1]">au7s+O1a6EOhU92BZ9mTfAAA</XPD:REF>
-<XPD:REF name="Views[2]">uC7b5/Ag8E+lVXijU0puEAAA</XPD:REF>
+<XPD:REF name="Views[1]">uC7b5/Ag8E+lVXijU0puEAAA</XPD:REF>
+<XPD:REF name="Views[2]">au7s+O1a6EOhU92BZ9mTfAAA</XPD:REF>
 <XPD:REF name="Views[3]">SutSAX/p70WlhiBCYP5mIQAA</XPD:REF>
 </XPD:OBJ>
 <XPD:OBJ name="Connections[1]" type="UMLAssociationEnd" guid="DDj3t0783k6mjECBMHSRZgAA">
@@ -1066,12 +1063,12 @@
 <XPD:REF name="Participant">3dlH2vm6sEayyvEaXZoCngAA</XPD:REF>
 <XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
 <XPD:REF name="Views[0]">Rn+WUty/KE6o3UWIZm/++wAA</XPD:REF>
-<XPD:REF name="Views[1]">7gOWzEGpb0KSajbXDeX03QAA</XPD:REF>
-<XPD:REF name="Views[2]">e/X32+GrOUiRRJMneGhhrwAA</XPD:REF>
+<XPD:REF name="Views[1]">e/X32+GrOUiRRJMneGhhrwAA</XPD:REF>
+<XPD:REF name="Views[2]">7gOWzEGpb0KSajbXDeX03QAA</XPD:REF>
 <XPD:REF name="Views[3]">1RN9/oe60kCHXG3xE2fYmQAA</XPD:REF>
 </XPD:OBJ>
 </XPD:OBJ>
-<XPD:OBJ name="OwnedElements[16]" type="UMLAssociation" guid="zR4RT17TyUGNWLtHCk4EHQAA">
+<XPD:OBJ name="OwnedElements[15]" type="UMLAssociation" guid="zR4RT17TyUGNWLtHCk4EHQAA">
 <XPD:ATTR name="Name" type="string">uses</XPD:ATTR>
 <XPD:REF name="Namespace">NmvwO09X4Uu7xy6qNwdIDQAA</XPD:REF>
 <XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
@@ -1086,8 +1083,8 @@
 <XPD:REF name="Participant">3dlH2vm6sEayyvEaXZoCngAA</XPD:REF>
 <XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
 <XPD:REF name="Views[0]">Ao1mzGyZkUOXJ7iUZ+CxmQAA</XPD:REF>
-<XPD:REF name="Views[1]">Mlo0JoqcnUWmKG46gdW/pgAA</XPD:REF>
-<XPD:REF name="Views[2]">60bFmV8mJ02N5+zPFmP+cAAA</XPD:REF>
+<XPD:REF name="Views[1]">60bFmV8mJ02N5+zPFmP+cAAA</XPD:REF>
+<XPD:REF name="Views[2]">Mlo0JoqcnUWmKG46gdW/pgAA</XPD:REF>
 <XPD:REF name="Views[3]">hQN6K9SliEunBHaWLwTWywAA</XPD:REF>
 </XPD:OBJ>
 <XPD:OBJ name="Connections[1]" type="UMLAssociationEnd" guid="AeNNCbWnPEKWIb774GWlfQAA">
@@ -1095,8 +1092,8 @@
 <XPD:REF name="Participant">rDKOyCdZEkCOx+oFSF1RfgAA</XPD:REF>
 <XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
 <XPD:REF name="Views[0]">65oSMAg0mkmODMiMbf+UjQAA</XPD:REF>
-<XPD:REF name="Views[1]">6vvMJYaqA0+EsdkZT8o6oAAA</XPD:REF>
-<XPD:REF name="Views[2]">znikN5jxMkWgoTVeUx7U0wAA</XPD:REF>
+<XPD:REF name="Views[1]">znikN5jxMkWgoTVeUx7U0wAA</XPD:REF>
+<XPD:REF name="Views[2]">6vvMJYaqA0+EsdkZT8o6oAAA</XPD:REF>
 <XPD:REF name="Views[3]">AnbfKLYaZ0qC8tWUwfnFkgAA</XPD:REF>
 </XPD:OBJ>
 </XPD:OBJ>
--- a/configurationengine/doc/plugins/dev-plugin/example-plugin.rst	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/doc/plugins/dev-plugin/example-plugin.rst	Tue Aug 10 14:29:28 2010 +0300
@@ -12,9 +12,11 @@
     - Implementation class
     - Implementation model
 - Using ``cone.public.utils`` for ConfML setting reference handling
+- Providing XML schema validation and model-level validation
 - Unit tests:
     - Testing the reader class, the implementation class and the model classes separately
     - Output generation testing (plug-in scope integration test)
+    - Validation testing
 
 The ExampleML language
 ----------------------
@@ -55,16 +57,19 @@
         - ``ConeExamplePlugin/`` - Source for the example plug-in
             - ``examplemlplugin/`` - Module directory containing all plug-in code
                 - ``tests/`` - Unit tests and test data for the plug-in
-                    - ``project/`` - Configuration project used in the tests
-                    - ``gen_expected/`` - Expected output for generation test case
+                    - ``testdata/`` - Directory containing all test data needed by the test cases
                     - ``__init__.py`` - Test module initialization file
                     - ``runtests.py`` - Script for running all test cases
                     - ``unittest_exampleml_impl.py`` - File containing test cases
                     - ``unittest_exampleml_reader.py`` - File containing test cases
                     - ``unittest_exampleml_generation.py`` - File containing test cases
+                    - ``unittest_exampleml_validation.py`` - File containing test cases
+                - ``xsd/`` - XML Schema files for schema validation
+                    - ``exampleml.xsd`` - Schema file for schema validation
                 - ``__init__.py`` - Plug-in module initialization file
                 - ``exampleml_impl.py`` - Plug-in source file
                 - ``exampleml_reader.py`` - Plug-in source file
+                - ``exampleml_validators.py`` - Plug-in source file
             - ``setup.py`` - Setup script for packaging the plug-in into an .egg file
             - ``setup.cfg`` - Configuration file for ``setup.py``
         - ``integration-test/`` - Integration tests for the example plug-in package
@@ -83,7 +88,10 @@
 - *Implementation class*, works as the interface of the plug-in towards ConE and uses the model to do the actual work
 - *Implementation reader*, converts the XML data into the logical model and creates a new implementation class instance
 
-In this case the *model* consists just of the class Output, which corresponds to the ``<output>`` element.
+Here the *model* consists just of the class Output, which corresponds to the ``<output>`` element.
+
+In addition to these, there is a collection of *validator classes* that are
+responsible for handling model-level validation.
 
 Plug-in code
 ------------
@@ -135,6 +143,28 @@
 .. literalinclude:: /../source/plugins/example/ConeExamplePlugin/examplemlplugin/exampleml_reader.py
    :linenos:
 
+Note that the reader class provides the XML schema by overriding
+``get_schema_data()``. If this method was not overridden, a default schema
+that accepts (almost) anything would be used for schema validation.
+
+
+exampleml_validators.py
+...................
+
+This file defines all validator classes. Since ExampleML is so simple, there
+are only two cases that need to be validated on the model level: setting
+references and the encoding. Notice that the setting reference validator
+uses the method ``check_feature_reference()`` inherited from ``ImplValidatorBase``.
+As there are utility functions for handling references in a uniform way, there
+is also a utility function for validating them.
+
+Note also the class list VALIDATOR_CLASSES at the bottom, which contains both
+of the validator classes. The file ``setup.py`` contains an entry point
+definition that points to this list, and the validation framework finds the
+validators via that.
+
+.. literalinclude:: /../source/plugins/example/ConeExamplePlugin/examplemlplugin/exampleml_validators.py
+   :linenos:
 
 Unit tests
 ----------
@@ -204,14 +234,26 @@
 .. literalinclude:: /../source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/unittest_exampleml_generation.py
    :linenos:
 
+unittest_exampleml_validation.py
+................................
+
+Like ``unittest_exampleml_generation.py`` test output generation, this file
+tests validation. The test cases themselves are pretty simple, since there are
+pre-existing helper methods for running the tests, and the tests mainly consist
+of test data and expected.
+
+.. literalinclude:: /../source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/unittest_exampleml_validation.py
+   :linenos:
+
+   
 Plug-in packaging
 -----------------
 
 The file ``setup.py`` handles the packaging of the plug-in into an egg file.
 
 The most important thing here is the plug-in's entry point info. The
-plug-in's reader classes must be specified as entry points, or they won't be
-loaded.
+plug-in's reader and validator classes must be specified as entry points,
+or they won't be loaded.
 
 .. literalinclude:: /../source/plugins/example/ConeExamplePlugin/setup.py
    :linenos:
@@ -268,11 +310,11 @@
 This file contains tests for generating output using the example plug-in.
 Note the following things:
 
-- The use of the variable ``CONE_CMD`` in ``get_cmd()``. This variable is set to
-  contain the actual ConE command to run if the tests are being run from the
-  exported standalone test set. In practice this will be something like
-  ``C:/cone_test/cone/cone.cmd``.
-- The actual generation and testing is done in a separate function, ``run_test_generate()``,
+- The check if ``CONE_CMD`` is in the environment variables in ``get_cmd()``.
+  This variable is set to contain the actual ConE command to run if the tests
+  are being run from the exported standalone test set. In practice this will be
+  something like  ``C:/cone_test/cone/cone.cmd``.
+- The actual generation and testing is done in a separate function, ``_run_test_generate()``,
   and there are two actual test functions that call it. One runs the test directly on the
   test project on the file system, and another first zips the test project and then runs
   the test on that. It is a good idea to test that generation works the same in both cases,
Binary file configurationengine/doc/plugins/dev-plugin/impl-validation-classes.jpg has changed
--- a/configurationengine/doc/plugins/dev-plugin/index.rst	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/doc/plugins/dev-plugin/index.rst	Tue Aug 10 14:29:28 2010 +0300
@@ -1,19 +1,18 @@
 .. _plugin-howto:
 
-How to create a ConE plug-in
-============================
+How to create an implementation plug-in for ConE
+================================================
 
-This page contains a description of ConE's plug-in interface, a description of
+This page contains a description of 
 an example plug-in intended to be used as a template for creating new plug-ins,
-and step-by-step instructions for creating a new ConE plug-in based on the template.
+and step-by-step instructions for creating a new ConE implementation plug-in based on the template.
 The impatient can simply skip to the step-by-step instructions, by it is recommended
-to read the also the plug-in interface and example plug-in descriptions.
+to read the also the :ref:`plug-in interface <plugin-howto-plugin-interface>` and example plug-in descriptions.
 
 The instructions assume that the used development environment is Eclipse/PyDev.
 
 .. toctree::
     :maxdepth: 3
     
-    plugin-interface
     example-plugin
     steps
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/plugins/dev-plugin/model-validation.uml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,2760 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<XPD:PROJECT xmlns:XPD="http://www.staruml.com" version="1">
+<XPD:HEADER>
+<XPD:SUBUNITS>
+</XPD:SUBUNITS>
+<XPD:PROFILES>
+</XPD:PROFILES>
+</XPD:HEADER>
+<XPD:BODY>
+<XPD:OBJ name="DocumentElement" type="UMLProject" guid="UgzTZtXBekmk2L7FzuhqeQAA">
+<XPD:ATTR name="Title" type="string">Untitled</XPD:ATTR>
+<XPD:ATTR name="#OwnedElements" type="integer">3</XPD:ATTR>
+<XPD:OBJ name="OwnedElements[0]" type="UMLModel" guid="J0JbQTHSq0yi13n61FmjzgAA">
+<XPD:ATTR name="Name" type="string">Model1</XPD:ATTR>
+<XPD:REF name="Namespace">UgzTZtXBekmk2L7FzuhqeQAA</XPD:REF>
+<XPD:ATTR name="#OwnedDiagrams" type="integer">2</XPD:ATTR>
+<XPD:OBJ name="OwnedDiagrams[0]" type="UMLClassDiagram" guid="BizY3ycO40CY71lR17niowAA">
+<XPD:ATTR name="Name" type="string">ImplmlValidation</XPD:ATTR>
+<XPD:REF name="DiagramOwner">J0JbQTHSq0yi13n61FmjzgAA</XPD:REF>
+<XPD:OBJ name="DiagramView" type="UMLClassDiagramView" guid="NysvcvEtxE67+tRerDEZ5gAA">
+<XPD:REF name="Diagram">BizY3ycO40CY71lR17niowAA</XPD:REF>
+<XPD:ATTR name="#OwnedViews" type="integer">30</XPD:ATTR>
+<XPD:OBJ name="OwnedViews[0]" type="UMLPackageView" guid="EJCUtlLZ2EmiEUOBxXASmAAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">432</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">508</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">153</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">125</XPD:ATTR>
+<XPD:REF name="Model">omsxqqbK/UWCHBKe5JrDagAA</XPD:REF>
+<XPD:OBJ name="NameCompartment" type="UMLNameCompartmentView" guid="WlGG/dPVBkKtfY3s4BdWjAAA">
+<XPD:OBJ name="NameLabel" type="LabelView" guid="DF6FiPtQhkqrGmR592DZ3wAA">
+<XPD:ATTR name="Text" type="string">cone.public.plugin</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="LabelView" guid="Kz4usPphP0a9jlMfTKp79AAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="LabelView" guid="92dtfrMU7E2/HUbix3GY8AAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[1]" type="UMLPackageView" guid="cBNU63cyHkyOttvWiFCzXAAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">208</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">104</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">397</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">301</XPD:ATTR>
+<XPD:REF name="Model">2qWKZicOf06yzOTeZuyqCAAA</XPD:REF>
+<XPD:OBJ name="NameCompartment" type="UMLNameCompartmentView" guid="14aCKnaYtk2dciMb+liBbAAA">
+<XPD:OBJ name="NameLabel" type="LabelView" guid="b2AffH0Z+kirJtgaBHcjXwAA">
+<XPD:ATTR name="Text" type="string">cone.validation.implmlvalidation</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="LabelView" guid="mSsJ6vFYkUKV94IW2s6ahgAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="LabelView" guid="LC0hzsE0y0KTgfnQf0X08AAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[2]" type="UMLClassView" guid="3goKGKxfG0uL8r408fsXYQAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">424</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">297</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">155</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">69</XPD:ATTR>
+<XPD:REF name="Model">XjBwLw9OjEmKJ4KD8B58wgAA</XPD:REF>
+<XPD:OBJ name="NameCompartment" type="UMLNameCompartmentView" guid="piP59V++SEyWQ1KbrytWsgAA">
+<XPD:OBJ name="NameLabel" type="LabelView" guid="ZMqoShwjO029N81TBrehSQAA">
+<XPD:ATTR name="FontStyle" type="integer">3</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">ImplValidatorBase</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="LabelView" guid="wSF8Jbj7SEu5DfAHh5nccgAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="LabelView" guid="cpZnC1Vn+EG8OCH6AqWXTgAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="AttributeCompartment" type="UMLAttributeCompartmentView" guid="1QldCtJUsECyFTsbu3s9XgAA">
+<XPD:REF name="Model">XjBwLw9OjEmKJ4KD8B58wgAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OperationCompartment" type="UMLOperationCompartmentView" guid="GwJF7Uc2qkucIa/W7XCSFwAA">
+<XPD:REF name="Model">XjBwLw9OjEmKJ4KD8B58wgAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TemplateParameterCompartment" type="UMLTemplateParameterCompartmentView" guid="Vg23dTmL40WKOmiqnNYWwQAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:REF name="Model">XjBwLw9OjEmKJ4KD8B58wgAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[3]" type="UMLPackageView" guid="9RQji6pg1U2ipqsxknfe8gAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">664</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">288</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">221</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">157</XPD:ATTR>
+<XPD:REF name="Model">SI/VACVeYUOmYmmg2TSKaQAA</XPD:REF>
+<XPD:OBJ name="NameCompartment" type="UMLNameCompartmentView" guid="1YzvB5zs6UuHM/fzMe/LwwAA">
+<XPD:OBJ name="NameLabel" type="LabelView" guid="A1V9RzoApUa2JDGeA3r+iwAA">
+<XPD:ATTR name="Text" type="string">crmlplugin.crml_validators</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="LabelView" guid="ZgZtWbLwNkiNhHNsH09xEgAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="LabelView" guid="9qCGptSfeEGKobG7ZyVsKAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[4]" type="UMLClassView" guid="UjOB3AO2S0SO11NmkC+uFwAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">676</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">332</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">145</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">43</XPD:ATTR>
+<XPD:REF name="Model">wbvMqm+/yE2hNe1Utj7f9AAA</XPD:REF>
+<XPD:OBJ name="NameCompartment" type="UMLNameCompartmentView" guid="6I97FYs3nk2DJoY8EcXEJgAA">
+<XPD:OBJ name="NameLabel" type="LabelView" guid="jykgpUGPOE6pQe2csqHWrwAA">
+<XPD:ATTR name="FontStyle" type="integer">1</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">CrmlReferenceValidator</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="LabelView" guid="Vn0FiXHWFUqJQ26YKzfl4AAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="LabelView" guid="p99es+YSZE+HVm0Q+3UeQAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="AttributeCompartment" type="UMLAttributeCompartmentView" guid="VsZ1ugd2fUCdG5xIOrwxdwAA">
+<XPD:REF name="Model">wbvMqm+/yE2hNe1Utj7f9AAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OperationCompartment" type="UMLOperationCompartmentView" guid="j2iWaOgMlEKIj8vhMaHFfQAA">
+<XPD:REF name="Model">wbvMqm+/yE2hNe1Utj7f9AAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TemplateParameterCompartment" type="UMLTemplateParameterCompartmentView" guid="wtdyekaYd0KBv6UhMLDnewAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:REF name="Model">wbvMqm+/yE2hNe1Utj7f9AAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[5]" type="UMLClassView" guid="POGF8jlAQ0WHmmVN5I344AAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">676</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">384</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">158</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">43</XPD:ATTR>
+<XPD:REF name="Model">Cy+SmuqmpkSX9nQNWXF+MgAA</XPD:REF>
+<XPD:OBJ name="NameCompartment" type="UMLNameCompartmentView" guid="Cmzdd2JFHUCfh6KGL8tGoAAA">
+<XPD:OBJ name="NameLabel" type="LabelView" guid="Er6Zi1HOR0SymttW0YGfZgAA">
+<XPD:ATTR name="FontStyle" type="integer">1</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">CrmlDuplicateUidValidator</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="LabelView" guid="5lTrDBydPEOu6B42n2LA2wAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="LabelView" guid="Hv2BAqt8cE2iWC9HGZ2dlAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="AttributeCompartment" type="UMLAttributeCompartmentView" guid="WCx5ai4Z1kijSbAQp7n+6AAA">
+<XPD:REF name="Model">Cy+SmuqmpkSX9nQNWXF+MgAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OperationCompartment" type="UMLOperationCompartmentView" guid="VtgEwJKxc0aWpNn81zMWxgAA">
+<XPD:REF name="Model">Cy+SmuqmpkSX9nQNWXF+MgAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TemplateParameterCompartment" type="UMLTemplateParameterCompartmentView" guid="HM/6PUALRU+eMxw64yLK/QAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:REF name="Model">Cy+SmuqmpkSX9nQNWXF+MgAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[6]" type="UMLRealizationView" guid="oqIw0IFa9kWea9XTuFMZ1AAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Points" type="Points">682,384;578,354</XPD:ATTR>
+<XPD:REF name="Model">Kc/JhhXZ9kaQvIqg52hkzQAA</XPD:REF>
+<XPD:REF name="Head">3goKGKxfG0uL8r408fsXYQAA</XPD:REF>
+<XPD:REF name="Tail">POGF8jlAQ0WHmmVN5I344AAA</XPD:REF>
+<XPD:OBJ name="NameLabel" type="EdgeLabelView" guid="4Ju7YjWI0kS3NUyxQah2ZQAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">15</XPD:ATTR>
+<XPD:REF name="Model">Kc/JhhXZ9kaQvIqg52hkzQAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="EdgeLabelView" guid="NHJXrkZ9iUao9zyQg2EKugAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">30</XPD:ATTR>
+<XPD:REF name="Model">Kc/JhhXZ9kaQvIqg52hkzQAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="EdgeLabelView" guid="mIgLnOfmNkCkHAhbqSNpDgAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">-1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">15</XPD:ATTR>
+<XPD:REF name="Model">Kc/JhhXZ9kaQvIqg52hkzQAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[7]" type="UMLRealizationView" guid="ysaiWR11jkCPXTaPKqvETAAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Points" type="Points">676,347;578,338</XPD:ATTR>
+<XPD:REF name="Model">6sSq0GCuIUuD+jUJQcViugAA</XPD:REF>
+<XPD:REF name="Head">3goKGKxfG0uL8r408fsXYQAA</XPD:REF>
+<XPD:REF name="Tail">UjOB3AO2S0SO11NmkC+uFwAA</XPD:REF>
+<XPD:OBJ name="NameLabel" type="EdgeLabelView" guid="15dM8+2xdUqVA0PEz4Z+lAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">15</XPD:ATTR>
+<XPD:REF name="Model">6sSq0GCuIUuD+jUJQcViugAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="EdgeLabelView" guid="Yy5JZoVrZk6fO/HBzcXbLQAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">30</XPD:ATTR>
+<XPD:REF name="Model">6sSq0GCuIUuD+jUJQcViugAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="EdgeLabelView" guid="rdBsD6yDGUCxMqzu4s/5jgAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">-1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">15</XPD:ATTR>
+<XPD:REF name="Model">6sSq0GCuIUuD+jUJQcViugAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[8]" type="UMLClassView" guid="g14za6T92EGNk4PWs/vUjQAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">228</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">296</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">111</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">73</XPD:ATTR>
+<XPD:REF name="Model">nx3Lx4aZoUSFCSv3hH2xRgAA</XPD:REF>
+<XPD:OBJ name="NameCompartment" type="UMLNameCompartmentView" guid="+JhoB4Vqk0iivwdSqTFWiQAA">
+<XPD:OBJ name="NameLabel" type="LabelView" guid="0w/OZI5olEunJNmEWiF/IwAA">
+<XPD:ATTR name="FontStyle" type="integer">1</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">ValidationContext</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="LabelView" guid="vipkq9wCm0WbCc3Ul6B3rAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="LabelView" guid="OOp2tO6bnUed6Qzh4n+N8QAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="AttributeCompartment" type="UMLAttributeCompartmentView" guid="yEtGoC/OVU+MtM58Kcp8eQAA">
+<XPD:REF name="Model">nx3Lx4aZoUSFCSv3hH2xRgAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OperationCompartment" type="UMLOperationCompartmentView" guid="sl4ETPFlpUmkpdJ3lTHfCAAA">
+<XPD:REF name="Model">nx3Lx4aZoUSFCSv3hH2xRgAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TemplateParameterCompartment" type="UMLTemplateParameterCompartmentView" guid="aSfLN5cFNkW4AgKNImQMDAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:REF name="Model">nx3Lx4aZoUSFCSv3hH2xRgAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[9]" type="UMLAssociationView" guid="G4BGfDCjwkO+jlXwGuVFJwAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="LineStyle" type="LineStyleKind">lsRectilinear</XPD:ATTR>
+<XPD:ATTR name="Points" type="Points">338,332;424,332</XPD:ATTR>
+<XPD:REF name="Model">9tUo6t0cgkqrFSmHsMYuAAAA</XPD:REF>
+<XPD:REF name="Head">3goKGKxfG0uL8r408fsXYQAA</XPD:REF>
+<XPD:REF name="Tail">g14za6T92EGNk4PWs/vUjQAA</XPD:REF>
+<XPD:OBJ name="NameLabel" type="EdgeLabelView" guid="4KvH0CBxeE6GrVd/KPRCVAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">15</XPD:ATTR>
+<XPD:REF name="Model">9tUo6t0cgkqrFSmHsMYuAAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="EdgeLabelView" guid="Q/jeLaNxY0mQNbmb5EjLqwAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">30</XPD:ATTR>
+<XPD:REF name="Model">9tUo6t0cgkqrFSmHsMYuAAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="EdgeLabelView" guid="2wPc15TFakOVGaYagKeKWQAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">-1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">15</XPD:ATTR>
+<XPD:REF name="Model">9tUo6t0cgkqrFSmHsMYuAAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="HeadRoleNameLabel" type="EdgeLabelView" guid="VheCL5brfEmRNkId9sisYAAA">
+<XPD:ATTR name="Alpha" type="real">-0.523598775598299</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">30</XPD:ATTR>
+<XPD:ATTR name="EdgePosition" type="EdgePositionKind">epHead</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">+context</XPD:ATTR>
+<XPD:REF name="Model">to4Ge8pEOk6oiY69/D4VDgAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TailRoleNameLabel" type="EdgeLabelView" guid="MetUdT1H9UuvGWMD17NpFQAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">0.523598775598299</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">30</XPD:ATTR>
+<XPD:ATTR name="EdgePosition" type="EdgePositionKind">epTail</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">+FD</XPD:ATTR>
+<XPD:REF name="Model">q6CV7L6RD0ipPZFD0c2e1wAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="HeadMultiplicityLabel" type="EdgeLabelView" guid="9iTNYzJ5TUuDLk/vA1PFmwAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">0.523598775598299</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">25</XPD:ATTR>
+<XPD:ATTR name="EdgePosition" type="EdgePositionKind">epHead</XPD:ATTR>
+<XPD:REF name="Model">to4Ge8pEOk6oiY69/D4VDgAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TailMultiplicityLabel" type="EdgeLabelView" guid="slOChvPyFUqAdCyKfHjcvAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">-0.523598775598299</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">25</XPD:ATTR>
+<XPD:ATTR name="EdgePosition" type="EdgePositionKind">epTail</XPD:ATTR>
+<XPD:REF name="Model">q6CV7L6RD0ipPZFD0c2e1wAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="HeadPropertyLabel" type="EdgeLabelView" guid="QuuWBk9xWkmhDNnTN1VaFgAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">-0.785398163397448</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">40</XPD:ATTR>
+<XPD:ATTR name="EdgePosition" type="EdgePositionKind">epHead</XPD:ATTR>
+<XPD:REF name="Model">to4Ge8pEOk6oiY69/D4VDgAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TailPropertyLabel" type="EdgeLabelView" guid="yPzKg0VG3kSo7bwqixJw5wAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">0.785398163397448</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">40</XPD:ATTR>
+<XPD:ATTR name="EdgePosition" type="EdgePositionKind">epTail</XPD:ATTR>
+<XPD:REF name="Model">q6CV7L6RD0ipPZFD0c2e1wAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="HeadQualifierCompartment" type="UMLQualifierCompartmentView" guid="42cJ86Z/+0K6N/F17BRRBQAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">-888</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">-828</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">50</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">8</XPD:ATTR>
+<XPD:REF name="Model">to4Ge8pEOk6oiY69/D4VDgAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TailQualifierCompartment" type="UMLQualifierCompartmentView" guid="yIiEf+5aYkWbTpXOnT53ggAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">-888</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">-828</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">50</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">8</XPD:ATTR>
+<XPD:REF name="Model">q6CV7L6RD0ipPZFD0c2e1wAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[10]" type="UMLClassView" guid="c5pkkfn3Xk2arAYxl83oLgAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">456</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">556</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">91</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">43</XPD:ATTR>
+<XPD:REF name="Model">cQYhYY9L50KRVH8GX320RAAA</XPD:REF>
+<XPD:OBJ name="NameCompartment" type="UMLNameCompartmentView" guid="wzsm6fgG8Eq5xVIh1WUidgAA">
+<XPD:OBJ name="NameLabel" type="LabelView" guid="k3cEUqjWf06gwU8ec6UtFwAA">
+<XPD:ATTR name="FontStyle" type="integer">3</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">ImplBase</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="LabelView" guid="qhntLgiYx0aCH0+2ILT+IAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="LabelView" guid="xo/EJJHR2kGoeDzHBZNEUgAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="AttributeCompartment" type="UMLAttributeCompartmentView" guid="Ylq6cKNmOE+S+jAz03hfeAAA">
+<XPD:REF name="Model">cQYhYY9L50KRVH8GX320RAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OperationCompartment" type="UMLOperationCompartmentView" guid="rOLzdil6uECps+oXj/rh5QAA">
+<XPD:REF name="Model">cQYhYY9L50KRVH8GX320RAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TemplateParameterCompartment" type="UMLTemplateParameterCompartmentView" guid="2bQ9ix8R0kGXUdsUVLOfmwAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:REF name="Model">cQYhYY9L50KRVH8GX320RAAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[11]" type="UMLNoteView" guid="AWb6hJZcbU+VJwaQPrrTdgAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">788</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">456</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">178</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">38</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">Plug-ins provide validator classes
+via an egg entry point.
+</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[12]" type="UMLNoteLinkView" guid="nCEOwcdZhkCY6VCalG5pxAAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Points" type="Points">791,426;844,456</XPD:ATTR>
+<XPD:REF name="Head">AWb6hJZcbU+VJwaQPrrTdgAA</XPD:REF>
+<XPD:REF name="Tail">POGF8jlAQ0WHmmVN5I344AAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[13]" type="UMLAssociationView" guid="chIlFeu+W0CfzByUAT+hMAAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Points" type="Points">501,556;501,365</XPD:ATTR>
+<XPD:REF name="Model">lMyxDaFSF0SCrMvdMMibSwAA</XPD:REF>
+<XPD:REF name="Head">3goKGKxfG0uL8r408fsXYQAA</XPD:REF>
+<XPD:REF name="Tail">c5pkkfn3Xk2arAYxl83oLgAA</XPD:REF>
+<XPD:OBJ name="NameLabel" type="EdgeLabelView" guid="wuLJ37KQ8EuRL4PCZItYNwAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">15</XPD:ATTR>
+<XPD:REF name="Model">lMyxDaFSF0SCrMvdMMibSwAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="EdgeLabelView" guid="D5NQL72A30SlV3uTGM6S/wAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">30</XPD:ATTR>
+<XPD:REF name="Model">lMyxDaFSF0SCrMvdMMibSwAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="EdgeLabelView" guid="rF4ks9l5TkGOHIUJ8vyKmwAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">-1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">15</XPD:ATTR>
+<XPD:REF name="Model">lMyxDaFSF0SCrMvdMMibSwAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="HeadRoleNameLabel" type="EdgeLabelView" guid="gNKP+7f4V02nCGw0oisRogAA">
+<XPD:ATTR name="Alpha" type="real">-0.523598775598299</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">30</XPD:ATTR>
+<XPD:ATTR name="EdgePosition" type="EdgePositionKind">epHead</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">+impl</XPD:ATTR>
+<XPD:REF name="Model">GfSW7NI3NEORsulHu2l+XgAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TailRoleNameLabel" type="EdgeLabelView" guid="xEctc7E62kSVYwICvYhLmwAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">0.523598775598299</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">30</XPD:ATTR>
+<XPD:ATTR name="EdgePosition" type="EdgePositionKind">epTail</XPD:ATTR>
+<XPD:REF name="Model">xO0O32Ik5UKs7FALsy3uPQAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="HeadMultiplicityLabel" type="EdgeLabelView" guid="fvH9lFDYXUOQ4sZb1bq8JwAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">0.523598775598299</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">25</XPD:ATTR>
+<XPD:ATTR name="EdgePosition" type="EdgePositionKind">epHead</XPD:ATTR>
+<XPD:REF name="Model">GfSW7NI3NEORsulHu2l+XgAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TailMultiplicityLabel" type="EdgeLabelView" guid="t5ygmZQvmketK0B1UlCGyAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">-0.523598775598299</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">25</XPD:ATTR>
+<XPD:ATTR name="EdgePosition" type="EdgePositionKind">epTail</XPD:ATTR>
+<XPD:REF name="Model">xO0O32Ik5UKs7FALsy3uPQAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="HeadPropertyLabel" type="EdgeLabelView" guid="n0abP8A4Kky9OwOpQrrd/AAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">-0.785398163397448</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">40</XPD:ATTR>
+<XPD:ATTR name="EdgePosition" type="EdgePositionKind">epHead</XPD:ATTR>
+<XPD:REF name="Model">GfSW7NI3NEORsulHu2l+XgAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TailPropertyLabel" type="EdgeLabelView" guid="usGQ87TWBUu3+WGQUcXqYQAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">0.785398163397448</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">40</XPD:ATTR>
+<XPD:ATTR name="EdgePosition" type="EdgePositionKind">epTail</XPD:ATTR>
+<XPD:REF name="Model">xO0O32Ik5UKs7FALsy3uPQAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="HeadQualifierCompartment" type="UMLQualifierCompartmentView" guid="vxzp55tliEacRjs1Bzk+KQAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">-888</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">-820</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">50</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">8</XPD:ATTR>
+<XPD:REF name="Model">GfSW7NI3NEORsulHu2l+XgAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TailQualifierCompartment" type="UMLQualifierCompartmentView" guid="Xt49OQdNiEOsCMaWsliTKgAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">-888</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">-820</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">50</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">8</XPD:ATTR>
+<XPD:REF name="Model">xO0O32Ik5UKs7FALsy3uPQAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[14]" type="UMLNoteView" guid="oHULdTV6v0uuFqaiVKIWYgAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">604</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">508</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">214</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">143</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">Each validator class lists the
+implementation classes it supports.
+
+When validating an implementation,
+the framework checks for each
+registered validator class if it supports
+the current implementation. If so,
+a validator instance is created and
+it is used to validate the implementation.
+</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[15]" type="UMLNoteLinkView" guid="O/xP50RSyUiL6yxgxSyB7QAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Points" type="Points">530,365;650,508</XPD:ATTR>
+<XPD:REF name="Head">oHULdTV6v0uuFqaiVKIWYgAA</XPD:REF>
+<XPD:REF name="Tail">3goKGKxfG0uL8r408fsXYQAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[16]" type="UMLNoteLinkView" guid="jL+JmWewlE2ESB44/sSDZwAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Points" type="Points">546,577;604,578</XPD:ATTR>
+<XPD:REF name="Head">oHULdTV6v0uuFqaiVKIWYgAA</XPD:REF>
+<XPD:REF name="Tail">c5pkkfn3Xk2arAYxl83oLgAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[17]" type="UMLClassView" guid="TEw9LFZNuE+vJNGP9lmkkQAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">436</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">176</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">123</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">43</XPD:ATTR>
+<XPD:REF name="Model">w1x85nyRiUi3HLBob1jwlQAA</XPD:REF>
+<XPD:OBJ name="NameCompartment" type="UMLNameCompartmentView" guid="1A4iC0D0G0+79eXGRsVTxgAA">
+<XPD:OBJ name="NameLabel" type="LabelView" guid="F0+ah77aHEmff0MV1z9TzwAA">
+<XPD:ATTR name="FontStyle" type="integer">3</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">GlobalValidatorBase</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="LabelView" guid="X8at4ShVmkGzHkAPZO8CwgAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="LabelView" guid="FWJmH0mQx0CWlOXrpKpP7AAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="AttributeCompartment" type="UMLAttributeCompartmentView" guid="CJx7Itfy7Uibwjeyw5yQDQAA">
+<XPD:REF name="Model">w1x85nyRiUi3HLBob1jwlQAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OperationCompartment" type="UMLOperationCompartmentView" guid="jFGd4I3bN0K55FxynMIRQwAA">
+<XPD:REF name="Model">w1x85nyRiUi3HLBob1jwlQAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TemplateParameterCompartment" type="UMLTemplateParameterCompartmentView" guid="z0uyUnKnI0Gaw2xWrA8UsgAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:REF name="Model">w1x85nyRiUi3HLBob1jwlQAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[18]" type="UMLClassView" guid="y/GCWOvnj0elYh+OdbeO9gAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">264</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">168</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">100</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">69</XPD:ATTR>
+<XPD:REF name="Model">WfkxoUbZqUOof1sQP1YufAAA</XPD:REF>
+<XPD:OBJ name="NameCompartment" type="UMLNameCompartmentView" guid="7n3qsi0a50axkkxhE45y+QAA">
+<XPD:OBJ name="NameLabel" type="LabelView" guid="fdhNx6nCX0iafUrR6B16iwAA">
+<XPD:ATTR name="FontStyle" type="integer">3</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">ValidatorBase</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="LabelView" guid="SaGQnUC7B06kIyGffH35eAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="LabelView" guid="4pUoG+BFUE2j60ej8nKOYgAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="AttributeCompartment" type="UMLAttributeCompartmentView" guid="/gHyKKAz8E2mAa0etgNEMQAA">
+<XPD:REF name="Model">WfkxoUbZqUOof1sQP1YufAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OperationCompartment" type="UMLOperationCompartmentView" guid="9uZgXfUGFUWwEn2HwyGyLAAA">
+<XPD:REF name="Model">WfkxoUbZqUOof1sQP1YufAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TemplateParameterCompartment" type="UMLTemplateParameterCompartmentView" guid="4sk3WJs3VUakc5yh9IJfcAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:REF name="Model">WfkxoUbZqUOof1sQP1YufAAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[19]" type="UMLGeneralizationView" guid="5zFd1aBYUEiaDAk+OIT1vwAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Points" type="Points">451,297;363,236</XPD:ATTR>
+<XPD:REF name="Model">TFV/zVsrMESTDkTEnyr/rAAA</XPD:REF>
+<XPD:REF name="Head">y/GCWOvnj0elYh+OdbeO9gAA</XPD:REF>
+<XPD:REF name="Tail">3goKGKxfG0uL8r408fsXYQAA</XPD:REF>
+<XPD:OBJ name="NameLabel" type="EdgeLabelView" guid="Q1EVGEa+gEGBTfHRPHeyQwAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">15</XPD:ATTR>
+<XPD:REF name="Model">TFV/zVsrMESTDkTEnyr/rAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="EdgeLabelView" guid="V3kkj8+ppU2uUukKHuY5HAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">30</XPD:ATTR>
+<XPD:REF name="Model">TFV/zVsrMESTDkTEnyr/rAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="EdgeLabelView" guid="DMtW4jIk1EGOUomDvZBeRQAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">-1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">15</XPD:ATTR>
+<XPD:REF name="Model">TFV/zVsrMESTDkTEnyr/rAAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[20]" type="UMLGeneralizationView" guid="9YkaGi+Za0asQQTIGIZsJAAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="LineStyle" type="LineStyleKind">lsRectilinear</XPD:ATTR>
+<XPD:ATTR name="Points" type="Points">436,198;363,198</XPD:ATTR>
+<XPD:REF name="Model">sh0Wc2GWw02v4RJbRczpBwAA</XPD:REF>
+<XPD:REF name="Head">y/GCWOvnj0elYh+OdbeO9gAA</XPD:REF>
+<XPD:REF name="Tail">TEw9LFZNuE+vJNGP9lmkkQAA</XPD:REF>
+<XPD:OBJ name="NameLabel" type="EdgeLabelView" guid="/ISe8VXAX0C5S5zwkxof5AAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">15</XPD:ATTR>
+<XPD:REF name="Model">sh0Wc2GWw02v4RJbRczpBwAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="EdgeLabelView" guid="lt3cB7/kRUiQtDWrTE6mSwAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">30</XPD:ATTR>
+<XPD:REF name="Model">sh0Wc2GWw02v4RJbRczpBwAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="EdgeLabelView" guid="AUHGhTx7YkSkeWhJgHdmLwAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">-1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">15</XPD:ATTR>
+<XPD:REF name="Model">sh0Wc2GWw02v4RJbRczpBwAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[21]" type="UMLNoteView" guid="sUc4obK/ZEa9nz+c1miVhwAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">24</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">48</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">211</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">173</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">ImplML validation happens using
+validator classes. Each validator
+checks for only one specific sort of
+problem (or at most a few).
+
+PROBLEM_TYPES specifies the types of
+problems the validator class produces,
+so the validator classes can be filtered
+using the problem filter, and the
+validation code for those does not need
+to be run unnecessarily.
+</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[22]" type="UMLNoteLinkView" guid="Uz1JfsQF+U6nCAYpumccXAAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Points" type="Points">264,184;234,173</XPD:ATTR>
+<XPD:REF name="Head">sUc4obK/ZEa9nz+c1miVhwAA</XPD:REF>
+<XPD:REF name="Tail">y/GCWOvnj0elYh+OdbeO9gAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[23]" type="UMLNoteView" guid="Jnc/ZHbN/U2fSg2Fi1cCCAAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">364</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">32</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">231</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">53</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">Validators deriving from GlobalValidatorBase
+validate the whole implementation set
+at once. These are pretty rare cases.
+</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[24]" type="UMLNoteLinkView" guid="9KcDSptqe0GHuL32XyzzCgAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Points" type="Points">494,176;482,84</XPD:ATTR>
+<XPD:REF name="Head">Jnc/ZHbN/U2fSg2Fi1cCCAAA</XPD:REF>
+<XPD:REF name="Tail">TEw9LFZNuE+vJNGP9lmkkQAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[25]" type="UMLPackageView" guid="oyJAaWjr+06Ztadvt0qcowAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">672</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">104</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">233</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">105</XPD:ATTR>
+<XPD:REF name="Model">Md0YIXCoWEGWJR7Ev5Wv5AAA</XPD:REF>
+<XPD:OBJ name="NameCompartment" type="UMLNameCompartmentView" guid="2tTeAqqbeEiZxvuFCwqvgQAA">
+<XPD:OBJ name="NameLabel" type="LabelView" guid="0MmVS5fx50mMvqLox9nhRQAA">
+<XPD:ATTR name="Text" type="string">cone.validation.builtinvalidators.implml</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="LabelView" guid="EyCx+0CnU0u9zgpIHpjotwAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="LabelView" guid="2t5r+XBKD065MxE3CL0EKAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[26]" type="UMLClassView" guid="1HH9DFhjeUaISb6w7/0iHwAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">688</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">148</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">209</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">43</XPD:ATTR>
+<XPD:REF name="Model">dtL6oUxsS0aPIWsKeupmrwAA</XPD:REF>
+<XPD:OBJ name="NameCompartment" type="UMLNameCompartmentView" guid="ES2fu4F1pEGRkgCeSchcMwAA">
+<XPD:OBJ name="NameLabel" type="LabelView" guid="DLbsYfARt02Gp0WWFguk+QAA">
+<XPD:ATTR name="FontStyle" type="integer">1</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">DuplicateTempFeatureRefValidator</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="LabelView" guid="goUu+z/QDEej2rLtG4sztgAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="LabelView" guid="JG4wB6nngk2x175JkCACRQAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="AttributeCompartment" type="UMLAttributeCompartmentView" guid="LQOwUJ3q3U2h79vr6vuJrAAA">
+<XPD:REF name="Model">dtL6oUxsS0aPIWsKeupmrwAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OperationCompartment" type="UMLOperationCompartmentView" guid="yZanADMD1kWito+AdZun4AAA">
+<XPD:REF name="Model">dtL6oUxsS0aPIWsKeupmrwAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TemplateParameterCompartment" type="UMLTemplateParameterCompartmentView" guid="08EckAooiE+rkMKGjX/75wAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:REF name="Model">dtL6oUxsS0aPIWsKeupmrwAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[27]" type="UMLRealizationView" guid="p+vZY5sJc0C6ZbH9zCH27wAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Points" type="Points">688,179;558,191</XPD:ATTR>
+<XPD:REF name="Model">SYK6JJaoy0SMuQ+WSY9s/QAA</XPD:REF>
+<XPD:REF name="Head">TEw9LFZNuE+vJNGP9lmkkQAA</XPD:REF>
+<XPD:REF name="Tail">1HH9DFhjeUaISb6w7/0iHwAA</XPD:REF>
+<XPD:OBJ name="NameLabel" type="EdgeLabelView" guid="OisbfBnQfEaKRdVx11hhYQAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">15</XPD:ATTR>
+<XPD:REF name="Model">SYK6JJaoy0SMuQ+WSY9s/QAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="EdgeLabelView" guid="LkcpLPU5cUe8GPCArFisOQAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">30</XPD:ATTR>
+<XPD:REF name="Model">SYK6JJaoy0SMuQ+WSY9s/QAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="EdgeLabelView" guid="7u2KWJKsX0Cfd7ZbbmNPMQAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">-1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">15</XPD:ATTR>
+<XPD:REF name="Model">SYK6JJaoy0SMuQ+WSY9s/QAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[28]" type="UMLNoteView" guid="SuIMeQW7gk6KodeUMOeXnwAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">636</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">8</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">178</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">83</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">Mainly ImplML validators come
+from plug-ins, but there is also
+a set of built-in validator classes
+(for validating ImplContainer
+instances).
+</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[29]" type="UMLNoteLinkView" guid="qrCgXxwivEm4AcMYImbMjwAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Points" type="Points">757,104;749,90</XPD:ATTR>
+<XPD:REF name="Head">SuIMeQW7gk6KodeUMOeXnwAA</XPD:REF>
+<XPD:REF name="Tail">oyJAaWjr+06Ztadvt0qcowAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedDiagrams[1]" type="UMLClassDiagram" guid="iijTyCe1nke1ngA2DWMMDAAA">
+<XPD:ATTR name="Name" type="string">ConfmlValidation</XPD:ATTR>
+<XPD:REF name="DiagramOwner">J0JbQTHSq0yi13n61FmjzgAA</XPD:REF>
+<XPD:OBJ name="DiagramView" type="UMLClassDiagramView" guid="YJnJaMJXX0mRbyH8gN9PZQAA">
+<XPD:REF name="Diagram">iijTyCe1nke1ngA2DWMMDAAA</XPD:REF>
+<XPD:ATTR name="#OwnedViews" type="integer">19</XPD:ATTR>
+<XPD:OBJ name="OwnedViews[0]" type="UMLPackageView" guid="sm9uFVeIzEybVzNh0ZD+ywAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">548</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">120</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">215</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">157</XPD:ATTR>
+<XPD:REF name="Model">gb1B3r/wIkeUDgFfr7dtwwAA</XPD:REF>
+<XPD:OBJ name="NameCompartment" type="UMLNameCompartmentView" guid="L373DrT4CkOQiOj0sz4gEQAA">
+<XPD:OBJ name="NameLabel" type="LabelView" guid="/MNO2OYFJE2Kx/H955rCawAA">
+<XPD:ATTR name="Text" type="string">cone.validation.builtinvalidator.confml</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="LabelView" guid="OuVfLOJ780yqW0Kyl3t5hAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="LabelView" guid="MWRrK1bzrEajQ+KA0W2TOgAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[1]" type="UMLPackageView" guid="P3ezBGNoxUSwo3wuAMVFiAAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">88</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">96</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">373</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">185</XPD:ATTR>
+<XPD:REF name="Model">Wl0JQVQ3CEuxp+MiuIDDVQAA</XPD:REF>
+<XPD:OBJ name="NameCompartment" type="UMLNameCompartmentView" guid="tez9QgCIEU6ejLO43GLiRAAA">
+<XPD:OBJ name="NameLabel" type="LabelView" guid="eNAF2TaB1EaEr6E+6A3o8wAA">
+<XPD:ATTR name="Text" type="string">cone.validation.confmlvalidation</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="LabelView" guid="ZeuH1NrxlEuVzgnf8uYMhgAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="LabelView" guid="kuMMijryJUupa8o4T6P/egAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[2]" type="UMLClassView" guid="5sQAX2rJOESpxsazqtjv/wAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">112</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">140</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">111</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">95</XPD:ATTR>
+<XPD:REF name="Model">6WAPzjt1AUKuMkcJEQnMNAAA</XPD:REF>
+<XPD:OBJ name="NameCompartment" type="UMLNameCompartmentView" guid="NTG+Fr36CECF9OvkOsxluAAA">
+<XPD:OBJ name="NameLabel" type="LabelView" guid="CbRGQfp0H0K7WvZADPSJPgAA">
+<XPD:ATTR name="FontStyle" type="integer">1</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">ValidationContext</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="LabelView" guid="K0xqKZO+NU2Asdv80xL2jQAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="LabelView" guid="jwPJY4XbLkCuUSSy0UBWHQAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="AttributeCompartment" type="UMLAttributeCompartmentView" guid="hDcwGnPSZEimcb15NFHnOAAA">
+<XPD:REF name="Model">6WAPzjt1AUKuMkcJEQnMNAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OperationCompartment" type="UMLOperationCompartmentView" guid="IM1WlpZrKEqwEHUaM74EFAAA">
+<XPD:REF name="Model">6WAPzjt1AUKuMkcJEQnMNAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TemplateParameterCompartment" type="UMLTemplateParameterCompartmentView" guid="EI3ZLQJ4ak2I2jQ+4aOQ4wAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:REF name="Model">6WAPzjt1AUKuMkcJEQnMNAAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[3]" type="UMLClassView" guid="ogVxPBQL3k6pyOzvc0MMFAAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">304</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">156</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">100</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">69</XPD:ATTR>
+<XPD:REF name="Model">yeAzLzipb0S50RpYIsQH2gAA</XPD:REF>
+<XPD:OBJ name="NameCompartment" type="UMLNameCompartmentView" guid="J0KV+h4VAEuuInbzKHVkrwAA">
+<XPD:OBJ name="NameLabel" type="LabelView" guid="RNAgKe4bhk+ZcDdabra8zwAA">
+<XPD:ATTR name="FontStyle" type="integer">3</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">ValidatorBase</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="LabelView" guid="O0t9TqxxYU+JEOrP4ol+xgAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="LabelView" guid="gsELg6U8kU2VUSZGn18q8QAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="AttributeCompartment" type="UMLAttributeCompartmentView" guid="xj1GtlFznUasqLxmUZeJcwAA">
+<XPD:REF name="Model">yeAzLzipb0S50RpYIsQH2gAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OperationCompartment" type="UMLOperationCompartmentView" guid="Leqp3IYyvEKQTTTtNSjC7wAA">
+<XPD:REF name="Model">yeAzLzipb0S50RpYIsQH2gAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TemplateParameterCompartment" type="UMLTemplateParameterCompartmentView" guid="GnFhUdzPmEa3rwo8LcYKEQAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:REF name="Model">yeAzLzipb0S50RpYIsQH2gAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[4]" type="UMLAssociationView" guid="OO3OuToGd0unmYJL9p4BcgAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Points" type="Points">222,188;304,189</XPD:ATTR>
+<XPD:REF name="Model">a+P0rhTH2kieoO26fePJcAAA</XPD:REF>
+<XPD:REF name="Head">ogVxPBQL3k6pyOzvc0MMFAAA</XPD:REF>
+<XPD:REF name="Tail">5sQAX2rJOESpxsazqtjv/wAA</XPD:REF>
+<XPD:OBJ name="NameLabel" type="EdgeLabelView" guid="Jf3WcoK5rkK0bXKIzzP1LwAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">15</XPD:ATTR>
+<XPD:REF name="Model">a+P0rhTH2kieoO26fePJcAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="EdgeLabelView" guid="E5yN6PLtpkiSBcAATCm/CgAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">30</XPD:ATTR>
+<XPD:REF name="Model">a+P0rhTH2kieoO26fePJcAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="EdgeLabelView" guid="dEV2q1LebUmoTMPYClzbqwAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">-1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">15</XPD:ATTR>
+<XPD:REF name="Model">a+P0rhTH2kieoO26fePJcAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="HeadRoleNameLabel" type="EdgeLabelView" guid="vbnMU/dM+0O0vafILK/dSwAA">
+<XPD:ATTR name="Alpha" type="real">-0.523598775598299</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">30</XPD:ATTR>
+<XPD:ATTR name="EdgePosition" type="EdgePositionKind">epHead</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">+context</XPD:ATTR>
+<XPD:REF name="Model">2zKLgXw7zUKcrd3FmFVP3wAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TailRoleNameLabel" type="EdgeLabelView" guid="LXveBLUSk024mZkKltY4VQAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">0.523598775598299</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">30</XPD:ATTR>
+<XPD:ATTR name="EdgePosition" type="EdgePositionKind">epTail</XPD:ATTR>
+<XPD:REF name="Model">BmDMhTlKJkKpLaJwiCOBZwAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="HeadMultiplicityLabel" type="EdgeLabelView" guid="zdAyL2g1+0WkJ4IeOTOggQAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">0.523598775598299</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">25</XPD:ATTR>
+<XPD:ATTR name="EdgePosition" type="EdgePositionKind">epHead</XPD:ATTR>
+<XPD:REF name="Model">2zKLgXw7zUKcrd3FmFVP3wAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TailMultiplicityLabel" type="EdgeLabelView" guid="jFZFyZ5BKEGQ2J0Zo9QgvQAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">-0.523598775598299</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">25</XPD:ATTR>
+<XPD:ATTR name="EdgePosition" type="EdgePositionKind">epTail</XPD:ATTR>
+<XPD:REF name="Model">BmDMhTlKJkKpLaJwiCOBZwAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="HeadPropertyLabel" type="EdgeLabelView" guid="ncLwP0F7NUCXrZIiSdoUHgAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">-0.785398163397448</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">40</XPD:ATTR>
+<XPD:ATTR name="EdgePosition" type="EdgePositionKind">epHead</XPD:ATTR>
+<XPD:REF name="Model">2zKLgXw7zUKcrd3FmFVP3wAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TailPropertyLabel" type="EdgeLabelView" guid="K5g2QnUcyUGngPoEWoXatwAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">0.785398163397448</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">40</XPD:ATTR>
+<XPD:ATTR name="EdgePosition" type="EdgePositionKind">epTail</XPD:ATTR>
+<XPD:REF name="Model">BmDMhTlKJkKpLaJwiCOBZwAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="HeadQualifierCompartment" type="UMLQualifierCompartmentView" guid="KGEeUhgfWUCyUQxhCDRf3gAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">-1080</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">-984</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">50</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">8</XPD:ATTR>
+<XPD:REF name="Model">2zKLgXw7zUKcrd3FmFVP3wAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TailQualifierCompartment" type="UMLQualifierCompartmentView" guid="EFO+Bga4PUWWBm9ayJ5PFAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">-1080</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">-984</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">50</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">8</XPD:ATTR>
+<XPD:REF name="Model">BmDMhTlKJkKpLaJwiCOBZwAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[5]" type="UMLClassView" guid="qOPIH+pKDEWBtOJbZYgCaAAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">588</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">164</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">124</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">43</XPD:ATTR>
+<XPD:REF name="Model">hborxSDNsk2fbR0/hWRHNgAA</XPD:REF>
+<XPD:OBJ name="NameCompartment" type="UMLNameCompartmentView" guid="/k07VpONNEqsVKSsDHj3yAAA">
+<XPD:OBJ name="NameLabel" type="LabelView" guid="g02eojmQS0WE5YG4qQ/T4gAA">
+<XPD:ATTR name="FontStyle" type="integer">1</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">MaxLengthValidator</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="LabelView" guid="hi2Crjzk/keopV+3NJhxfAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="LabelView" guid="MtXTCjsP5kGk5iWkgfI1ogAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="AttributeCompartment" type="UMLAttributeCompartmentView" guid="5U3ADC9fokmZPYm91Xd3mAAA">
+<XPD:REF name="Model">hborxSDNsk2fbR0/hWRHNgAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OperationCompartment" type="UMLOperationCompartmentView" guid="M4a94cLxpkGVKOxShuVFqQAA">
+<XPD:REF name="Model">hborxSDNsk2fbR0/hWRHNgAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TemplateParameterCompartment" type="UMLTemplateParameterCompartmentView" guid="NeV2eYQyR0aQwtSl4rhQhQAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:REF name="Model">hborxSDNsk2fbR0/hWRHNgAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[6]" type="UMLRealizationView" guid="qV4ITWMWLU6VMUw0NGujcQAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Points" type="Points">588,186;403,189</XPD:ATTR>
+<XPD:REF name="Model">x3PVKMHyJUO0m0hk6x6+8QAA</XPD:REF>
+<XPD:REF name="Head">ogVxPBQL3k6pyOzvc0MMFAAA</XPD:REF>
+<XPD:REF name="Tail">qOPIH+pKDEWBtOJbZYgCaAAA</XPD:REF>
+<XPD:OBJ name="NameLabel" type="EdgeLabelView" guid="bzqSN6R+nUuCmmCmE3g3UAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">15</XPD:ATTR>
+<XPD:REF name="Model">x3PVKMHyJUO0m0hk6x6+8QAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="EdgeLabelView" guid="LoJmdkzjLE6NtolTzPHITAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">30</XPD:ATTR>
+<XPD:REF name="Model">x3PVKMHyJUO0m0hk6x6+8QAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="EdgeLabelView" guid="wO7Dtbem4k2F4ew1uxznzAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">-1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">15</XPD:ATTR>
+<XPD:REF name="Model">x3PVKMHyJUO0m0hk6x6+8QAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[7]" type="UMLClassView" guid="z9HhgfsZpk6vQG5aOdZBKQAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">588</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">216</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">120</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">43</XPD:ATTR>
+<XPD:REF name="Model">S5CFGHNdFU+TPZnIr60XEAAA</XPD:REF>
+<XPD:OBJ name="NameCompartment" type="UMLNameCompartmentView" guid="CwRTZSVJPEOmlIkV9rzKIwAA">
+<XPD:OBJ name="NameLabel" type="LabelView" guid="rKTlpAW2FUaPXVEaBSyBewAA">
+<XPD:ATTR name="FontStyle" type="integer">1</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">MinLengthValidator</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="LabelView" guid="KuMIOT4iX0afYDPQzosDoAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="LabelView" guid="/YsPjCWpVE+70GQQDKiwcQAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="AttributeCompartment" type="UMLAttributeCompartmentView" guid="gPUSt+fcikOaoH+AAheLzwAA">
+<XPD:REF name="Model">S5CFGHNdFU+TPZnIr60XEAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OperationCompartment" type="UMLOperationCompartmentView" guid="uOs4rEOv0UykmXnKX3W0ygAA">
+<XPD:REF name="Model">S5CFGHNdFU+TPZnIr60XEAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TemplateParameterCompartment" type="UMLTemplateParameterCompartmentView" guid="eGBKj40IZEGUCiX4P1z1jAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:REF name="Model">S5CFGHNdFU+TPZnIr60XEAAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[8]" type="UMLRealizationView" guid="3SoG4OJ000uW8mQ1rd9WfAAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Points" type="Points">588,228;403,198</XPD:ATTR>
+<XPD:REF name="Model">SVsn2qUKTEmmF2QmMwcJnAAA</XPD:REF>
+<XPD:REF name="Head">ogVxPBQL3k6pyOzvc0MMFAAA</XPD:REF>
+<XPD:REF name="Tail">z9HhgfsZpk6vQG5aOdZBKQAA</XPD:REF>
+<XPD:OBJ name="NameLabel" type="EdgeLabelView" guid="fdSow+ETWEizVTlugKms7wAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">15</XPD:ATTR>
+<XPD:REF name="Model">SVsn2qUKTEmmF2QmMwcJnAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="EdgeLabelView" guid="PgumoRJ2pU67+WAiaOS0lwAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">30</XPD:ATTR>
+<XPD:REF name="Model">SVsn2qUKTEmmF2QmMwcJnAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="EdgeLabelView" guid="4p1y9ojoTkOUrWgaa6wB7QAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">-1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">15</XPD:ATTR>
+<XPD:REF name="Model">SVsn2qUKTEmmF2QmMwcJnAAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[9]" type="UMLPackageView" guid="qfGVeEllc0uRJYtt+gcmLQAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">380</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">372</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">133</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">117</XPD:ATTR>
+<XPD:REF name="Model">LaydkygZykqnLCXC9YglFgAA</XPD:REF>
+<XPD:OBJ name="NameCompartment" type="UMLNameCompartmentView" guid="1j7TDkksv0OTYhR57mkR0gAA">
+<XPD:OBJ name="NameLabel" type="LabelView" guid="OpNbG+kHakyUx+JE2BzsuwAA">
+<XPD:ATTR name="Text" type="string">fooplugin.foovalidators</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="LabelView" guid="CQ/y0rlBa02FSvRpmyTsTAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="LabelView" guid="X88vOhiae0yph4iPv9gVugAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[10]" type="UMLClassView" guid="RMmkBo4Wy0uDlgbbF8qp9AAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">400</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">424</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">90</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">43</XPD:ATTR>
+<XPD:REF name="Model">W4OOCM1jAEK5Dgre8fmqTAAA</XPD:REF>
+<XPD:OBJ name="NameCompartment" type="UMLNameCompartmentView" guid="IhT59rVu7ECu4w52KA5SxgAA">
+<XPD:OBJ name="NameLabel" type="LabelView" guid="yom+12c0g0O0PA5a/ARKOAAA">
+<XPD:ATTR name="FontStyle" type="integer">1</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">FooValidator</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="LabelView" guid="NXBXTpTG7EWCLhB+OzyWtAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="LabelView" guid="aDk4MkEGKke1eufqBAlvKwAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="AttributeCompartment" type="UMLAttributeCompartmentView" guid="WMsOpu0SNky1x3JnGxUpCQAA">
+<XPD:REF name="Model">W4OOCM1jAEK5Dgre8fmqTAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OperationCompartment" type="UMLOperationCompartmentView" guid="Jn5ocjLA20e+fh9gbFcRMQAA">
+<XPD:REF name="Model">W4OOCM1jAEK5Dgre8fmqTAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TemplateParameterCompartment" type="UMLTemplateParameterCompartmentView" guid="u/dPvwRLi0iaQ3TkhlpThAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:REF name="Model">W4OOCM1jAEK5Dgre8fmqTAAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[11]" type="UMLRealizationView" guid="vTs2mU66JUuBuD3YYBowNgAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Points" type="Points">437,424;365,224</XPD:ATTR>
+<XPD:REF name="Model">NwUHVYoqBUydydMZ2tDe4QAA</XPD:REF>
+<XPD:REF name="Head">ogVxPBQL3k6pyOzvc0MMFAAA</XPD:REF>
+<XPD:REF name="Tail">RMmkBo4Wy0uDlgbbF8qp9AAA</XPD:REF>
+<XPD:OBJ name="NameLabel" type="EdgeLabelView" guid="9LpNxmfD5UaMQzxQUSzZoQAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">15</XPD:ATTR>
+<XPD:REF name="Model">NwUHVYoqBUydydMZ2tDe4QAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="EdgeLabelView" guid="Q18hr5MPjE+KKV+74W27RAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">30</XPD:ATTR>
+<XPD:REF name="Model">NwUHVYoqBUydydMZ2tDe4QAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="EdgeLabelView" guid="JvIT766O7ECZQysR8GwXAQAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">-1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">15</XPD:ATTR>
+<XPD:REF name="Model">NwUHVYoqBUydydMZ2tDe4QAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[12]" type="UMLNoteView" guid="H7s5kCj7L0aVT3PqpTfoWwAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">516</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">324</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">204</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">68</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">The confmlvalidation module contains
+the built-in validators, but plug-ins can
+also provide custom validators via an
+egg entry point.
+</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[13]" type="UMLNoteLinkView" guid="fflEGKmmeEewcTaIE1gCrQAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Points" type="Points">636,276;625,324</XPD:ATTR>
+<XPD:REF name="Head">H7s5kCj7L0aVT3PqpTfoWwAA</XPD:REF>
+<XPD:REF name="Tail">sm9uFVeIzEybVzNh0ZD+ywAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[14]" type="UMLNoteLinkView" guid="vplvcGI0eESGWzUGT2Pi2gAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Points" type="Points">512,402;538,391</XPD:ATTR>
+<XPD:REF name="Head">H7s5kCj7L0aVT3PqpTfoWwAA</XPD:REF>
+<XPD:REF name="Tail">qfGVeEllc0uRJYtt+gcmLQAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[15]" type="UMLNoteView" guid="X6ZcBnf5GUGlnTTo1b8fKAAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">440</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">12</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">161</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">68</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">Like with ImplML validation,
+a validator is responsible only
+for generating problems of a
+specific type.
+</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[16]" type="UMLNoteLinkView" guid="J4R6jl4xhEii5JD9kIi07AAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Points" type="Points">392,156;481,79</XPD:ATTR>
+<XPD:REF name="Head">X6ZcBnf5GUGlnTTo1b8fKAAA</XPD:REF>
+<XPD:REF name="Tail">ogVxPBQL3k6pyOzvc0MMFAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[17]" type="UMLNoteView" guid="wYBm24foAkuCyXNp5c7rPwAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">68</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">336</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">244</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">83</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">The context contains the input (configuration)
+and the output (problems), but also all sorts of
+other data, e.g. a list of all features, so that
+validators do not need to build it themselves
+by traversing the model.
+</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[18]" type="UMLNoteLinkView" guid="3G+mR5vDKkeLUJVgqmxrvQAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Points" type="Points">172,234;184,336</XPD:ATTR>
+<XPD:REF name="Head">wYBm24foAkuCyXNp5c7rPwAA</XPD:REF>
+<XPD:REF name="Tail">5sQAX2rJOESpxsazqtjv/wAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:ATTR name="#OwnedElements" type="integer">18</XPD:ATTR>
+<XPD:OBJ name="OwnedElements[0]" type="UMLPackage" guid="2qWKZicOf06yzOTeZuyqCAAA">
+<XPD:ATTR name="Name" type="string">cone.validation.implmlvalidation</XPD:ATTR>
+<XPD:REF name="Namespace">J0JbQTHSq0yi13n61FmjzgAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">1</XPD:ATTR>
+<XPD:REF name="Views[0]">cBNU63cyHkyOttvWiFCzXAAA</XPD:REF>
+<XPD:ATTR name="#OwnedElements" type="integer">4</XPD:ATTR>
+<XPD:OBJ name="OwnedElements[0]" type="UMLClass" guid="XjBwLw9OjEmKJ4KD8B58wgAA">
+<XPD:ATTR name="Name" type="string">ImplValidatorBase</XPD:ATTR>
+<XPD:ATTR name="IsAbstract" type="boolean">True</XPD:ATTR>
+<XPD:REF name="Namespace">2qWKZicOf06yzOTeZuyqCAAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">3goKGKxfG0uL8r408fsXYQAA</XPD:REF>
+<XPD:REF name="Views[1]">1QldCtJUsECyFTsbu3s9XgAA</XPD:REF>
+<XPD:REF name="Views[2]">GwJF7Uc2qkucIa/W7XCSFwAA</XPD:REF>
+<XPD:REF name="Views[3]">Vg23dTmL40WKOmiqnNYWwQAA</XPD:REF>
+<XPD:ATTR name="#SupplierDependencies" type="integer">2</XPD:ATTR>
+<XPD:REF name="SupplierDependencies[0]">Kc/JhhXZ9kaQvIqg52hkzQAA</XPD:REF>
+<XPD:REF name="SupplierDependencies[1]">6sSq0GCuIUuD+jUJQcViugAA</XPD:REF>
+<XPD:ATTR name="#Generalizations" type="integer">1</XPD:ATTR>
+<XPD:REF name="Generalizations[0]">TFV/zVsrMESTDkTEnyr/rAAA</XPD:REF>
+<XPD:ATTR name="#Operations" type="integer">1</XPD:ATTR>
+<XPD:OBJ name="Operations[0]" type="UMLOperation" guid="EDvmoc6/qUS10x+lUcZuYgAA">
+<XPD:ATTR name="Name" type="string">validate</XPD:ATTR>
+<XPD:ATTR name="IsAbstract" type="boolean">True</XPD:ATTR>
+<XPD:REF name="Owner">XjBwLw9OjEmKJ4KD8B58wgAA</XPD:REF>
+</XPD:OBJ>
+<XPD:ATTR name="#Associations" type="integer">2</XPD:ATTR>
+<XPD:REF name="Associations[0]">to4Ge8pEOk6oiY69/D4VDgAA</XPD:REF>
+<XPD:REF name="Associations[1]">GfSW7NI3NEORsulHu2l+XgAA</XPD:REF>
+<XPD:ATTR name="#Attributes" type="integer">1</XPD:ATTR>
+<XPD:OBJ name="Attributes[0]" type="UMLAttribute" guid="fIrvo8pJyEGS7cbbM4xtzgAA">
+<XPD:ATTR name="Name" type="string">SUPPORTED_IMPL_CLASSES</XPD:ATTR>
+<XPD:ATTR name="OwnerScope" type="UMLScopeKind">skClassifier</XPD:ATTR>
+<XPD:ATTR name="TargetScope" type="UMLScopeKind">skClassifier</XPD:ATTR>
+<XPD:REF name="Owner">XjBwLw9OjEmKJ4KD8B58wgAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedElements[1]" type="UMLClass" guid="nx3Lx4aZoUSFCSv3hH2xRgAA">
+<XPD:ATTR name="Name" type="string">ValidationContext</XPD:ATTR>
+<XPD:REF name="Namespace">2qWKZicOf06yzOTeZuyqCAAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">g14za6T92EGNk4PWs/vUjQAA</XPD:REF>
+<XPD:REF name="Views[1]">yEtGoC/OVU+MtM58Kcp8eQAA</XPD:REF>
+<XPD:REF name="Views[2]">sl4ETPFlpUmkpdJ3lTHfCAAA</XPD:REF>
+<XPD:REF name="Views[3]">aSfLN5cFNkW4AgKNImQMDAAA</XPD:REF>
+<XPD:ATTR name="#Associations" type="integer">1</XPD:ATTR>
+<XPD:REF name="Associations[0]">q6CV7L6RD0ipPZFD0c2e1wAA</XPD:REF>
+<XPD:ATTR name="#Attributes" type="integer">2</XPD:ATTR>
+<XPD:OBJ name="Attributes[0]" type="UMLAttribute" guid="Jmv2o920ukqnHKmC7FGbIgAA">
+<XPD:ATTR name="Name" type="string">configuration</XPD:ATTR>
+<XPD:REF name="Owner">nx3Lx4aZoUSFCSv3hH2xRgAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="Attributes[1]" type="UMLAttribute" guid="/CwszCth20Kl1E5e3XiQoQAA">
+<XPD:ATTR name="Name" type="string">problems</XPD:ATTR>
+<XPD:REF name="Owner">nx3Lx4aZoUSFCSv3hH2xRgAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedElements[2]" type="UMLClass" guid="WfkxoUbZqUOof1sQP1YufAAA">
+<XPD:ATTR name="Name" type="string">ValidatorBase</XPD:ATTR>
+<XPD:ATTR name="IsAbstract" type="boolean">True</XPD:ATTR>
+<XPD:REF name="Namespace">2qWKZicOf06yzOTeZuyqCAAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">y/GCWOvnj0elYh+OdbeO9gAA</XPD:REF>
+<XPD:REF name="Views[1]">/gHyKKAz8E2mAa0etgNEMQAA</XPD:REF>
+<XPD:REF name="Views[2]">9uZgXfUGFUWwEn2HwyGyLAAA</XPD:REF>
+<XPD:REF name="Views[3]">4sk3WJs3VUakc5yh9IJfcAAA</XPD:REF>
+<XPD:ATTR name="#Specializations" type="integer">2</XPD:ATTR>
+<XPD:REF name="Specializations[0]">TFV/zVsrMESTDkTEnyr/rAAA</XPD:REF>
+<XPD:REF name="Specializations[1]">sh0Wc2GWw02v4RJbRczpBwAA</XPD:REF>
+<XPD:ATTR name="#Operations" type="integer">1</XPD:ATTR>
+<XPD:OBJ name="Operations[0]" type="UMLOperation" guid="3mlkcVFjHUmdKSwESgFxaAAA">
+<XPD:ATTR name="Name" type="string">validate</XPD:ATTR>
+<XPD:REF name="Owner">WfkxoUbZqUOof1sQP1YufAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:ATTR name="#Attributes" type="integer">1</XPD:ATTR>
+<XPD:OBJ name="Attributes[0]" type="UMLAttribute" guid="la+IIPPuX0mJUaBEri0DtgAA">
+<XPD:ATTR name="Name" type="string">PROBLEM_TYPES</XPD:ATTR>
+<XPD:ATTR name="OwnerScope" type="UMLScopeKind">skClassifier</XPD:ATTR>
+<XPD:REF name="Owner">WfkxoUbZqUOof1sQP1YufAAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedElements[3]" type="UMLClass" guid="w1x85nyRiUi3HLBob1jwlQAA">
+<XPD:ATTR name="Name" type="string">GlobalValidatorBase</XPD:ATTR>
+<XPD:ATTR name="IsAbstract" type="boolean">True</XPD:ATTR>
+<XPD:REF name="Namespace">2qWKZicOf06yzOTeZuyqCAAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">TEw9LFZNuE+vJNGP9lmkkQAA</XPD:REF>
+<XPD:REF name="Views[1]">CJx7Itfy7Uibwjeyw5yQDQAA</XPD:REF>
+<XPD:REF name="Views[2]">jFGd4I3bN0K55FxynMIRQwAA</XPD:REF>
+<XPD:REF name="Views[3]">z0uyUnKnI0Gaw2xWrA8UsgAA</XPD:REF>
+<XPD:ATTR name="#SupplierDependencies" type="integer">1</XPD:ATTR>
+<XPD:REF name="SupplierDependencies[0]">SYK6JJaoy0SMuQ+WSY9s/QAA</XPD:REF>
+<XPD:ATTR name="#Generalizations" type="integer">1</XPD:ATTR>
+<XPD:REF name="Generalizations[0]">sh0Wc2GWw02v4RJbRczpBwAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedElements[1]" type="UMLPackage" guid="SI/VACVeYUOmYmmg2TSKaQAA">
+<XPD:ATTR name="Name" type="string">crmlplugin.crml_validators</XPD:ATTR>
+<XPD:REF name="Namespace">J0JbQTHSq0yi13n61FmjzgAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">1</XPD:ATTR>
+<XPD:REF name="Views[0]">9RQji6pg1U2ipqsxknfe8gAA</XPD:REF>
+<XPD:ATTR name="#OwnedElements" type="integer">2</XPD:ATTR>
+<XPD:OBJ name="OwnedElements[0]" type="UMLClass" guid="wbvMqm+/yE2hNe1Utj7f9AAA">
+<XPD:ATTR name="Name" type="string">CrmlReferenceValidator</XPD:ATTR>
+<XPD:REF name="Namespace">SI/VACVeYUOmYmmg2TSKaQAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">UjOB3AO2S0SO11NmkC+uFwAA</XPD:REF>
+<XPD:REF name="Views[1]">VsZ1ugd2fUCdG5xIOrwxdwAA</XPD:REF>
+<XPD:REF name="Views[2]">j2iWaOgMlEKIj8vhMaHFfQAA</XPD:REF>
+<XPD:REF name="Views[3]">wtdyekaYd0KBv6UhMLDnewAA</XPD:REF>
+<XPD:ATTR name="#ClientDependencies" type="integer">1</XPD:ATTR>
+<XPD:REF name="ClientDependencies[0]">6sSq0GCuIUuD+jUJQcViugAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedElements[1]" type="UMLClass" guid="Cy+SmuqmpkSX9nQNWXF+MgAA">
+<XPD:ATTR name="Name" type="string">CrmlDuplicateUidValidator</XPD:ATTR>
+<XPD:REF name="Namespace">SI/VACVeYUOmYmmg2TSKaQAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">POGF8jlAQ0WHmmVN5I344AAA</XPD:REF>
+<XPD:REF name="Views[1]">WCx5ai4Z1kijSbAQp7n+6AAA</XPD:REF>
+<XPD:REF name="Views[2]">VtgEwJKxc0aWpNn81zMWxgAA</XPD:REF>
+<XPD:REF name="Views[3]">HM/6PUALRU+eMxw64yLK/QAA</XPD:REF>
+<XPD:ATTR name="#ClientDependencies" type="integer">1</XPD:ATTR>
+<XPD:REF name="ClientDependencies[0]">Kc/JhhXZ9kaQvIqg52hkzQAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedElements[2]" type="UMLRealization" guid="Kc/JhhXZ9kaQvIqg52hkzQAA">
+<XPD:REF name="Namespace">J0JbQTHSq0yi13n61FmjzgAA</XPD:REF>
+<XPD:REF name="Client">Cy+SmuqmpkSX9nQNWXF+MgAA</XPD:REF>
+<XPD:REF name="Supplier">XjBwLw9OjEmKJ4KD8B58wgAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">oqIw0IFa9kWea9XTuFMZ1AAA</XPD:REF>
+<XPD:REF name="Views[1]">4Ju7YjWI0kS3NUyxQah2ZQAA</XPD:REF>
+<XPD:REF name="Views[2]">NHJXrkZ9iUao9zyQg2EKugAA</XPD:REF>
+<XPD:REF name="Views[3]">mIgLnOfmNkCkHAhbqSNpDgAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedElements[3]" type="UMLRealization" guid="6sSq0GCuIUuD+jUJQcViugAA">
+<XPD:REF name="Namespace">J0JbQTHSq0yi13n61FmjzgAA</XPD:REF>
+<XPD:REF name="Client">wbvMqm+/yE2hNe1Utj7f9AAA</XPD:REF>
+<XPD:REF name="Supplier">XjBwLw9OjEmKJ4KD8B58wgAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">ysaiWR11jkCPXTaPKqvETAAA</XPD:REF>
+<XPD:REF name="Views[1]">15dM8+2xdUqVA0PEz4Z+lAAA</XPD:REF>
+<XPD:REF name="Views[2]">Yy5JZoVrZk6fO/HBzcXbLQAA</XPD:REF>
+<XPD:REF name="Views[3]">rdBsD6yDGUCxMqzu4s/5jgAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedElements[4]" type="UMLAssociation" guid="9tUo6t0cgkqrFSmHsMYuAAAA">
+<XPD:REF name="Namespace">J0JbQTHSq0yi13n61FmjzgAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">G4BGfDCjwkO+jlXwGuVFJwAA</XPD:REF>
+<XPD:REF name="Views[1]">4KvH0CBxeE6GrVd/KPRCVAAA</XPD:REF>
+<XPD:REF name="Views[2]">Q/jeLaNxY0mQNbmb5EjLqwAA</XPD:REF>
+<XPD:REF name="Views[3]">2wPc15TFakOVGaYagKeKWQAA</XPD:REF>
+<XPD:ATTR name="#Connections" type="integer">2</XPD:ATTR>
+<XPD:OBJ name="Connections[0]" type="UMLAssociationEnd" guid="q6CV7L6RD0ipPZFD0c2e1wAA">
+<XPD:REF name="Association">9tUo6t0cgkqrFSmHsMYuAAAA</XPD:REF>
+<XPD:REF name="Participant">nx3Lx4aZoUSFCSv3hH2xRgAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">MetUdT1H9UuvGWMD17NpFQAA</XPD:REF>
+<XPD:REF name="Views[1]">slOChvPyFUqAdCyKfHjcvAAA</XPD:REF>
+<XPD:REF name="Views[2]">yPzKg0VG3kSo7bwqixJw5wAA</XPD:REF>
+<XPD:REF name="Views[3]">yIiEf+5aYkWbTpXOnT53ggAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="Connections[1]" type="UMLAssociationEnd" guid="to4Ge8pEOk6oiY69/D4VDgAA">
+<XPD:ATTR name="Name" type="string">context</XPD:ATTR>
+<XPD:ATTR name="Aggregation" type="UMLAggregationKind">akAggregate</XPD:ATTR>
+<XPD:REF name="Association">9tUo6t0cgkqrFSmHsMYuAAAA</XPD:REF>
+<XPD:REF name="Participant">XjBwLw9OjEmKJ4KD8B58wgAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">VheCL5brfEmRNkId9sisYAAA</XPD:REF>
+<XPD:REF name="Views[1]">9iTNYzJ5TUuDLk/vA1PFmwAA</XPD:REF>
+<XPD:REF name="Views[2]">QuuWBk9xWkmhDNnTN1VaFgAA</XPD:REF>
+<XPD:REF name="Views[3]">42cJ86Z/+0K6N/F17BRRBQAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedElements[5]" type="UMLAssociation" guid="lMyxDaFSF0SCrMvdMMibSwAA">
+<XPD:REF name="Namespace">J0JbQTHSq0yi13n61FmjzgAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">chIlFeu+W0CfzByUAT+hMAAA</XPD:REF>
+<XPD:REF name="Views[1]">wuLJ37KQ8EuRL4PCZItYNwAA</XPD:REF>
+<XPD:REF name="Views[2]">D5NQL72A30SlV3uTGM6S/wAA</XPD:REF>
+<XPD:REF name="Views[3]">rF4ks9l5TkGOHIUJ8vyKmwAA</XPD:REF>
+<XPD:ATTR name="#Connections" type="integer">2</XPD:ATTR>
+<XPD:OBJ name="Connections[0]" type="UMLAssociationEnd" guid="xO0O32Ik5UKs7FALsy3uPQAA">
+<XPD:REF name="Association">lMyxDaFSF0SCrMvdMMibSwAA</XPD:REF>
+<XPD:REF name="Participant">cQYhYY9L50KRVH8GX320RAAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">xEctc7E62kSVYwICvYhLmwAA</XPD:REF>
+<XPD:REF name="Views[1]">t5ygmZQvmketK0B1UlCGyAAA</XPD:REF>
+<XPD:REF name="Views[2]">usGQ87TWBUu3+WGQUcXqYQAA</XPD:REF>
+<XPD:REF name="Views[3]">Xt49OQdNiEOsCMaWsliTKgAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="Connections[1]" type="UMLAssociationEnd" guid="GfSW7NI3NEORsulHu2l+XgAA">
+<XPD:ATTR name="Name" type="string">impl</XPD:ATTR>
+<XPD:ATTR name="Aggregation" type="UMLAggregationKind">akAggregate</XPD:ATTR>
+<XPD:REF name="Association">lMyxDaFSF0SCrMvdMMibSwAA</XPD:REF>
+<XPD:REF name="Participant">XjBwLw9OjEmKJ4KD8B58wgAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">gNKP+7f4V02nCGw0oisRogAA</XPD:REF>
+<XPD:REF name="Views[1]">fvH9lFDYXUOQ4sZb1bq8JwAA</XPD:REF>
+<XPD:REF name="Views[2]">n0abP8A4Kky9OwOpQrrd/AAA</XPD:REF>
+<XPD:REF name="Views[3]">vxzp55tliEacRjs1Bzk+KQAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedElements[6]" type="UMLPackage" guid="omsxqqbK/UWCHBKe5JrDagAA">
+<XPD:ATTR name="Name" type="string">cone.public.plugin</XPD:ATTR>
+<XPD:REF name="Namespace">J0JbQTHSq0yi13n61FmjzgAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">1</XPD:ATTR>
+<XPD:REF name="Views[0]">EJCUtlLZ2EmiEUOBxXASmAAA</XPD:REF>
+<XPD:ATTR name="#OwnedElements" type="integer">1</XPD:ATTR>
+<XPD:OBJ name="OwnedElements[0]" type="UMLClass" guid="cQYhYY9L50KRVH8GX320RAAA">
+<XPD:ATTR name="Name" type="string">ImplBase</XPD:ATTR>
+<XPD:ATTR name="IsAbstract" type="boolean">True</XPD:ATTR>
+<XPD:REF name="Namespace">omsxqqbK/UWCHBKe5JrDagAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">c5pkkfn3Xk2arAYxl83oLgAA</XPD:REF>
+<XPD:REF name="Views[1]">Ylq6cKNmOE+S+jAz03hfeAAA</XPD:REF>
+<XPD:REF name="Views[2]">rOLzdil6uECps+oXj/rh5QAA</XPD:REF>
+<XPD:REF name="Views[3]">2bQ9ix8R0kGXUdsUVLOfmwAA</XPD:REF>
+<XPD:ATTR name="#Associations" type="integer">1</XPD:ATTR>
+<XPD:REF name="Associations[0]">xO0O32Ik5UKs7FALsy3uPQAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedElements[7]" type="UMLPackage" guid="Wl0JQVQ3CEuxp+MiuIDDVQAA">
+<XPD:ATTR name="Name" type="string">cone.validation.confmlvalidation</XPD:ATTR>
+<XPD:REF name="Namespace">J0JbQTHSq0yi13n61FmjzgAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">1</XPD:ATTR>
+<XPD:REF name="Views[0]">P3ezBGNoxUSwo3wuAMVFiAAA</XPD:REF>
+<XPD:ATTR name="#OwnedElements" type="integer">2</XPD:ATTR>
+<XPD:OBJ name="OwnedElements[0]" type="UMLClass" guid="6WAPzjt1AUKuMkcJEQnMNAAA">
+<XPD:ATTR name="Name" type="string">ValidationContext</XPD:ATTR>
+<XPD:REF name="Namespace">Wl0JQVQ3CEuxp+MiuIDDVQAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">5sQAX2rJOESpxsazqtjv/wAA</XPD:REF>
+<XPD:REF name="Views[1]">hDcwGnPSZEimcb15NFHnOAAA</XPD:REF>
+<XPD:REF name="Views[2]">IM1WlpZrKEqwEHUaM74EFAAA</XPD:REF>
+<XPD:REF name="Views[3]">EI3ZLQJ4ak2I2jQ+4aOQ4wAA</XPD:REF>
+<XPD:ATTR name="#Associations" type="integer">1</XPD:ATTR>
+<XPD:REF name="Associations[0]">BmDMhTlKJkKpLaJwiCOBZwAA</XPD:REF>
+<XPD:ATTR name="#Attributes" type="integer">3</XPD:ATTR>
+<XPD:OBJ name="Attributes[0]" type="UMLAttribute" guid="YXEjV1z+Ukqc4tcuVz8+LwAA">
+<XPD:ATTR name="Name" type="string">configuration</XPD:ATTR>
+<XPD:REF name="Owner">6WAPzjt1AUKuMkcJEQnMNAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="Attributes[1]" type="UMLAttribute" guid="oLQ4b8kD5EqWv3auriAPGQAA">
+<XPD:ATTR name="Name" type="string">feature_dict</XPD:ATTR>
+<XPD:REF name="Owner">6WAPzjt1AUKuMkcJEQnMNAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="Attributes[2]" type="UMLAttribute" guid="CFpJ6UXq9EKo93pLznfV2QAA">
+<XPD:ATTR name="Name" type="string">problems</XPD:ATTR>
+<XPD:REF name="Owner">6WAPzjt1AUKuMkcJEQnMNAAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedElements[1]" type="UMLClass" guid="yeAzLzipb0S50RpYIsQH2gAA">
+<XPD:ATTR name="Name" type="string">ValidatorBase</XPD:ATTR>
+<XPD:ATTR name="IsAbstract" type="boolean">True</XPD:ATTR>
+<XPD:REF name="Namespace">Wl0JQVQ3CEuxp+MiuIDDVQAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">ogVxPBQL3k6pyOzvc0MMFAAA</XPD:REF>
+<XPD:REF name="Views[1]">xj1GtlFznUasqLxmUZeJcwAA</XPD:REF>
+<XPD:REF name="Views[2]">Leqp3IYyvEKQTTTtNSjC7wAA</XPD:REF>
+<XPD:REF name="Views[3]">GnFhUdzPmEa3rwo8LcYKEQAA</XPD:REF>
+<XPD:ATTR name="#SupplierDependencies" type="integer">3</XPD:ATTR>
+<XPD:REF name="SupplierDependencies[0]">x3PVKMHyJUO0m0hk6x6+8QAA</XPD:REF>
+<XPD:REF name="SupplierDependencies[1]">SVsn2qUKTEmmF2QmMwcJnAAA</XPD:REF>
+<XPD:REF name="SupplierDependencies[2]">NwUHVYoqBUydydMZ2tDe4QAA</XPD:REF>
+<XPD:ATTR name="#Operations" type="integer">1</XPD:ATTR>
+<XPD:OBJ name="Operations[0]" type="UMLOperation" guid="b9v8GwUo7ECkQRD9c90P/gAA">
+<XPD:ATTR name="Name" type="string">validate</XPD:ATTR>
+<XPD:ATTR name="IsAbstract" type="boolean">True</XPD:ATTR>
+<XPD:REF name="Owner">yeAzLzipb0S50RpYIsQH2gAA</XPD:REF>
+</XPD:OBJ>
+<XPD:ATTR name="#Associations" type="integer">1</XPD:ATTR>
+<XPD:REF name="Associations[0]">2zKLgXw7zUKcrd3FmFVP3wAA</XPD:REF>
+<XPD:ATTR name="#Attributes" type="integer">1</XPD:ATTR>
+<XPD:OBJ name="Attributes[0]" type="UMLAttribute" guid="0MbIYCfb406jhFrFspSKwgAA">
+<XPD:ATTR name="Name" type="string">PROBLEM_TYPES</XPD:ATTR>
+<XPD:ATTR name="OwnerScope" type="UMLScopeKind">skClassifier</XPD:ATTR>
+<XPD:ATTR name="TargetScope" type="UMLScopeKind">skClassifier</XPD:ATTR>
+<XPD:REF name="Owner">yeAzLzipb0S50RpYIsQH2gAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedElements[8]" type="UMLAssociation" guid="a+P0rhTH2kieoO26fePJcAAA">
+<XPD:REF name="Namespace">J0JbQTHSq0yi13n61FmjzgAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">OO3OuToGd0unmYJL9p4BcgAA</XPD:REF>
+<XPD:REF name="Views[1]">Jf3WcoK5rkK0bXKIzzP1LwAA</XPD:REF>
+<XPD:REF name="Views[2]">E5yN6PLtpkiSBcAATCm/CgAA</XPD:REF>
+<XPD:REF name="Views[3]">dEV2q1LebUmoTMPYClzbqwAA</XPD:REF>
+<XPD:ATTR name="#Connections" type="integer">2</XPD:ATTR>
+<XPD:OBJ name="Connections[0]" type="UMLAssociationEnd" guid="BmDMhTlKJkKpLaJwiCOBZwAA">
+<XPD:REF name="Association">a+P0rhTH2kieoO26fePJcAAA</XPD:REF>
+<XPD:REF name="Participant">6WAPzjt1AUKuMkcJEQnMNAAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">LXveBLUSk024mZkKltY4VQAA</XPD:REF>
+<XPD:REF name="Views[1]">jFZFyZ5BKEGQ2J0Zo9QgvQAA</XPD:REF>
+<XPD:REF name="Views[2]">K5g2QnUcyUGngPoEWoXatwAA</XPD:REF>
+<XPD:REF name="Views[3]">EFO+Bga4PUWWBm9ayJ5PFAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="Connections[1]" type="UMLAssociationEnd" guid="2zKLgXw7zUKcrd3FmFVP3wAA">
+<XPD:ATTR name="Name" type="string">context</XPD:ATTR>
+<XPD:ATTR name="Aggregation" type="UMLAggregationKind">akAggregate</XPD:ATTR>
+<XPD:REF name="Association">a+P0rhTH2kieoO26fePJcAAA</XPD:REF>
+<XPD:REF name="Participant">yeAzLzipb0S50RpYIsQH2gAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">vbnMU/dM+0O0vafILK/dSwAA</XPD:REF>
+<XPD:REF name="Views[1]">zdAyL2g1+0WkJ4IeOTOggQAA</XPD:REF>
+<XPD:REF name="Views[2]">ncLwP0F7NUCXrZIiSdoUHgAA</XPD:REF>
+<XPD:REF name="Views[3]">KGEeUhgfWUCyUQxhCDRf3gAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedElements[9]" type="UMLRealization" guid="x3PVKMHyJUO0m0hk6x6+8QAA">
+<XPD:REF name="Namespace">J0JbQTHSq0yi13n61FmjzgAA</XPD:REF>
+<XPD:REF name="Client">hborxSDNsk2fbR0/hWRHNgAA</XPD:REF>
+<XPD:REF name="Supplier">yeAzLzipb0S50RpYIsQH2gAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">qV4ITWMWLU6VMUw0NGujcQAA</XPD:REF>
+<XPD:REF name="Views[1]">bzqSN6R+nUuCmmCmE3g3UAAA</XPD:REF>
+<XPD:REF name="Views[2]">LoJmdkzjLE6NtolTzPHITAAA</XPD:REF>
+<XPD:REF name="Views[3]">wO7Dtbem4k2F4ew1uxznzAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedElements[10]" type="UMLRealization" guid="SVsn2qUKTEmmF2QmMwcJnAAA">
+<XPD:REF name="Namespace">J0JbQTHSq0yi13n61FmjzgAA</XPD:REF>
+<XPD:REF name="Client">S5CFGHNdFU+TPZnIr60XEAAA</XPD:REF>
+<XPD:REF name="Supplier">yeAzLzipb0S50RpYIsQH2gAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">3SoG4OJ000uW8mQ1rd9WfAAA</XPD:REF>
+<XPD:REF name="Views[1]">fdSow+ETWEizVTlugKms7wAA</XPD:REF>
+<XPD:REF name="Views[2]">PgumoRJ2pU67+WAiaOS0lwAA</XPD:REF>
+<XPD:REF name="Views[3]">4p1y9ojoTkOUrWgaa6wB7QAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedElements[11]" type="UMLPackage" guid="LaydkygZykqnLCXC9YglFgAA">
+<XPD:ATTR name="Name" type="string">fooplugin.foovalidators</XPD:ATTR>
+<XPD:REF name="Namespace">J0JbQTHSq0yi13n61FmjzgAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">1</XPD:ATTR>
+<XPD:REF name="Views[0]">qfGVeEllc0uRJYtt+gcmLQAA</XPD:REF>
+<XPD:ATTR name="#OwnedElements" type="integer">1</XPD:ATTR>
+<XPD:OBJ name="OwnedElements[0]" type="UMLClass" guid="W4OOCM1jAEK5Dgre8fmqTAAA">
+<XPD:ATTR name="Name" type="string">FooValidator</XPD:ATTR>
+<XPD:REF name="Namespace">LaydkygZykqnLCXC9YglFgAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">RMmkBo4Wy0uDlgbbF8qp9AAA</XPD:REF>
+<XPD:REF name="Views[1]">WMsOpu0SNky1x3JnGxUpCQAA</XPD:REF>
+<XPD:REF name="Views[2]">Jn5ocjLA20e+fh9gbFcRMQAA</XPD:REF>
+<XPD:REF name="Views[3]">u/dPvwRLi0iaQ3TkhlpThAAA</XPD:REF>
+<XPD:ATTR name="#ClientDependencies" type="integer">1</XPD:ATTR>
+<XPD:REF name="ClientDependencies[0]">NwUHVYoqBUydydMZ2tDe4QAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedElements[12]" type="UMLRealization" guid="NwUHVYoqBUydydMZ2tDe4QAA">
+<XPD:REF name="Namespace">J0JbQTHSq0yi13n61FmjzgAA</XPD:REF>
+<XPD:REF name="Client">W4OOCM1jAEK5Dgre8fmqTAAA</XPD:REF>
+<XPD:REF name="Supplier">yeAzLzipb0S50RpYIsQH2gAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">vTs2mU66JUuBuD3YYBowNgAA</XPD:REF>
+<XPD:REF name="Views[1]">9LpNxmfD5UaMQzxQUSzZoQAA</XPD:REF>
+<XPD:REF name="Views[2]">Q18hr5MPjE+KKV+74W27RAAA</XPD:REF>
+<XPD:REF name="Views[3]">JvIT766O7ECZQysR8GwXAQAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedElements[13]" type="UMLPackage" guid="gb1B3r/wIkeUDgFfr7dtwwAA">
+<XPD:ATTR name="Name" type="string">cone.validation.builtinvalidator.confml</XPD:ATTR>
+<XPD:REF name="Namespace">J0JbQTHSq0yi13n61FmjzgAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">1</XPD:ATTR>
+<XPD:REF name="Views[0]">sm9uFVeIzEybVzNh0ZD+ywAA</XPD:REF>
+<XPD:ATTR name="#OwnedElements" type="integer">2</XPD:ATTR>
+<XPD:OBJ name="OwnedElements[0]" type="UMLClass" guid="hborxSDNsk2fbR0/hWRHNgAA">
+<XPD:ATTR name="Name" type="string">MaxLengthValidator</XPD:ATTR>
+<XPD:REF name="Namespace">gb1B3r/wIkeUDgFfr7dtwwAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">qOPIH+pKDEWBtOJbZYgCaAAA</XPD:REF>
+<XPD:REF name="Views[1]">5U3ADC9fokmZPYm91Xd3mAAA</XPD:REF>
+<XPD:REF name="Views[2]">M4a94cLxpkGVKOxShuVFqQAA</XPD:REF>
+<XPD:REF name="Views[3]">NeV2eYQyR0aQwtSl4rhQhQAA</XPD:REF>
+<XPD:ATTR name="#ClientDependencies" type="integer">1</XPD:ATTR>
+<XPD:REF name="ClientDependencies[0]">x3PVKMHyJUO0m0hk6x6+8QAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedElements[1]" type="UMLClass" guid="S5CFGHNdFU+TPZnIr60XEAAA">
+<XPD:ATTR name="Name" type="string">MinLengthValidator</XPD:ATTR>
+<XPD:REF name="Namespace">gb1B3r/wIkeUDgFfr7dtwwAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">z9HhgfsZpk6vQG5aOdZBKQAA</XPD:REF>
+<XPD:REF name="Views[1]">gPUSt+fcikOaoH+AAheLzwAA</XPD:REF>
+<XPD:REF name="Views[2]">uOs4rEOv0UykmXnKX3W0ygAA</XPD:REF>
+<XPD:REF name="Views[3]">eGBKj40IZEGUCiX4P1z1jAAA</XPD:REF>
+<XPD:ATTR name="#ClientDependencies" type="integer">1</XPD:ATTR>
+<XPD:REF name="ClientDependencies[0]">SVsn2qUKTEmmF2QmMwcJnAAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedElements[14]" type="UMLGeneralization" guid="TFV/zVsrMESTDkTEnyr/rAAA">
+<XPD:REF name="Namespace">J0JbQTHSq0yi13n61FmjzgAA</XPD:REF>
+<XPD:REF name="Child">XjBwLw9OjEmKJ4KD8B58wgAA</XPD:REF>
+<XPD:REF name="Parent">WfkxoUbZqUOof1sQP1YufAAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">5zFd1aBYUEiaDAk+OIT1vwAA</XPD:REF>
+<XPD:REF name="Views[1]">Q1EVGEa+gEGBTfHRPHeyQwAA</XPD:REF>
+<XPD:REF name="Views[2]">V3kkj8+ppU2uUukKHuY5HAAA</XPD:REF>
+<XPD:REF name="Views[3]">DMtW4jIk1EGOUomDvZBeRQAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedElements[15]" type="UMLGeneralization" guid="sh0Wc2GWw02v4RJbRczpBwAA">
+<XPD:REF name="Namespace">J0JbQTHSq0yi13n61FmjzgAA</XPD:REF>
+<XPD:REF name="Child">w1x85nyRiUi3HLBob1jwlQAA</XPD:REF>
+<XPD:REF name="Parent">WfkxoUbZqUOof1sQP1YufAAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">9YkaGi+Za0asQQTIGIZsJAAA</XPD:REF>
+<XPD:REF name="Views[1]">/ISe8VXAX0C5S5zwkxof5AAA</XPD:REF>
+<XPD:REF name="Views[2]">lt3cB7/kRUiQtDWrTE6mSwAA</XPD:REF>
+<XPD:REF name="Views[3]">AUHGhTx7YkSkeWhJgHdmLwAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedElements[16]" type="UMLPackage" guid="Md0YIXCoWEGWJR7Ev5Wv5AAA">
+<XPD:ATTR name="Name" type="string">cone.validation.builtinvalidators.implml</XPD:ATTR>
+<XPD:REF name="Namespace">J0JbQTHSq0yi13n61FmjzgAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">1</XPD:ATTR>
+<XPD:REF name="Views[0]">oyJAaWjr+06Ztadvt0qcowAA</XPD:REF>
+<XPD:ATTR name="#OwnedElements" type="integer">1</XPD:ATTR>
+<XPD:OBJ name="OwnedElements[0]" type="UMLClass" guid="dtL6oUxsS0aPIWsKeupmrwAA">
+<XPD:ATTR name="Name" type="string">DuplicateTempFeatureRefValidator</XPD:ATTR>
+<XPD:REF name="Namespace">Md0YIXCoWEGWJR7Ev5Wv5AAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">1HH9DFhjeUaISb6w7/0iHwAA</XPD:REF>
+<XPD:REF name="Views[1]">LQOwUJ3q3U2h79vr6vuJrAAA</XPD:REF>
+<XPD:REF name="Views[2]">yZanADMD1kWito+AdZun4AAA</XPD:REF>
+<XPD:REF name="Views[3]">08EckAooiE+rkMKGjX/75wAA</XPD:REF>
+<XPD:ATTR name="#ClientDependencies" type="integer">1</XPD:ATTR>
+<XPD:REF name="ClientDependencies[0]">SYK6JJaoy0SMuQ+WSY9s/QAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedElements[17]" type="UMLRealization" guid="SYK6JJaoy0SMuQ+WSY9s/QAA">
+<XPD:REF name="Namespace">J0JbQTHSq0yi13n61FmjzgAA</XPD:REF>
+<XPD:REF name="Client">dtL6oUxsS0aPIWsKeupmrwAA</XPD:REF>
+<XPD:REF name="Supplier">w1x85nyRiUi3HLBob1jwlQAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">p+vZY5sJc0C6ZbH9zCH27wAA</XPD:REF>
+<XPD:REF name="Views[1]">OisbfBnQfEaKRdVx11hhYQAA</XPD:REF>
+<XPD:REF name="Views[2]">LkcpLPU5cUe8GPCArFisOQAA</XPD:REF>
+<XPD:REF name="Views[3]">7u2KWJKsX0Cfd7ZbbmNPMQAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedElements[1]" type="UMLModel" guid="k3+1z5eSS0aCc7wycfchUAAA">
+<XPD:ATTR name="Name" type="string">Model1_</XPD:ATTR>
+<XPD:REF name="Namespace">UgzTZtXBekmk2L7FzuhqeQAA</XPD:REF>
+<XPD:ATTR name="#OwnedDiagrams" type="integer">1</XPD:ATTR>
+<XPD:OBJ name="OwnedDiagrams[0]" type="UMLClassDiagram" guid="Vg1IlfHoukmfbJx8/sW/jgAA">
+<XPD:ATTR name="Name" type="string">ExceptionHierarchy</XPD:ATTR>
+<XPD:REF name="DiagramOwner">k3+1z5eSS0aCc7wycfchUAAA</XPD:REF>
+<XPD:OBJ name="DiagramView" type="UMLClassDiagramView" guid="Vn3GyQ/iNk6+DeeNdnvokAAA">
+<XPD:REF name="Diagram">Vg1IlfHoukmfbJx8/sW/jgAA</XPD:REF>
+<XPD:ATTR name="#OwnedViews" type="integer">35</XPD:ATTR>
+<XPD:OBJ name="OwnedViews[0]" type="UMLClassView" guid="xtxslIAJy0CgGPVXL9z0lwAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">228</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">84</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">93</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">95</XPD:ATTR>
+<XPD:REF name="Model">CpCtdq7WY0mJ2Yw3xLfP6wAA</XPD:REF>
+<XPD:OBJ name="NameCompartment" type="UMLNameCompartmentView" guid="KPNXi3GpaE+12SyUVqOpwwAA">
+<XPD:OBJ name="NameLabel" type="LabelView" guid="I5Y2Y7D3ik6KDnO1skLTgwAA">
+<XPD:ATTR name="FontStyle" type="integer">1</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">ConeException</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="LabelView" guid="tUsvHa7Ia0OTfRWVHTk3VwAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="LabelView" guid="AD9Mp1nDLEevdIKPTSBkDwAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="AttributeCompartment" type="UMLAttributeCompartmentView" guid="RluVbyxCt0eQNOSNQk/mOAAA">
+<XPD:REF name="Model">CpCtdq7WY0mJ2Yw3xLfP6wAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OperationCompartment" type="UMLOperationCompartmentView" guid="vk1ty4gEUkOI0VMbKTvtuAAA">
+<XPD:REF name="Model">CpCtdq7WY0mJ2Yw3xLfP6wAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TemplateParameterCompartment" type="UMLTemplateParameterCompartmentView" guid="3jNopHqYBUSqUDjX1lLAngAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:REF name="Model">CpCtdq7WY0mJ2Yw3xLfP6wAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[1]" type="UMLClassView" guid="8gEuzA+nTkK36m0ICWvjogAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">320</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">264</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">80</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">43</XPD:ATTR>
+<XPD:REF name="Model">WWb6aySf10m9HwLKW3GB1QAA</XPD:REF>
+<XPD:OBJ name="NameCompartment" type="UMLNameCompartmentView" guid="EUfsiEbaDU+3q4lOpjTsQAAA">
+<XPD:OBJ name="NameLabel" type="LabelView" guid="W2+brokclEuw7TuANjn1xQAA">
+<XPD:ATTR name="FontStyle" type="integer">1</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">ParseError</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="LabelView" guid="ZrVfmGR1AUKJHr4CTyYJhAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="LabelView" guid="Rl00JfYfZ0eonou6uPCw2gAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="AttributeCompartment" type="UMLAttributeCompartmentView" guid="r+Z/xX5IGEqLzb6SNdTfjAAA">
+<XPD:REF name="Model">WWb6aySf10m9HwLKW3GB1QAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OperationCompartment" type="UMLOperationCompartmentView" guid="ysZRQWJOnUKg77Wyu8QqowAA">
+<XPD:REF name="Model">WWb6aySf10m9HwLKW3GB1QAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TemplateParameterCompartment" type="UMLTemplateParameterCompartmentView" guid="ykLLApl4X0GrGo5gT/GYxgAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:REF name="Model">WWb6aySf10m9HwLKW3GB1QAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[2]" type="UMLClassView" guid="P7XYUAivPkyiZfqkmJZTdQAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">344</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">340</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">91</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">43</XPD:ATTR>
+<XPD:REF name="Model">7RmjflOgQEaQYY1KEcdIdwAA</XPD:REF>
+<XPD:OBJ name="NameCompartment" type="UMLNameCompartmentView" guid="rr5y2+gIsUeNVnGNM5IMFwAA">
+<XPD:OBJ name="NameLabel" type="LabelView" guid="Jb5p4PNTjUSV7dlCDVUpdgAA">
+<XPD:ATTR name="FontStyle" type="integer">1</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">XmlParseError</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="LabelView" guid="fVIA/uC5wkmGgzGg5xvSsgAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="LabelView" guid="Qr0saGrYPkm2kzaf+QlzGQAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="AttributeCompartment" type="UMLAttributeCompartmentView" guid="P+xdKH0iJk+BKxNaC/XksQAA">
+<XPD:REF name="Model">7RmjflOgQEaQYY1KEcdIdwAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OperationCompartment" type="UMLOperationCompartmentView" guid="yYyOQgqeC0OhH+tV8BkOzQAA">
+<XPD:REF name="Model">7RmjflOgQEaQYY1KEcdIdwAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TemplateParameterCompartment" type="UMLTemplateParameterCompartmentView" guid="027y9BBw1Ey4+cWdxjA6YAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:REF name="Model">7RmjflOgQEaQYY1KEcdIdwAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[3]" type="UMLClassView" guid="HaeqtHPbakqRfaLbF6CwpwAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">364</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">428</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">110</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">43</XPD:ATTR>
+<XPD:REF name="Model">Cw3u9C6Qt0iw1URnTduBSQAA</XPD:REF>
+<XPD:OBJ name="NameCompartment" type="UMLNameCompartmentView" guid="5fPmhrN2f0WYBRUN4LOvFAAA">
+<XPD:OBJ name="NameLabel" type="LabelView" guid="gp7sCrvOwE+lDG6hss0QugAA">
+<XPD:ATTR name="FontStyle" type="integer">1</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">ImplmlParseError</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="LabelView" guid="TajUf5QMZE6S1hwzNArIhwAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="LabelView" guid="/m51lu4cLU6/3A740L9ZPwAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="AttributeCompartment" type="UMLAttributeCompartmentView" guid="PGpsrNfvsES6ELZtPdnjDQAA">
+<XPD:REF name="Model">Cw3u9C6Qt0iw1URnTduBSQAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OperationCompartment" type="UMLOperationCompartmentView" guid="PjQLjDTFXUKcCeZZ9KvnVAAA">
+<XPD:REF name="Model">Cw3u9C6Qt0iw1URnTduBSQAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TemplateParameterCompartment" type="UMLTemplateParameterCompartmentView" guid="BwFC2YYWrkqriY5YQ79YOAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:REF name="Model">Cw3u9C6Qt0iw1URnTduBSQAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[4]" type="UMLClassView" guid="dwomj5YP7kGwFoltp6sFMgAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">228</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">428</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">109</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">43</XPD:ATTR>
+<XPD:REF name="Model">9WnQ1vjaiU+SCF/1UtuV2AAA</XPD:REF>
+<XPD:OBJ name="NameCompartment" type="UMLNameCompartmentView" guid="rlfLHyR6/UiX7z84KXYU+wAA">
+<XPD:OBJ name="NameLabel" type="LabelView" guid="dAAwShNgA0CJwzmVgJN05AAA">
+<XPD:ATTR name="FontStyle" type="integer">1</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">ConfmlParseError</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="LabelView" guid="oxcYO7s1W02zsflfM/DoCgAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="LabelView" guid="Ngt+pak5QUOuZgIT4s/9TgAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="AttributeCompartment" type="UMLAttributeCompartmentView" guid="jDNhce0FjkCT+X8T2sj7jgAA">
+<XPD:REF name="Model">9WnQ1vjaiU+SCF/1UtuV2AAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OperationCompartment" type="UMLOperationCompartmentView" guid="bGGyEwnscE6wXcks12dpygAA">
+<XPD:REF name="Model">9WnQ1vjaiU+SCF/1UtuV2AAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TemplateParameterCompartment" type="UMLTemplateParameterCompartmentView" guid="HQvspPLLBkKpV7E7VJXw5QAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:REF name="Model">9WnQ1vjaiU+SCF/1UtuV2AAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[5]" type="UMLGeneralizationView" guid="DEzFmZHWVkiVKVUlFGwr5wAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Points" type="Points">381,340;367,306</XPD:ATTR>
+<XPD:REF name="Model">BVm0I2jH00SRoMbHM39nRgAA</XPD:REF>
+<XPD:REF name="Head">8gEuzA+nTkK36m0ICWvjogAA</XPD:REF>
+<XPD:REF name="Tail">P7XYUAivPkyiZfqkmJZTdQAA</XPD:REF>
+<XPD:OBJ name="NameLabel" type="EdgeLabelView" guid="/zt+BmkJbk+chHMIAbJzqwAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">15</XPD:ATTR>
+<XPD:REF name="Model">BVm0I2jH00SRoMbHM39nRgAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="EdgeLabelView" guid="1eIkm9jR80uLOi1Y+t12mgAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">30</XPD:ATTR>
+<XPD:REF name="Model">BVm0I2jH00SRoMbHM39nRgAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="EdgeLabelView" guid="VwvCh8vDck+wTVaOAHHCnAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">-1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">15</XPD:ATTR>
+<XPD:REF name="Model">BVm0I2jH00SRoMbHM39nRgAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[6]" type="UMLGeneralizationView" guid="1xq22E+bLkGOtw6Io0Y6wAAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Points" type="Points">411,428;396,382</XPD:ATTR>
+<XPD:REF name="Model">LLUDbllKq02VrT7YfbfAtwAA</XPD:REF>
+<XPD:REF name="Head">P7XYUAivPkyiZfqkmJZTdQAA</XPD:REF>
+<XPD:REF name="Tail">HaeqtHPbakqRfaLbF6CwpwAA</XPD:REF>
+<XPD:OBJ name="NameLabel" type="EdgeLabelView" guid="FfbUNjmFokylSXVU5+M71QAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">15</XPD:ATTR>
+<XPD:REF name="Model">LLUDbllKq02VrT7YfbfAtwAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="EdgeLabelView" guid="Pl72SYHpc0u2FANSnb80PQAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">30</XPD:ATTR>
+<XPD:REF name="Model">LLUDbllKq02VrT7YfbfAtwAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="EdgeLabelView" guid="KUN4dttJJki7GZhFn7yfAAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">-1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">15</XPD:ATTR>
+<XPD:REF name="Model">LLUDbllKq02VrT7YfbfAtwAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[7]" type="UMLGeneralizationView" guid="QaUC3xuE6kO01J9qUWDYjAAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Points" type="Points">308,428;364,382</XPD:ATTR>
+<XPD:REF name="Model">gpkLumrZqE2iroonUSQ5qwAA</XPD:REF>
+<XPD:REF name="Head">P7XYUAivPkyiZfqkmJZTdQAA</XPD:REF>
+<XPD:REF name="Tail">dwomj5YP7kGwFoltp6sFMgAA</XPD:REF>
+<XPD:OBJ name="NameLabel" type="EdgeLabelView" guid="Lh8b67cFIE2AMq1mE7zVuAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">15</XPD:ATTR>
+<XPD:REF name="Model">gpkLumrZqE2iroonUSQ5qwAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="EdgeLabelView" guid="sS12Nr1Xc0CezbuWSHeXmAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">30</XPD:ATTR>
+<XPD:REF name="Model">gpkLumrZqE2iroonUSQ5qwAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="EdgeLabelView" guid="IxYe2zQoG0CC0N8xyyiXaQAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">-1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">15</XPD:ATTR>
+<XPD:REF name="Model">gpkLumrZqE2iroonUSQ5qwAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[8]" type="UMLClassView" guid="4MOFx6CJ7E+9t6vpLk2hfAAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">136</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">260</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">160</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">43</XPD:ATTR>
+<XPD:REF name="Model">LYT5nNubLU21hr+9lFCjagAA</XPD:REF>
+<XPD:OBJ name="NameCompartment" type="UMLNameCompartmentView" guid="8IJSoxS5YE+o45WR+LAH2wAA">
+<XPD:OBJ name="NameLabel" type="LabelView" guid="Bbl/cI14N0KdjDRulbxJ+wAA">
+<XPD:ATTR name="FontStyle" type="integer">1</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">XmlSchemaValidationError</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="LabelView" guid="1eQJjiTFt0WAPUkreSLFowAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="LabelView" guid="NXXyqAmXbkyP7CdzRygmIAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="AttributeCompartment" type="UMLAttributeCompartmentView" guid="pKg3xC3EoECOqH1DKTcw1gAA">
+<XPD:REF name="Model">LYT5nNubLU21hr+9lFCjagAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OperationCompartment" type="UMLOperationCompartmentView" guid="0IN/57AxKkW9S1a24KVqrwAA">
+<XPD:REF name="Model">LYT5nNubLU21hr+9lFCjagAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TemplateParameterCompartment" type="UMLTemplateParameterCompartmentView" guid="HfxuFaSr+kWSC9RMs2DGrgAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:REF name="Model">LYT5nNubLU21hr+9lFCjagAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[9]" type="UMLClassView" guid="Xf++UZDQF0KMRcUTaXRTRQAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">468</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">112</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">101</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">121</XPD:ATTR>
+<XPD:REF name="Model">nW6zFgSSY0WITaYT3YtvmQAA</XPD:REF>
+<XPD:OBJ name="NameCompartment" type="UMLNameCompartmentView" guid="Yego/sS8AUy7qk3hKAjyPwAA">
+<XPD:OBJ name="NameLabel" type="LabelView" guid="zo269AQv/UGd+lV4CmP50QAA">
+<XPD:ATTR name="FontStyle" type="integer">1</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">Problem</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="LabelView" guid="gNg+4dZKgkqdq/X/vdAHvQAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="LabelView" guid="ZTVNOgcyl0+2xwqVJwWg0wAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="AttributeCompartment" type="UMLAttributeCompartmentView" guid="xGJmIZm9LUmVsEUJd0LzcQAA">
+<XPD:REF name="Model">nW6zFgSSY0WITaYT3YtvmQAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OperationCompartment" type="UMLOperationCompartmentView" guid="ksBzPPYQuEmMjRKqH71jMAAA">
+<XPD:REF name="Model">nW6zFgSSY0WITaYT3YtvmQAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TemplateParameterCompartment" type="UMLTemplateParameterCompartmentView" guid="DI543AOKrUuhdWGU4HBgswAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:REF name="Model">nW6zFgSSY0WITaYT3YtvmQAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[10]" type="UMLNoteView" guid="2Z9yQrE9zUGGKAsClGiDQQAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">72</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">124</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">125</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">23</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">Problem type: generic
+</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[11]" type="UMLNoteView" guid="upmGcLte/EODbeZ/V/XS3AAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">492</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">400</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">87</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">68</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">Problem type:
+xml
+xml.confml
+xml.implml
+</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[12]" type="UMLNoteView" guid="ESA/vgQhRkavFLeS7xjUTgAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">492</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">488</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">150</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">30</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">Problem type: model.implml
+</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[13]" type="UMLNoteView" guid="6py8ZMKbPkGRCatUH8+yJgAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">108</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">524</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">153</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">30</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">Problem type: model.confml
+</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[14]" type="UMLNoteView" guid="w/KYdX2JD0akKYHVVWzOFwAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">96</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">320</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">91</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">53</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">Problem type:
+schema.confml
+schema.implml
+</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[15]" type="UMLNoteView" guid="pE1PBoTUuEihwSO/6zZ1xQAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">432</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">12</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">254</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">68</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">Example Problem object:
+msg = AttributeError: 'object' has no attribute 'x'
+line = None
+type = generic
+</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[16]" type="UMLNoteView" guid="WrkAc4o+9Em99gEWWKk3RQAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">596</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">344</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">218</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">68</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">Example Problem object:
+msg = no element found: line 1, column 0
+line = 1
+type = xml
+</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[17]" type="UMLClassView" guid="ycmoHebIUkeHupzKOsY0GgAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">232</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">12</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">90</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">43</XPD:ATTR>
+<XPD:REF name="Model">rf6UykFPpkeu7c421sgazQAA</XPD:REF>
+<XPD:OBJ name="NameCompartment" type="UMLNameCompartmentView" guid="YGdCL26Kf064uLfDCix4lQAA">
+<XPD:OBJ name="NameLabel" type="LabelView" guid="Egccq252nUuvCqJGplUW2wAA">
+<XPD:ATTR name="FontStyle" type="integer">1</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">Exception</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="LabelView" guid="Li1wDPmyP0uvhnHX2wkIlAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="LabelView" guid="+xXWHjCjk06+ao9rWSDonAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="AttributeCompartment" type="UMLAttributeCompartmentView" guid="kaDas08xSUSwaF3Qo0nanwAA">
+<XPD:REF name="Model">rf6UykFPpkeu7c421sgazQAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OperationCompartment" type="UMLOperationCompartmentView" guid="vdo9HscXSkeF0cX4MnGddgAA">
+<XPD:REF name="Model">rf6UykFPpkeu7c421sgazQAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TemplateParameterCompartment" type="UMLTemplateParameterCompartmentView" guid="NhZBPUXvf0iw2VkM+GMpnAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:REF name="Model">rf6UykFPpkeu7c421sgazQAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[18]" type="UMLGeneralizationView" guid="dSXjIJ9YUE2CX+onbmfhGgAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Points" type="Points">275,84;276,54</XPD:ATTR>
+<XPD:REF name="Model">XStsjSJBDk+s2L22GVmGfQAA</XPD:REF>
+<XPD:REF name="Head">ycmoHebIUkeHupzKOsY0GgAA</XPD:REF>
+<XPD:REF name="Tail">xtxslIAJy0CgGPVXL9z0lwAA</XPD:REF>
+<XPD:OBJ name="NameLabel" type="EdgeLabelView" guid="yoUriE7jSEeYmCUlxujIIwAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">15</XPD:ATTR>
+<XPD:REF name="Model">XStsjSJBDk+s2L22GVmGfQAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="EdgeLabelView" guid="AZ60xT26CEKYZqbO16ljaAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">30</XPD:ATTR>
+<XPD:REF name="Model">XStsjSJBDk+s2L22GVmGfQAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="EdgeLabelView" guid="b+RDR1+nHUG8DCzD022LUQAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">-1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">15</XPD:ATTR>
+<XPD:REF name="Model">XStsjSJBDk+s2L22GVmGfQAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[19]" type="UMLNoteLinkView" guid="aQhDgyuaxEWDdq5snrrJKwAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Points" type="Points">191,302;171,320</XPD:ATTR>
+<XPD:REF name="Head">w/KYdX2JD0akKYHVVWzOFwAA</XPD:REF>
+<XPD:REF name="Tail">4MOFx6CJ7E+9t6vpLk2hfAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[20]" type="UMLNoteLinkView" guid="HrRNVZzgv06EcL37TdizrwAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Points" type="Points">432,382;492,412</XPD:ATTR>
+<XPD:REF name="Head">upmGcLte/EODbeZ/V/XS3AAA</XPD:REF>
+<XPD:REF name="Tail">P7XYUAivPkyiZfqkmJZTdQAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[21]" type="UMLNoteLinkView" guid="t3c/+/XXc0W4si4zvwut2wAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Points" type="Points">259,470;199,524</XPD:ATTR>
+<XPD:REF name="Head">6py8ZMKbPkGRCatUH8+yJgAA</XPD:REF>
+<XPD:REF name="Tail">dwomj5YP7kGwFoltp6sFMgAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[22]" type="UMLNoteLinkView" guid="5Skbi3mc00qSPVdg2+MiTwAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Points" type="Points">473,469;527,488</XPD:ATTR>
+<XPD:REF name="Head">ESA/vgQhRkavFLeS7xjUTgAA</XPD:REF>
+<XPD:REF name="Tail">HaeqtHPbakqRfaLbF6CwpwAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[23]" type="UMLNoteView" guid="uljCIGZb00u9fKL/uJvnCQAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">608</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">152</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">153</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">68</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">The Problem class offers a
+class method for creating a
+Problem object based on an
+exception
+</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[24]" type="UMLNoteLinkView" guid="Cp7hImQbi02UuSMwA2/lTwAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Points" type="Points">568,176;608,179</XPD:ATTR>
+<XPD:REF name="Head">uljCIGZb00u9fKL/uJvnCQAA</XPD:REF>
+<XPD:REF name="Tail">Xf++UZDQF0KMRcUTaXRTRQAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[25]" type="UMLNoteView" guid="aaMMwnwWZE+gAFJiCuYz9gAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">464</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">248</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">215</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">83</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">A Problem can be created from
+any exception, but if the exception class
+inherits ConeException, it may contain
+more relevant information than a
+regular exception
+</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[26]" type="UMLNoteLinkView" guid="wVmuGHUDjEaviubju+9jKwAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Points" type="Points">545,232;552,248</XPD:ATTR>
+<XPD:REF name="Head">aaMMwnwWZE+gAFJiCuYz9gAA</XPD:REF>
+<XPD:REF name="Tail">Xf++UZDQF0KMRcUTaXRTRQAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[27]" type="UMLNoteLinkView" guid="zM6SVBoIqECrQR/SHrxJtAAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Points" type="Points">321,35;432,40</XPD:ATTR>
+<XPD:REF name="Head">pE1PBoTUuEihwSO/6zZ1xQAA</XPD:REF>
+<XPD:REF name="Tail">ycmoHebIUkeHupzKOsY0GgAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[28]" type="UMLNoteLinkView" guid="O8/xB2/lz0aaS8oHi0Ai0AAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Points" type="Points">434,363;596,371</XPD:ATTR>
+<XPD:REF name="Head">WrkAc4o+9Em99gEWWKk3RQAA</XPD:REF>
+<XPD:REF name="Tail">P7XYUAivPkyiZfqkmJZTdQAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[29]" type="UMLClassView" guid="ciGDbr0BfUil+uQUIDeXQQAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">416</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">524</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">96</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">43</XPD:ATTR>
+<XPD:REF name="Model">0F4w8SQAhU6PQs5Ym0CzEAAA</XPD:REF>
+<XPD:OBJ name="NameCompartment" type="UMLNameCompartmentView" guid="dK6g74gAUUGRQPQY4A0mewAA">
+<XPD:OBJ name="NameLabel" type="LabelView" guid="eeKlSMq8iU2hJ2jPobVMpgAA">
+<XPD:ATTR name="FontStyle" type="integer">1</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">CrmlParseError</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="LabelView" guid="wMIBUXPJnkWXr6rCItk/5QAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="LabelView" guid="trvUZXrcK0KQxxTm5Nez4QAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="AttributeCompartment" type="UMLAttributeCompartmentView" guid="CPVoTDN5oEGoCR2LZrM2KwAA">
+<XPD:REF name="Model">0F4w8SQAhU6PQs5Ym0CzEAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OperationCompartment" type="UMLOperationCompartmentView" guid="5TxAVUuD/06c2nmBaYwLRAAA">
+<XPD:REF name="Model">0F4w8SQAhU6PQs5Ym0CzEAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TemplateParameterCompartment" type="UMLTemplateParameterCompartmentView" guid="szEqhCsiVE65lCiPPYS8OwAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:REF name="Model">0F4w8SQAhU6PQs5Ym0CzEAAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[30]" type="UMLGeneralizationView" guid="g9lNCCdLNE2rVWwg8oKFlQAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Points" type="Points">453,524;428,470</XPD:ATTR>
+<XPD:REF name="Model">B+b9kyKZoUiNPA0amRmuuwAA</XPD:REF>
+<XPD:REF name="Head">HaeqtHPbakqRfaLbF6CwpwAA</XPD:REF>
+<XPD:REF name="Tail">ciGDbr0BfUil+uQUIDeXQQAA</XPD:REF>
+<XPD:OBJ name="NameLabel" type="EdgeLabelView" guid="qQxCbD8bPkm1RzefpboXbwAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">15</XPD:ATTR>
+<XPD:REF name="Model">B+b9kyKZoUiNPA0amRmuuwAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="EdgeLabelView" guid="knY2vp+HL02Rl2Fy2DYaOAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">30</XPD:ATTR>
+<XPD:REF name="Model">B+b9kyKZoUiNPA0amRmuuwAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="EdgeLabelView" guid="NfHUtnHoW06wP1ZpBMH2dgAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">-1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">15</XPD:ATTR>
+<XPD:REF name="Model">B+b9kyKZoUiNPA0amRmuuwAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[31]" type="UMLNoteView" guid="SEQV+AMRRkakyiujQzFiDwAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">548</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">532</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">173</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">30</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">Problem type: model.implml.crml
+</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[32]" type="UMLNoteLinkView" guid="4Pp/sxLWokiSsvRZ/7VrfwAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Points" type="Points">511,545;548,545</XPD:ATTR>
+<XPD:REF name="Head">SEQV+AMRRkakyiujQzFiDwAA</XPD:REF>
+<XPD:REF name="Tail">ciGDbr0BfUil+uQUIDeXQQAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[33]" type="UMLGeneralizationView" guid="Y3Nmw6b48ES7XMYmOgDkcQAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Points" type="Points">223,260;255,178</XPD:ATTR>
+<XPD:REF name="Model">qQ54GGA4DEWmPw3Ix0jbCQAA</XPD:REF>
+<XPD:REF name="Head">xtxslIAJy0CgGPVXL9z0lwAA</XPD:REF>
+<XPD:REF name="Tail">4MOFx6CJ7E+9t6vpLk2hfAAA</XPD:REF>
+<XPD:OBJ name="NameLabel" type="EdgeLabelView" guid="BV6s2EtNyU2NIwJrOCKEsgAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">15</XPD:ATTR>
+<XPD:REF name="Model">qQ54GGA4DEWmPw3Ix0jbCQAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="EdgeLabelView" guid="f0AOhRp8y0aAenoFW5fAEwAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">30</XPD:ATTR>
+<XPD:REF name="Model">qQ54GGA4DEWmPw3Ix0jbCQAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="EdgeLabelView" guid="xeqe/1TQFUSBF0zLR7uPSAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">-1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">15</XPD:ATTR>
+<XPD:REF name="Model">qQ54GGA4DEWmPw3Ix0jbCQAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[34]" type="UMLGeneralizationView" guid="lzTahw8af0mMhES17c0s7gAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Points" type="Points">347,264;300,178</XPD:ATTR>
+<XPD:REF name="Model">hrAhTmhhzUqPv4OZuUD93AAA</XPD:REF>
+<XPD:REF name="Head">xtxslIAJy0CgGPVXL9z0lwAA</XPD:REF>
+<XPD:REF name="Tail">8gEuzA+nTkK36m0ICWvjogAA</XPD:REF>
+<XPD:OBJ name="NameLabel" type="EdgeLabelView" guid="a5ldPk/cF0SEFRsmjO7EzQAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">15</XPD:ATTR>
+<XPD:REF name="Model">hrAhTmhhzUqPv4OZuUD93AAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="EdgeLabelView" guid="ujixESozM0WHAPa6R9/0NAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">30</XPD:ATTR>
+<XPD:REF name="Model">hrAhTmhhzUqPv4OZuUD93AAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="EdgeLabelView" guid="EcDaxMOyA0ecgSslQ7x4lwAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">-1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">15</XPD:ATTR>
+<XPD:REF name="Model">hrAhTmhhzUqPv4OZuUD93AAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:ATTR name="#OwnedElements" type="integer">16</XPD:ATTR>
+<XPD:OBJ name="OwnedElements[0]" type="UMLClass" guid="CpCtdq7WY0mJ2Yw3xLfP6wAA">
+<XPD:ATTR name="Name" type="string">ConeException</XPD:ATTR>
+<XPD:REF name="Namespace">k3+1z5eSS0aCc7wycfchUAAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">xtxslIAJy0CgGPVXL9z0lwAA</XPD:REF>
+<XPD:REF name="Views[1]">RluVbyxCt0eQNOSNQk/mOAAA</XPD:REF>
+<XPD:REF name="Views[2]">vk1ty4gEUkOI0VMbKTvtuAAA</XPD:REF>
+<XPD:REF name="Views[3]">3jNopHqYBUSqUDjX1lLAngAA</XPD:REF>
+<XPD:ATTR name="#Generalizations" type="integer">1</XPD:ATTR>
+<XPD:REF name="Generalizations[0]">XStsjSJBDk+s2L22GVmGfQAA</XPD:REF>
+<XPD:ATTR name="#Specializations" type="integer">2</XPD:ATTR>
+<XPD:REF name="Specializations[0]">qQ54GGA4DEWmPw3Ix0jbCQAA</XPD:REF>
+<XPD:REF name="Specializations[1]">hrAhTmhhzUqPv4OZuUD93AAA</XPD:REF>
+<XPD:ATTR name="#Attributes" type="integer">4</XPD:ATTR>
+<XPD:OBJ name="Attributes[0]" type="UMLAttribute" guid="fmijBXpGWEutl22vw3SS7QAA">
+<XPD:ATTR name="Name" type="string">lineno</XPD:ATTR>
+<XPD:REF name="Owner">CpCtdq7WY0mJ2Yw3xLfP6wAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="Attributes[1]" type="UMLAttribute" guid="VXcV+pBvZkGw5MPpzruBJQAA">
+<XPD:ATTR name="Name" type="string">desc</XPD:ATTR>
+<XPD:REF name="Owner">CpCtdq7WY0mJ2Yw3xLfP6wAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="Attributes[2]" type="UMLAttribute" guid="m/kve2KeZkOdCqXW9m3SxgAA">
+<XPD:ATTR name="Name" type="string">problem_type</XPD:ATTR>
+<XPD:REF name="Owner">CpCtdq7WY0mJ2Yw3xLfP6wAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="Attributes[3]" type="UMLAttribute" guid="QfSB6TtaQ0ejVKcpUTRlyAAA">
+<XPD:ATTR name="Name" type="string">file</XPD:ATTR>
+<XPD:REF name="Owner">CpCtdq7WY0mJ2Yw3xLfP6wAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedElements[1]" type="UMLClass" guid="WWb6aySf10m9HwLKW3GB1QAA">
+<XPD:ATTR name="Name" type="string">ParseError</XPD:ATTR>
+<XPD:REF name="Namespace">k3+1z5eSS0aCc7wycfchUAAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">8gEuzA+nTkK36m0ICWvjogAA</XPD:REF>
+<XPD:REF name="Views[1]">r+Z/xX5IGEqLzb6SNdTfjAAA</XPD:REF>
+<XPD:REF name="Views[2]">ysZRQWJOnUKg77Wyu8QqowAA</XPD:REF>
+<XPD:REF name="Views[3]">ykLLApl4X0GrGo5gT/GYxgAA</XPD:REF>
+<XPD:ATTR name="#Generalizations" type="integer">1</XPD:ATTR>
+<XPD:REF name="Generalizations[0]">hrAhTmhhzUqPv4OZuUD93AAA</XPD:REF>
+<XPD:ATTR name="#Specializations" type="integer">1</XPD:ATTR>
+<XPD:REF name="Specializations[0]">BVm0I2jH00SRoMbHM39nRgAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedElements[2]" type="UMLClass" guid="7RmjflOgQEaQYY1KEcdIdwAA">
+<XPD:ATTR name="Name" type="string">XmlParseError</XPD:ATTR>
+<XPD:REF name="Namespace">k3+1z5eSS0aCc7wycfchUAAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">P7XYUAivPkyiZfqkmJZTdQAA</XPD:REF>
+<XPD:REF name="Views[1]">P+xdKH0iJk+BKxNaC/XksQAA</XPD:REF>
+<XPD:REF name="Views[2]">yYyOQgqeC0OhH+tV8BkOzQAA</XPD:REF>
+<XPD:REF name="Views[3]">027y9BBw1Ey4+cWdxjA6YAAA</XPD:REF>
+<XPD:ATTR name="#Generalizations" type="integer">1</XPD:ATTR>
+<XPD:REF name="Generalizations[0]">BVm0I2jH00SRoMbHM39nRgAA</XPD:REF>
+<XPD:ATTR name="#Specializations" type="integer">2</XPD:ATTR>
+<XPD:REF name="Specializations[0]">LLUDbllKq02VrT7YfbfAtwAA</XPD:REF>
+<XPD:REF name="Specializations[1]">gpkLumrZqE2iroonUSQ5qwAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedElements[3]" type="UMLClass" guid="Cw3u9C6Qt0iw1URnTduBSQAA">
+<XPD:ATTR name="Name" type="string">ImplmlParseError</XPD:ATTR>
+<XPD:REF name="Namespace">k3+1z5eSS0aCc7wycfchUAAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">HaeqtHPbakqRfaLbF6CwpwAA</XPD:REF>
+<XPD:REF name="Views[1]">PGpsrNfvsES6ELZtPdnjDQAA</XPD:REF>
+<XPD:REF name="Views[2]">PjQLjDTFXUKcCeZZ9KvnVAAA</XPD:REF>
+<XPD:REF name="Views[3]">BwFC2YYWrkqriY5YQ79YOAAA</XPD:REF>
+<XPD:ATTR name="#Generalizations" type="integer">1</XPD:ATTR>
+<XPD:REF name="Generalizations[0]">LLUDbllKq02VrT7YfbfAtwAA</XPD:REF>
+<XPD:ATTR name="#Specializations" type="integer">1</XPD:ATTR>
+<XPD:REF name="Specializations[0]">B+b9kyKZoUiNPA0amRmuuwAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedElements[4]" type="UMLClass" guid="9WnQ1vjaiU+SCF/1UtuV2AAA">
+<XPD:ATTR name="Name" type="string">ConfmlParseError</XPD:ATTR>
+<XPD:REF name="Namespace">k3+1z5eSS0aCc7wycfchUAAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">dwomj5YP7kGwFoltp6sFMgAA</XPD:REF>
+<XPD:REF name="Views[1]">jDNhce0FjkCT+X8T2sj7jgAA</XPD:REF>
+<XPD:REF name="Views[2]">bGGyEwnscE6wXcks12dpygAA</XPD:REF>
+<XPD:REF name="Views[3]">HQvspPLLBkKpV7E7VJXw5QAA</XPD:REF>
+<XPD:ATTR name="#Generalizations" type="integer">1</XPD:ATTR>
+<XPD:REF name="Generalizations[0]">gpkLumrZqE2iroonUSQ5qwAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedElements[5]" type="UMLGeneralization" guid="BVm0I2jH00SRoMbHM39nRgAA">
+<XPD:REF name="Namespace">k3+1z5eSS0aCc7wycfchUAAA</XPD:REF>
+<XPD:REF name="Child">7RmjflOgQEaQYY1KEcdIdwAA</XPD:REF>
+<XPD:REF name="Parent">WWb6aySf10m9HwLKW3GB1QAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">DEzFmZHWVkiVKVUlFGwr5wAA</XPD:REF>
+<XPD:REF name="Views[1]">/zt+BmkJbk+chHMIAbJzqwAA</XPD:REF>
+<XPD:REF name="Views[2]">1eIkm9jR80uLOi1Y+t12mgAA</XPD:REF>
+<XPD:REF name="Views[3]">VwvCh8vDck+wTVaOAHHCnAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedElements[6]" type="UMLGeneralization" guid="LLUDbllKq02VrT7YfbfAtwAA">
+<XPD:REF name="Namespace">k3+1z5eSS0aCc7wycfchUAAA</XPD:REF>
+<XPD:REF name="Child">Cw3u9C6Qt0iw1URnTduBSQAA</XPD:REF>
+<XPD:REF name="Parent">7RmjflOgQEaQYY1KEcdIdwAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">1xq22E+bLkGOtw6Io0Y6wAAA</XPD:REF>
+<XPD:REF name="Views[1]">FfbUNjmFokylSXVU5+M71QAA</XPD:REF>
+<XPD:REF name="Views[2]">Pl72SYHpc0u2FANSnb80PQAA</XPD:REF>
+<XPD:REF name="Views[3]">KUN4dttJJki7GZhFn7yfAAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedElements[7]" type="UMLGeneralization" guid="gpkLumrZqE2iroonUSQ5qwAA">
+<XPD:REF name="Namespace">k3+1z5eSS0aCc7wycfchUAAA</XPD:REF>
+<XPD:REF name="Child">9WnQ1vjaiU+SCF/1UtuV2AAA</XPD:REF>
+<XPD:REF name="Parent">7RmjflOgQEaQYY1KEcdIdwAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">QaUC3xuE6kO01J9qUWDYjAAA</XPD:REF>
+<XPD:REF name="Views[1]">Lh8b67cFIE2AMq1mE7zVuAAA</XPD:REF>
+<XPD:REF name="Views[2]">sS12Nr1Xc0CezbuWSHeXmAAA</XPD:REF>
+<XPD:REF name="Views[3]">IxYe2zQoG0CC0N8xyyiXaQAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedElements[8]" type="UMLClass" guid="LYT5nNubLU21hr+9lFCjagAA">
+<XPD:ATTR name="Name" type="string">XmlSchemaValidationError</XPD:ATTR>
+<XPD:REF name="Namespace">k3+1z5eSS0aCc7wycfchUAAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">4MOFx6CJ7E+9t6vpLk2hfAAA</XPD:REF>
+<XPD:REF name="Views[1]">pKg3xC3EoECOqH1DKTcw1gAA</XPD:REF>
+<XPD:REF name="Views[2]">0IN/57AxKkW9S1a24KVqrwAA</XPD:REF>
+<XPD:REF name="Views[3]">HfxuFaSr+kWSC9RMs2DGrgAA</XPD:REF>
+<XPD:ATTR name="#Generalizations" type="integer">1</XPD:ATTR>
+<XPD:REF name="Generalizations[0]">qQ54GGA4DEWmPw3Ix0jbCQAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedElements[9]" type="UMLClass" guid="nW6zFgSSY0WITaYT3YtvmQAA">
+<XPD:ATTR name="Name" type="string">Problem</XPD:ATTR>
+<XPD:REF name="Namespace">k3+1z5eSS0aCc7wycfchUAAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">Xf++UZDQF0KMRcUTaXRTRQAA</XPD:REF>
+<XPD:REF name="Views[1]">xGJmIZm9LUmVsEUJd0LzcQAA</XPD:REF>
+<XPD:REF name="Views[2]">ksBzPPYQuEmMjRKqH71jMAAA</XPD:REF>
+<XPD:REF name="Views[3]">DI543AOKrUuhdWGU4HBgswAA</XPD:REF>
+<XPD:ATTR name="#Operations" type="integer">1</XPD:ATTR>
+<XPD:OBJ name="Operations[0]" type="UMLOperation" guid="QNWAO3SH2kKPrEEYaYdtkAAA">
+<XPD:ATTR name="Name" type="string">from_exception</XPD:ATTR>
+<XPD:ATTR name="OwnerScope" type="UMLScopeKind">skClassifier</XPD:ATTR>
+<XPD:REF name="Owner">nW6zFgSSY0WITaYT3YtvmQAA</XPD:REF>
+</XPD:OBJ>
+<XPD:ATTR name="#Attributes" type="integer">5</XPD:ATTR>
+<XPD:OBJ name="Attributes[0]" type="UMLAttribute" guid="8nmRSvqHpU6flTW4ZjNAtAAA">
+<XPD:ATTR name="Name" type="string">msg</XPD:ATTR>
+<XPD:REF name="Owner">nW6zFgSSY0WITaYT3YtvmQAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="Attributes[1]" type="UMLAttribute" guid="GzeQlDpPgEOZIkCBj+NKiwAA">
+<XPD:ATTR name="Name" type="string">line</XPD:ATTR>
+<XPD:REF name="Owner">nW6zFgSSY0WITaYT3YtvmQAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="Attributes[2]" type="UMLAttribute" guid="V9xspUEr9UWYbO2IUyS1WwAA">
+<XPD:ATTR name="Name" type="string">file</XPD:ATTR>
+<XPD:REF name="Owner">nW6zFgSSY0WITaYT3YtvmQAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="Attributes[3]" type="UMLAttribute" guid="JX39ZaoxpEChgkQkxtzfrgAA">
+<XPD:ATTR name="Name" type="string">severity</XPD:ATTR>
+<XPD:REF name="Owner">nW6zFgSSY0WITaYT3YtvmQAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="Attributes[4]" type="UMLAttribute" guid="hoQptpZ9fkOBsQYeFgDUawAA">
+<XPD:ATTR name="Name" type="string">type</XPD:ATTR>
+<XPD:REF name="Owner">nW6zFgSSY0WITaYT3YtvmQAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedElements[10]" type="UMLClass" guid="rf6UykFPpkeu7c421sgazQAA">
+<XPD:ATTR name="Name" type="string">Exception</XPD:ATTR>
+<XPD:REF name="Namespace">k3+1z5eSS0aCc7wycfchUAAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">ycmoHebIUkeHupzKOsY0GgAA</XPD:REF>
+<XPD:REF name="Views[1]">kaDas08xSUSwaF3Qo0nanwAA</XPD:REF>
+<XPD:REF name="Views[2]">vdo9HscXSkeF0cX4MnGddgAA</XPD:REF>
+<XPD:REF name="Views[3]">NhZBPUXvf0iw2VkM+GMpnAAA</XPD:REF>
+<XPD:ATTR name="#Specializations" type="integer">1</XPD:ATTR>
+<XPD:REF name="Specializations[0]">XStsjSJBDk+s2L22GVmGfQAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedElements[11]" type="UMLGeneralization" guid="XStsjSJBDk+s2L22GVmGfQAA">
+<XPD:REF name="Namespace">k3+1z5eSS0aCc7wycfchUAAA</XPD:REF>
+<XPD:REF name="Child">CpCtdq7WY0mJ2Yw3xLfP6wAA</XPD:REF>
+<XPD:REF name="Parent">rf6UykFPpkeu7c421sgazQAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">dSXjIJ9YUE2CX+onbmfhGgAA</XPD:REF>
+<XPD:REF name="Views[1]">yoUriE7jSEeYmCUlxujIIwAA</XPD:REF>
+<XPD:REF name="Views[2]">AZ60xT26CEKYZqbO16ljaAAA</XPD:REF>
+<XPD:REF name="Views[3]">b+RDR1+nHUG8DCzD022LUQAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedElements[12]" type="UMLClass" guid="0F4w8SQAhU6PQs5Ym0CzEAAA">
+<XPD:ATTR name="Name" type="string">CrmlParseError</XPD:ATTR>
+<XPD:REF name="Namespace">k3+1z5eSS0aCc7wycfchUAAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">ciGDbr0BfUil+uQUIDeXQQAA</XPD:REF>
+<XPD:REF name="Views[1]">CPVoTDN5oEGoCR2LZrM2KwAA</XPD:REF>
+<XPD:REF name="Views[2]">5TxAVUuD/06c2nmBaYwLRAAA</XPD:REF>
+<XPD:REF name="Views[3]">szEqhCsiVE65lCiPPYS8OwAA</XPD:REF>
+<XPD:ATTR name="#Generalizations" type="integer">1</XPD:ATTR>
+<XPD:REF name="Generalizations[0]">B+b9kyKZoUiNPA0amRmuuwAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedElements[13]" type="UMLGeneralization" guid="B+b9kyKZoUiNPA0amRmuuwAA">
+<XPD:REF name="Namespace">k3+1z5eSS0aCc7wycfchUAAA</XPD:REF>
+<XPD:REF name="Child">0F4w8SQAhU6PQs5Ym0CzEAAA</XPD:REF>
+<XPD:REF name="Parent">Cw3u9C6Qt0iw1URnTduBSQAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">g9lNCCdLNE2rVWwg8oKFlQAA</XPD:REF>
+<XPD:REF name="Views[1]">qQxCbD8bPkm1RzefpboXbwAA</XPD:REF>
+<XPD:REF name="Views[2]">knY2vp+HL02Rl2Fy2DYaOAAA</XPD:REF>
+<XPD:REF name="Views[3]">NfHUtnHoW06wP1ZpBMH2dgAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedElements[14]" type="UMLGeneralization" guid="qQ54GGA4DEWmPw3Ix0jbCQAA">
+<XPD:REF name="Namespace">k3+1z5eSS0aCc7wycfchUAAA</XPD:REF>
+<XPD:REF name="Child">LYT5nNubLU21hr+9lFCjagAA</XPD:REF>
+<XPD:REF name="Parent">CpCtdq7WY0mJ2Yw3xLfP6wAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">Y3Nmw6b48ES7XMYmOgDkcQAA</XPD:REF>
+<XPD:REF name="Views[1]">BV6s2EtNyU2NIwJrOCKEsgAA</XPD:REF>
+<XPD:REF name="Views[2]">f0AOhRp8y0aAenoFW5fAEwAA</XPD:REF>
+<XPD:REF name="Views[3]">xeqe/1TQFUSBF0zLR7uPSAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedElements[15]" type="UMLGeneralization" guid="hrAhTmhhzUqPv4OZuUD93AAA">
+<XPD:REF name="Namespace">k3+1z5eSS0aCc7wycfchUAAA</XPD:REF>
+<XPD:REF name="Child">WWb6aySf10m9HwLKW3GB1QAA</XPD:REF>
+<XPD:REF name="Parent">CpCtdq7WY0mJ2Yw3xLfP6wAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">lzTahw8af0mMhES17c0s7gAA</XPD:REF>
+<XPD:REF name="Views[1]">a5ldPk/cF0SEFRsmjO7EzQAA</XPD:REF>
+<XPD:REF name="Views[2]">ujixESozM0WHAPa6R9/0NAAA</XPD:REF>
+<XPD:REF name="Views[3]">EcDaxMOyA0ecgSslQ7x4lwAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedElements[2]" type="UMLModel" guid="YIOeIf6CZkqa1NWYPAT9yQAA">
+<XPD:ATTR name="Name" type="string">Model2</XPD:ATTR>
+<XPD:REF name="Namespace">UgzTZtXBekmk2L7FzuhqeQAA</XPD:REF>
+<XPD:ATTR name="#OwnedDiagrams" type="integer">1</XPD:ATTR>
+<XPD:OBJ name="OwnedDiagrams[0]" type="UMLClassDiagram" guid="U5ypMcL5SkK1kpJjE1zJ7QAA">
+<XPD:ATTR name="Name" type="string">ClassDiagram1</XPD:ATTR>
+<XPD:REF name="DiagramOwner">YIOeIf6CZkqa1NWYPAT9yQAA</XPD:REF>
+<XPD:OBJ name="DiagramView" type="UMLClassDiagramView" guid="GYo7jP+B3Uy2LWLOVeCSPgAA">
+<XPD:REF name="Diagram">U5ypMcL5SkK1kpJjE1zJ7QAA</XPD:REF>
+<XPD:ATTR name="#OwnedViews" type="integer">7</XPD:ATTR>
+<XPD:OBJ name="OwnedViews[0]" type="UMLClassView" guid="nUTauj7GFUujlHPXz/NkOwAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">208</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">96</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">205</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">69</XPD:ATTR>
+<XPD:REF name="Model">TRhtGYancUSTVzgzudt8vgAA</XPD:REF>
+<XPD:OBJ name="NameCompartment" type="UMLNameCompartmentView" guid="h4/5qypj40Wyu54UgfThlgAA">
+<XPD:OBJ name="NameLabel" type="LabelView" guid="6Ds59JFnoEmergbvt/JReQAA">
+<XPD:ATTR name="FontStyle" type="integer">1</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">ImplmlParseContext</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="LabelView" guid="BXCcR7Lqi0ivkEZrTd0nyQAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="LabelView" guid="/yA+UAPDlES8DfNq4TjKsgAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="AttributeCompartment" type="UMLAttributeCompartmentView" guid="WVzqaOkVYk6M5VmRJT2SdwAA">
+<XPD:REF name="Model">TRhtGYancUSTVzgzudt8vgAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OperationCompartment" type="UMLOperationCompartmentView" guid="12iPO0ZV/ECC+ZxBdww9NwAA">
+<XPD:REF name="Model">TRhtGYancUSTVzgzudt8vgAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TemplateParameterCompartment" type="UMLTemplateParameterCompartmentView" guid="P389F+FIr0u60EVDOuy9QgAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:REF name="Model">TRhtGYancUSTVzgzudt8vgAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[1]" type="UMLClassView" guid="j5JHJNBwdUiknDiaUgPscQAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">292</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">248</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">205</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">69</XPD:ATTR>
+<XPD:REF name="Model">mvuvaoq69U+8RTdsphq0WAAA</XPD:REF>
+<XPD:OBJ name="NameCompartment" type="UMLNameCompartmentView" guid="E52DMa1Hvka1PdrDiIfjYQAA">
+<XPD:OBJ name="NameLabel" type="LabelView" guid="JTEDQY6c0ky6j3zmJqnIfgAA">
+<XPD:ATTR name="FontStyle" type="integer">1</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">ValidationImplmlParseContext</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="LabelView" guid="LcW0yJtSu0yrB1480dy64gAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="LabelView" guid="uGX2kqw8jky9rE+NQmAkmQAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="AttributeCompartment" type="UMLAttributeCompartmentView" guid="Hdc7mB53mUif8sFjpKqYdAAA">
+<XPD:REF name="Model">mvuvaoq69U+8RTdsphq0WAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OperationCompartment" type="UMLOperationCompartmentView" guid="eAOCvVCWdEW+UXQzOgQ6gAAA">
+<XPD:REF name="Model">mvuvaoq69U+8RTdsphq0WAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TemplateParameterCompartment" type="UMLTemplateParameterCompartmentView" guid="KXQDxUmITEiHMMcW/RM4jQAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:REF name="Model">mvuvaoq69U+8RTdsphq0WAAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[2]" type="UMLGeneralizationView" guid="0+P5ulM6CUK32H3J4trkIwAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Points" type="Points">375,248;329,164</XPD:ATTR>
+<XPD:REF name="Model">eT3WFDjFcUOC0uUTMJC3VwAA</XPD:REF>
+<XPD:REF name="Head">nUTauj7GFUujlHPXz/NkOwAA</XPD:REF>
+<XPD:REF name="Tail">j5JHJNBwdUiknDiaUgPscQAA</XPD:REF>
+<XPD:OBJ name="NameLabel" type="EdgeLabelView" guid="zdHGyXIYQkei12PmlUOtvAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">15</XPD:ATTR>
+<XPD:REF name="Model">eT3WFDjFcUOC0uUTMJC3VwAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="EdgeLabelView" guid="fd8XAhF0f0an5zXFhtyYvQAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">30</XPD:ATTR>
+<XPD:REF name="Model">eT3WFDjFcUOC0uUTMJC3VwAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="EdgeLabelView" guid="MsBk9Z2Ib0GEa5SGERK3hAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">-1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">15</XPD:ATTR>
+<XPD:REF name="Model">eT3WFDjFcUOC0uUTMJC3VwAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[3]" type="UMLNoteView" guid="u9kalNIVQUyZsb7Z40SkkgAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">456</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">76</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">224</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">68</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">The parse context defines how exceptions
+and problems encountered during parsing
+are handled. The default context simply
+logs all exceptions and problems.
+</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[4]" type="UMLNoteView" guid="qrZ2QIGHG0Cn+sYe8SCjGgAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">532</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">200</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">195</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">53</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">When validating, a parse context
+that collects a list of Problem objects
+is used.
+</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[5]" type="UMLNoteLinkView" guid="QAjqHR0FyEaj4G1nW3NLmgAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Points" type="Points">496,258;532,249</XPD:ATTR>
+<XPD:REF name="Head">qrZ2QIGHG0Cn+sYe8SCjGgAA</XPD:REF>
+<XPD:REF name="Tail">j5JHJNBwdUiknDiaUgPscQAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[6]" type="UMLNoteLinkView" guid="pRuLigQqJU2/WTa5t4hHCgAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Points" type="Points">412,122;456,118</XPD:ATTR>
+<XPD:REF name="Head">u9kalNIVQUyZsb7Z40SkkgAA</XPD:REF>
+<XPD:REF name="Tail">nUTauj7GFUujlHPXz/NkOwAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:ATTR name="#OwnedElements" type="integer">3</XPD:ATTR>
+<XPD:OBJ name="OwnedElements[0]" type="UMLClass" guid="TRhtGYancUSTVzgzudt8vgAA">
+<XPD:ATTR name="Name" type="string">ImplmlParseContext</XPD:ATTR>
+<XPD:REF name="Namespace">YIOeIf6CZkqa1NWYPAT9yQAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">nUTauj7GFUujlHPXz/NkOwAA</XPD:REF>
+<XPD:REF name="Views[1]">WVzqaOkVYk6M5VmRJT2SdwAA</XPD:REF>
+<XPD:REF name="Views[2]">12iPO0ZV/ECC+ZxBdww9NwAA</XPD:REF>
+<XPD:REF name="Views[3]">P389F+FIr0u60EVDOuy9QgAA</XPD:REF>
+<XPD:ATTR name="#Specializations" type="integer">1</XPD:ATTR>
+<XPD:REF name="Specializations[0]">eT3WFDjFcUOC0uUTMJC3VwAA</XPD:REF>
+<XPD:ATTR name="#Operations" type="integer">2</XPD:ATTR>
+<XPD:OBJ name="Operations[0]" type="UMLOperation" guid="kj0ZrAVvD0yl4xHAdFN8SQAA">
+<XPD:ATTR name="Name" type="string">handle_exception</XPD:ATTR>
+<XPD:REF name="Owner">TRhtGYancUSTVzgzudt8vgAA</XPD:REF>
+<XPD:ATTR name="#Parameters" type="integer">2</XPD:ATTR>
+<XPD:OBJ name="Parameters[0]" type="UMLParameter" guid="t/qvoqXzmkKFofF6JoQu7wAA">
+<XPD:ATTR name="Name" type="string">exception</XPD:ATTR>
+<XPD:REF name="BehavioralFeature">kj0ZrAVvD0yl4xHAdFN8SQAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="Parameters[1]" type="UMLParameter" guid="8iuzm+hsnEGcNK+W8ZLFfAAA">
+<XPD:ATTR name="Name" type="string">filename</XPD:ATTR>
+<XPD:REF name="BehavioralFeature">kj0ZrAVvD0yl4xHAdFN8SQAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="Operations[1]" type="UMLOperation" guid="ISpOCfw1GkONuBx7w9SXZQAA">
+<XPD:ATTR name="Name" type="string">handle_problem</XPD:ATTR>
+<XPD:REF name="Owner">TRhtGYancUSTVzgzudt8vgAA</XPD:REF>
+<XPD:ATTR name="#Parameters" type="integer">1</XPD:ATTR>
+<XPD:OBJ name="Parameters[0]" type="UMLParameter" guid="sxxSuo1X0UmoJdaF0uPQNAAA">
+<XPD:ATTR name="Name" type="string">problem</XPD:ATTR>
+<XPD:REF name="BehavioralFeature">ISpOCfw1GkONuBx7w9SXZQAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedElements[1]" type="UMLClass" guid="mvuvaoq69U+8RTdsphq0WAAA">
+<XPD:ATTR name="Name" type="string">ValidationImplmlParseContext</XPD:ATTR>
+<XPD:REF name="Namespace">YIOeIf6CZkqa1NWYPAT9yQAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">j5JHJNBwdUiknDiaUgPscQAA</XPD:REF>
+<XPD:REF name="Views[1]">Hdc7mB53mUif8sFjpKqYdAAA</XPD:REF>
+<XPD:REF name="Views[2]">eAOCvVCWdEW+UXQzOgQ6gAAA</XPD:REF>
+<XPD:REF name="Views[3]">KXQDxUmITEiHMMcW/RM4jQAA</XPD:REF>
+<XPD:ATTR name="#Generalizations" type="integer">1</XPD:ATTR>
+<XPD:REF name="Generalizations[0]">eT3WFDjFcUOC0uUTMJC3VwAA</XPD:REF>
+<XPD:ATTR name="#Operations" type="integer">2</XPD:ATTR>
+<XPD:OBJ name="Operations[0]" type="UMLOperation" guid="evp+p65t7U6mV5QdBdOpTAAA">
+<XPD:ATTR name="Name" type="string">handle_exception</XPD:ATTR>
+<XPD:REF name="Owner">mvuvaoq69U+8RTdsphq0WAAA</XPD:REF>
+<XPD:ATTR name="#Parameters" type="integer">2</XPD:ATTR>
+<XPD:OBJ name="Parameters[0]" type="UMLParameter" guid="o1Xgk7ewZE6mGCQCCbaFpgAA">
+<XPD:ATTR name="Name" type="string">exception</XPD:ATTR>
+<XPD:REF name="BehavioralFeature">evp+p65t7U6mV5QdBdOpTAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="Parameters[1]" type="UMLParameter" guid="gOGs6Fh3J0+9jT8FBpW8YwAA">
+<XPD:ATTR name="Name" type="string">filename</XPD:ATTR>
+<XPD:REF name="BehavioralFeature">evp+p65t7U6mV5QdBdOpTAAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="Operations[1]" type="UMLOperation" guid="7bCi/mTMJUWdBc/nL9kodgAA">
+<XPD:ATTR name="Name" type="string">handle_problem</XPD:ATTR>
+<XPD:REF name="Owner">mvuvaoq69U+8RTdsphq0WAAA</XPD:REF>
+<XPD:ATTR name="#Parameters" type="integer">1</XPD:ATTR>
+<XPD:OBJ name="Parameters[0]" type="UMLParameter" guid="tP8XVg1Eo0CrsbV5f6ffHgAA">
+<XPD:ATTR name="Name" type="string">problem</XPD:ATTR>
+<XPD:REF name="BehavioralFeature">7bCi/mTMJUWdBc/nL9kodgAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedElements[2]" type="UMLGeneralization" guid="eT3WFDjFcUOC0uUTMJC3VwAA">
+<XPD:REF name="Namespace">YIOeIf6CZkqa1NWYPAT9yQAA</XPD:REF>
+<XPD:REF name="Child">mvuvaoq69U+8RTdsphq0WAAA</XPD:REF>
+<XPD:REF name="Parent">TRhtGYancUSTVzgzudt8vgAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">0+P5ulM6CUK32H3J4trkIwAA</XPD:REF>
+<XPD:REF name="Views[1]">zdHGyXIYQkei12PmlUOtvAAA</XPD:REF>
+<XPD:REF name="Views[2]">fd8XAhF0f0an5zXFhtyYvQAA</XPD:REF>
+<XPD:REF name="Views[3]">MsBk9Z2Ib0GEa5SGERK3hAAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+</XPD:OBJ>
+</XPD:BODY>
+</XPD:PROJECT>
--- a/configurationengine/doc/plugins/dev-plugin/plugin-interface.rst	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/doc/plugins/dev-plugin/plugin-interface.rst	Tue Aug 10 14:29:28 2010 +0300
@@ -3,7 +3,11 @@
 Plug-in interface
 =================
 
-A ConE plug-in has two points for interfacing with ConE:
+Implementation languages
+------------------------
+
+A ConE plug-in that adds support for an implementation language has two points
+for interfacing with ConE:
 
 #. Reader classes that derive from ``cone.public.plugin.ReaderBase`` . These classes
    define supported Implementation Markup Languages (i.e. supported XML namespaces)
@@ -16,6 +20,9 @@
 
 .. image:: plugin_classes.jpg
 
+For more information on the classes see the
+`ConE API epydoc <../../epydoc/cone.public.plugin-module.html>`_.
+
 ConE generation can be seen to consist of two phases, implementation parsing
 and output generation:
 
@@ -38,7 +45,7 @@
 - Output is generated using each implementation set. For each implementation set:
 
     - The ``generation_context`` variable of each implementation instance is set
-      (this context contains generation-scope information implementations instances may use)
+      (this context contains generation-scope information implementation instances may use)
     - The ``generate()`` method of each instance is called
     - The ``post_generate()`` method of each instance is called
 
@@ -63,138 +70,48 @@
 10-11  Output generation methods are called
 ====== ========================================================================
 
-Plug-in interface class source
-------------------------------
+
+.. _plugin-howto-plugin-interface-validation:
 
-The following source listings show the most important parts of the ``ImplReader``
-and ``ImplBase`` classes from a plug-in's point of view:
-
-.. code-block:: python
+Validation
+----------
 
-    class ReaderBase(object):
-        """
-        Base class for implementation readers.
-        
-        Each reader class supports one XML namespace, from which it reads an implementation
-        instance.
-        
-        The method for parsing an implementation (read_impl()) is given an ElementTree
-        XML element as the root from which to parse the implementation. The plug-in
-        machinery handles each XML file so that the correct reader class is used to read
-        the implementations from XML elements based on the namespaces.
-        """
-        
-        # The XML namespace supported by the implementation reader.
-        # Should be something like "http://www.xyz.org/xml/1".
-        # Can also be None, in which case the reader will not be used
-        # (this can be useful for defining base classes for e.g. readers
-        # for different versions of an implementation).
-        NAMESPACE = None
-        
-        # Any extra XML namespaces that should be ignored by the
-        # implementation parsing machinery. This is useful for specifying
-        # namespaces that are not actual ImplML namespaces, but are used
-        # inside an implementation (e.g. XInclude)
-        IGNORED_NAMESPACES = []
-        
-        # Supported implementation file extensions.
-        # Sub-classes can override this to add new supported file extensions
-        # if necessary. The file extensions simply control whether implementations
-        # are attempted to be read from a file or not.
-        # Note that the extensions are case-insensitive.
-        FILE_EXTENSIONS = ['implml']
-        
-        @classmethod
-        def read_impl(cls, resource_ref, configuration, doc_root):
-            """
-            Read an implementation instance from the given element tree.
-            
-            @param resource_ref: Reference to the resource in the configuration in
-                which the given document root resides.
-            @param configuration: The configuration used.
-            @param doc_root: The document root from which to parse the implementation.
-            @return: The read implementation instance, or None.
-            """
-            raise exceptions.NotSupportedException()
+.. note::
+    
+    See also :ref:`validation-overview`
 
-.. code-block:: python
+The ConE plug-in interface allows for the extension of ConfML and ImplML validation.
+In the same way as support for new implementation languages can be provided
+by exposing implementation reader classes via egg entry points, validation
+can be extended by exposing validator classes.
+
+Validation happens roughly in the following manner:
 
-    class GenerationContext(object):
-        """
-        Context object that can be used for passing generation-scope
-        data to implementation instances.
-        """
-        
-        def __init__(self, tags={}):
-            # The tags used in this generation context
-            # (i.e. the tags passed from command line)
-            self.tags = tags
-            
-            # A dictionary that implementation instances can use to
-            # pass any data between each other
-            self.impl_data_dict = {}
-
-.. code-block:: python
+1. A list of *validator classes* is obtained through some means. In practice
+   this usually means finding all validator classes, and then filtering them
+   down to those that produce the problems that we are interested in.
+2. A *validation context* is created. This contains everything associated with
+   the validation, and here all found problems are reported. All validators
+   have access to it.
+3. For each entity (configuration or implementation instance) that is being
+   validated, an instance of each validator class is created and invoked.
 
-    class ImplBase(object):
-        """
-        Base class for any confml implementation. 
-        """
-        
-        # Identifier for the implementation type, used e.g. in .cfg files.
-        # Should be a string like e.g. 'someml'.
-        IMPL_TYPE_ID = None
-        
-        # Defines the default invocation phase for the implementation.
-        # The default is used if the phase is not explicitly set in the
-        # ImplML file or manually overridden by calling set_invocation_phase()
-        DEFAULT_INVOCATION_PHASE = None
-        
-        def __init__(self,ref, configuration):
-            """
-            Create a ImplBase object
-            @param ref : the ref to the Implml file resource.
-            @param configuration : the Configuration instance for the
-            configuration data.
-            """
-            self._settings = None
-            self.ref = ref
-            self.index = None
-            self.configuration = configuration
-            self.output_root = self.settings.get('output_root','output')
-            self.output_subdir = self.settings.get('output_subdir','')
-            self.plugin_output = self.settings.get('plugin_output','')
-            
-            self.generation_context = None
-            self._tags = None
-            self._invocation_phase = None
-            self._tempvar_defs = []
+This process is nearly the same for ConfML and ImplML validation, only some
+details about the validation context and the entities being validated are
+different, as well as the fact ConfML validation on the entire configuration,
+whereas ImplML validation happens on individual implementation instances, with
+a few exceptions.
+
+The following diagram illustrates ImplML validation:
+
+.. image:: impl-validation-classes.jpg
 
-        def generate(self):
-            """
-            Generate the given implementation.
-            @return: 
-            """
-            raise exceptions.NotSupportedException()
-        
-        def post_generate(self):
-            """
-            Called when all normal generation has been done.
-            
-            @attention: This is a temporary method used for implementing cenrep_rfs.txt generation.
-            """
-            pass
-        
-        def list_output_files(self):
-            """
-            Return a list of output files as an array. 
-            """
-            raise exceptions.NotSupportedException()
-        
-        def get_refs(self):
-            """
-            Return a list of all ConfML setting references that affect this
-            implementation. May also return None if references are not relevant
-            for the implementation.
-            """
-            return None
+The following diagram illustrates ConfML validation:
+
+.. image:: confml-validation-classes.jpg
+
+For more information on the classes involved in validate see the
+ConE API epydoc for `cone.validation.implmlvalidation <../../epydoc/cone.validation.implmlvalidation-module.html>`_
+and `cone.validation.confmlvalidation <../../epydoc/cone.validation.confmlvalidation-module.html>`_.
+Also the built-in validators in the package `cone.validation.builtinvalidators <../../epydoc/cone.validation.builtinvalidators-module.html>`_
+can serve as examples.
\ No newline at end of file
Binary file configurationengine/doc/plugins/dev-plugin/plugin_classes.jpg has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/plugins/dev-plugin/validation-example-plugin.rst	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,88 @@
+.. _validation-plugin-howto-example-plugin:
+
+Example ConfML validation plug-in
+=================================
+
+The example plug-in implements a simple ConfML validator class, and so demostrates
+how ConfML validation can be extended by plug-ins.
+
+The extra validation in this case is as follows: we have a requirement that if
+a string-type ConfML setting's reference starts with ``FOO_``, its value
+should also contain the string ``foo``. For example, consider the following
+file:
+
+.. code-block :: xml
+    :linenos:
+    
+    <?xml version="1.0" encoding="UTF-8"?>
+    <configuration xmlns="http://www.s60.com/xml/confml/1" name="ExampleValidatorTest">
+        <feature ref="ExampleValidatorTest" name="Settings for example validator testing">
+            <setting ref="SomeSetting" name="Some setting" type="string"/>
+            <setting ref="FOO_SomeSetting1" name="FOO - Some setting 1" type="string"/>
+            <setting ref="FOO_SomeSetting2" name="FOO - Some setting 2" type="string"/>
+        </feature>
+        <data>
+            <ExampleValidatorTest>
+                <SomeSetting>foo bar</SomeSetting>
+                <FOO_SomeSetting1>abc foo</FOO_SomeSetting1>
+                <FOO_SomeSetting2>abc123</FOO_SomeSetting2>
+            </ExampleValidatorTest>
+        </data>
+    </configuration>
+
+Here two settings are prefixed with ``FOO_``, but only one of them has ``foo``
+in its value, thus our custom validator should report a warning for the value
+on line 12.
+
+Directory structure
+-------------------
+
+- ``plugins/`` - Root directory for all ConE plug-in sources
+    - ``example/`` - Example plug-in package directory
+        - ``ConeExampleValidatorPlugin/`` - Source for the example validator plug-in
+            - ``examplevalidatorplugin/`` - Module directory containing all plug-in code
+                - ``tests/`` - Unit tests and test data for the plug-in
+                    - ``testdata/`` - Directory containing all test data needed by the test cases
+                    - ``__init__.py`` - Test module initialization file
+                    - ``runtests.py`` - Script for running all test cases
+                    - ``unittest_validation.py`` - File containing test cases
+                - ``__init__.py`` - Plug-in module initialization file
+                - ``validators.py`` - Plug-in source file
+            - ``setup.py`` - Setup script for packaging the plug-in into an .egg file
+            - ``setup.cfg`` - Configuration file for ``setup.py``
+
+Plug-in code
+------------
+
+validators.py
+.............
+
+This file defines the validator class. The validator simply goes through all
+``ConfmlStringSetting`` instances in the configuration and checks their values.
+
+.. literalinclude:: /../source/plugins/example/ConeExampleValidatorPlugin/examplevalidatorplugin/validators.py
+   :linenos:
+
+
+unittest_validation.py
+......................
+
+The tests for the plug-in simply contain one test case that tests the validator
+with the example ConfML file shown earlier, using the ``assert_problem_list_equals_expected()``
+method provided by the ``testautomation`` module.
+
+.. literalinclude:: /../source/plugins/example/ConeExampleValidatorPlugin/examplevalidatorplugin/tests/unittest_validation.py
+   :linenos:
+
+
+Plug-in packaging
+-----------------
+
+The file ``setup.py`` handles the packaging of the plug-in into an egg file.
+
+The most important thing here is the plug-in's entry point info. The list
+of validator classes provided by the plug-in must be specified as an entry
+point. The entry point group in this case is ``cone.plugins.confmlvalidators``.
+
+.. literalinclude:: /../source/plugins/example/ConeExampleValidatorPlugin/setup.py
+   :linenos:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/plugins/dev-plugin/validation-plugin-index.rst	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,13 @@
+.. _validation-plugin-howto:
+
+How to create a ConfML validation plug-in for ConE
+==================================================
+
+This page contains a description of
+an example plug-in intended to be used as a template for creating new ConfML validation plug-in.
+It is recommended to read also about the :ref:`plug-in interface <plugin-howto-plugin-interface-validation>`
+
+.. toctree::
+    :maxdepth: 3
+    
+    validation-example-plugin
--- a/configurationengine/doc/plugins/general.rst	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/doc/plugins/general.rst	Tue Aug 10 14:29:28 2010 +0300
@@ -55,7 +55,7 @@
             </rule>
         </ruleml>
 
-        <content xmlns="http://www.s60.com/xml/content/3">
+        <content xmlns="http://www.s60.com/xml/content/2">
             <output file="${StartupSettings.StartupSoundPath}">
                 <input file="${CustomSettings.StartupSoundFile.localPath}"/>
             </output>
@@ -71,7 +71,7 @@
 
  - The container is in http://www.symbianfoundation.org/xml/implml/1, the root element of implml namespace must always be container
  - The ruleml is in http://www.s60.com/xml/ruleml/2
- - The content is in xmlns="http://www.s60.com/xml/content/3"
+ - The content is in xmlns="http://www.s60.com/xml/content/2"
 
 When reading the implementation file, ConE checks the document root and its namespace 
 to find out from namespace to start parsing. 
@@ -157,7 +157,7 @@
     <?xml version="1.0" encoding="UTF-8"?>
     <container xmlns="http://www.symbianfoundation.org/xml/implml/1">
         <container>
-            <phase name="pre">
+            <phase name="pre"/>
             <ruleml xmlns="http://www.s60.com/xml/ruleml/2">
                 <rule>
                     CustomSettings.StartupSoundFile.localPath configures 
@@ -167,15 +167,15 @@
         </container>
      
         <container>
-            <phase name="normal">
-            <content xmlns="http://www.s60.com/xml/content/3">
+            <phase name="normal"/>
+            <content xmlns="http://www.s60.com/xml/content/2">
                 <output file="${StartupSettings.StartupSoundPath}">
                     <input file="${CustomSettings.StartupSoundFile.localPath}"/>
                 </output>
             </content>
             
             <!-- Another ContentML section, copies the file to another directory -->
-            <content xmlns="http://www.s60.com/xml/content/3">
+            <content xmlns="http://www.s60.com/xml/content/2">
                 <output dir="some/dir">
                     <input file="${CustomSettings.StartupSoundFile.localPath}"/>
                 </output>
@@ -291,7 +291,7 @@
             </output>
         </content>
         
-        <ruleml xmlns="http://www.s60.com/xml/ruleml/1" xmlns:implml="http://www.symbianfoundation.org/xml/implml/1">                    
+        <ruleml xmlns="http://www.s60.com/xml/ruleml/1">                    
             <rule>X.Y configures X.Z = X.Y</rule>
         </ruleml>
     </container>
@@ -310,7 +310,7 @@
     <container xmlns="http://www.symbianfoundation.org/xml/implml/1">        
         <container>
             <phase name='pre'/>
-            <ruleml xmlns="http://www.s60.com/xml/ruleml/1" xmlns:implml="http://www.symbianfoundation.org/xml/implml/1">                    
+            <ruleml xmlns="http://www.s60.com/xml/ruleml/1">                    
                 <rule>X.Y configures X.Z = X.Y</rule>
             </ruleml>
         </container>
@@ -356,10 +356,10 @@
 
 .. code-block:: xml
 
-    <tag name="target" value="core">
-    <tag name="target" value="rofs2">
-    <tag name="target" value="uda">
-    <tag name="content" value="music">
+    <tag name="target" value="core"/>
+    <tag name="target" value="rofs2"/>
+    <tag name="target" value="uda"/>
+    <tag name="content" value="music"/>
 
 Tags can also get their values from ConfML settings, which can be referenced in the usual way:
 
@@ -537,7 +537,7 @@
         </ruleml>
         
         <!-- ContentML implementation for copying the created file list to output -->
-        <content xmlns="http://www.s60.com/xml/content/3">
+        <content xmlns="http://www.s60.com/xml/content/2">
             <output dir="some_dir/">
                 <input files="${FileCopyTemp.Files.Path}"/>
             </output>
@@ -610,12 +610,10 @@
     <?xml version="1.0" encoding="UTF-8"?>
     <container xmlns="http://www.symbianfoundation.org/xml/implml/1">
         
-        <!-- Temporary sequence setting for storing a generation-time created list of files to copy -->
         <outputRootDir value="\epoc32\data"/>
         <outputSubDir value="widgets"/>
 
-        <!-- ContentML implementation for copying the created file list to output -->
-        <content xmlns="http://www.s60.com/xml/content/3">
+        <content xmlns="http://www.s60.com/xml/content/2">
             <output dir="some_dir/">
                 <input file="test.wgz"/>
             </output>
@@ -623,18 +621,4 @@
         
     </container>
 
-In the above example the content is copied to \epoc32\data\widgets\some_dir\text.wgz.
-
-
-.. rubric:: Footnotes
-
-.. [#multi-content-note] In this case the run-time behavior would still be same; ContentML
-   allows multiple ``output`` elements. However, this might not be the case for all
-   implementation languages.
-
-.. [#legacy-implml-root-name-note] The specifications for the legacy implementation
-   languages CRML and GenConfML do give the root element names, and say that each
-   implementation must be in its own crml/gcfml file.
-   It is recommended to stick to this convention for these two implementation languages
-   also in the future. Indeed, using them in a multi-implementation file has not been
-   tested and may not even work correctly.
+In the above example the content is copied to \\epoc32\\data\\widgets\\some_dir\\text.wgz.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/plugins/imageml-plugin/examples/bmp_and_optional_mask.imageml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<imageml xmlns="http://www.s60.com/xml/imageml/1">
+    <!--
+    BMP to MBM conversion with an optional mask bitmap. The value of
+    TestSettings.ConeInputBmpMask.localPath is empty, but since the 'optional'
+    attribute is set to be 'true', it is silently ignored. If the attribute
+    was not there, an error would be printed during generation.
+    -->
+    <output file="cone_with_optional_mask.mbm"> 
+        <input file="${TestSettings.ConeInputBmp.localPath}" depth="c24"/>
+        <input file="${TestSettings.ConeInputBmpMask.localPath}" depth="c1" optional='true'/>
+    </output>
+</imageml>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/plugins/imageml-plugin/examples/multi_input.imageml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,13 @@
+<imageml xmlns="http://www.s60.com/xml/imageml/1">
+    <!--
+    Image conversion using multiple input files.
+    -->
+    <output file="startup.mbm">
+        <!-- Files from a directory can be included using regex patterns -->
+        <input dir="startup_anim_bmp/">
+            <include pattern="bmp$"/>
+        </input>
+        <!-- Single files can be also added -->
+        <input file="cone.bmp"/>
+    </output>
+</imageml>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/plugins/imageml-plugin/examples/simple.imageml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<imageml xmlns="http://www.s60.com/xml/imageml/1">
+    <!--
+    Simple image conversions using a single input file.
+    -->
+    
+    <output file="simple/cone.mbm">
+        <input file="cone.bmp" depth="c24"/>
+    </output>
+    
+    <output file="simple/icon.mif">
+        <input file="icon.svg"/>
+    </output>
+</imageml>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/plugins/imageml-plugin/examples/with_refs.imageml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<imageml xmlns="http://www.s60.com/xml/imageml/1">
+    <!--
+    Simple image conversions using a single input file, but with the file
+    location coming from ConfML setting values.
+    
+    The target paths in the ConfML setting values are absolute paths on the
+    target device, e.g. 'Z:\\resource\\apps\\cone.mbm'. When the output file
+    location is taken from a ConfML setting, the ImageML plug-in automatically
+    strips the drive letter, so the output file location becomes
+    '<cone_output_dir>/resource/apps/cone.mbm' in this case.
+    -->
+    
+    <output file="${TestSettings.ConeMbmTargetPath}">
+        <input file="${TestSettings.ConeInputBmp.localPath}" depth="${TestSettings.ConeMbmDepth}"/>
+    </output>
+    
+    <output file="${TestSettings.IconMifTargetPath}">
+        <input file="${TestSettings.IconInputSvg.localPath}"/>
+    </output>
+</imageml>
\ No newline at end of file
Binary file configurationengine/doc/plugins/imageml-plugin/imageml-example-project.zip has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/doc/plugins/imageml-plugin/imageml-plugin.rst	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,214 @@
+User guide for ImageML Plugin usage in ConE
+===========================================
+
+Introduction
+------------
+This page describes how to use the ConE ImageML plug-in.
+The plug-in defines the ImageML Implementation Markup Language, which provides
+image conversion from BMP to MBM and SVG to MIF using the ``mifconv`` and
+``bmconv`` tools.
+
+XML namespace and file extension
+--------------------------------
+
+- Namespace: ``http://www.s60.com/xml/imageml/1``
+- File extension: ``imageml``
+
+ImageML elements
+----------------
+
+The ImageML XML element model is drawn out as a UML class diagram below:
+
+  .. image:: imageml.jpg
+
+output
+^^^^^^
+
+The ``output`` element defines an output file for image conversion. A single
+ImageML implementation may contain multiple ``output`` elements.
+
+**Attributes**
+
+  * *file* - Output file location, for example ``resource/apps/image.mbm``.
+    The output tool used to perform the conversion is deduced from the file
+    extension: bmconv for .mbm and mifconv for .mif. The file location can
+    also come from a ConfML setting using the ``${}`` notation.
+  * *tool* - Override for the path to the tool to use. This is mainly useful
+    for testing, in production use the bmconv and mifconv tools should be in PATH.
+  * *palette* - Specifies a .pal file to use for MBM conversion.
+  * *tooldir* - Override for the location of the bmconv and mifconv tools.
+    This is mainly useful for testing, in production use the bmconv and mifconv
+    tools should be in PATH.
+  * *extraparams* - Optional attribute that can be used to pass extra parameters 
+    for tool. For details see bmconv and mifconv documentation. E.g. "/V3" defines
+    for mifconv the format version of SVG binary conversion. If not defined value
+    forces Svgtbinencode to use the default platform specific value. 
+    Options for mifconv /V parameter are:
+
+.. list-table::
+
+    - - *Value*
+      - *Format type*
+    - - /V1
+      - BGR / float encoding
+    - - /V2
+      - BGR / fixed point encoding
+    - - /V3
+      - RGB / fixed point encoding
+    - - /V4
+      - RGB / float encoding
+    - - /V5
+      - NVG encoding
+
+
+**Example**
+
+.. code-block:: xml
+
+    <output file="resource/apps/startup.mbm">
+    
+    <output file="resource/apps/startup.mif">
+    
+    <!--
+    The drive letter is automatically stripped, and the output location
+    is the same as in the example above
+    -->
+    <output file="Z:\\resource\\apps\\startup.mif">
+    
+    <output file="${StartupSettings.StartupAnimationPath}">
+
+
+input
+^^^^^
+
+The ``input`` element defines a single input file for image conversion, or a
+directory from which input files are selected based on regular expression
+patterns. One ``output`` element may contain multiple ``input`` elements.
+
+An input element must specify a file using the ``file`` attribute or a directory
+using the ``dir`` attribute, but not both.
+
+**Attributes**
+
+  * *file* - Input file from the configuration project content. Can also be
+    a ConfML setting reference using the ``${}`` notation.
+  * *dir* - Directory for input files from the configuration project content.
+    Can also be a ConfML setting reference using the ``${}`` notation.
+  * *depth* - Color depth switch passed to bmconv for the file(s) specified by
+    the current ``input`` element, does nothing if mifconv is used.
+    Can also be a ConfML setting reference using the ``${}`` notation.
+  * *optional* - If ``true``, then the input dir or file may be empty and
+    no error is reported. Can be used to e.g. specify an optional mask bitmap.
+
+**Examples**
+
+.. code-block:: xml
+
+    <input file="images/icon.svg"/>
+    
+    <input file="images/image.bmp" depth="c24"/>
+    
+    <input file="images/image_mask.bmp" depth="c1" optional="true"/>
+    
+    <input file="${TestFeature.BmpFile.localPath}" depth="${TestFeature.BmpDepth}"/>
+    
+    <input dir="images/svg_files/">
+        <include pattern="svg$"/>
+        <exclude pattern=".svn"/>
+    </input>
+
+
+include and exclude
+^^^^^^^^^^^^^^^^^^^
+
+The ``include`` and ``exclude`` elements specify regular expressions for
+selecting input files from an input directory.
+
+**Attributes**
+
+  * *pattern* - The regular expression used to include or exclude files
+  
+**Examples**
+
+.. code-block:: xml
+
+    <include pattern="svg$"/>
+    <include pattern="bmp$"/>
+    <exclude pattern=".svn"/>
+
+Setting references 
+------------------
+
+The setting references that an ImageML implementation uses are determined as
+follows:
+
+  * If any ``input`` elements contain setting references in their ``file``
+    or ``dir`` attributes, those are the setting references used by the
+    ImageML implementation.
+  * If there are no setting references in those attributes, setting references
+    are considered to be irrelevant, and the implementation is always run
+    regardless of setting reference filtering.
+
+See the examples in the section below.
+
+ImageML examples
+----------------
+
+All the examples shown in this section can also be downloaded:
+
+    * :download:`imageml-example-project.zip`
+
+You need to have bmconv and mifconv somewhere in your path for generation to
+work. To generate output from the project simply run::
+
+    > cone generate -p imageml-example-project.zip
+
+Or unzip (e.g. to ``imageml-example-project``) and run::
+    
+    > cd imageml-example-project
+    imageml-example-project\> cone generate
+
+
+Simple image conversion using a single input file
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. literalinclude:: examples/simple.imageml
+   :language: xml
+
+Setting references of this implementation: None (irrelevant)
+
+Simple image conversion with ConfML setting references
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. literalinclude:: examples/with_refs.imageml
+   :language: xml
+
+Setting references of this implementation:
+
+    - ``TestSettings.ConeInputBmp.localPath``
+    - ``TestSettings.IconInputSvg.localPath``
+
+MBM conversion using multiple input files
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. literalinclude:: examples/multi_input.imageml
+   :language: xml
+
+Setting references of this implementation: None (irrelevant)
+
+MBM conversion using an optional mask file
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. literalinclude:: examples/bmp_and_optional_mask.imageml
+   :language: xml
+
+Setting references of this implementation:
+
+    - ``TestSettings.ConeInputBmp.localPath``
+    - ``TestSettings.ConeInputBmpMask.localPath``
+
+FAQ
+---
+
+This will be updated based on the questions.
+
Binary file configurationengine/doc/plugins/imageml-plugin/imageml.jpg has changed
--- a/configurationengine/doc/plugins/index.rst	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/doc/plugins/index.rst	Tue Aug 10 14:29:28 2010 +0300
@@ -34,11 +34,9 @@
     hcrml-plugin/hcrml-plugin
     convertprojectplugin
     thememl-plugin/themelplugin
+    imageml-plugin/imageml-plugin
 
 ConE plug-in development
 ------------------------
 
-.. toctree::
-    :maxdepth: 2
-    
-    dev-plugin/index
+* See :ref:`plugin-api` for instructions how to create a ConE plugin. 
--- a/configurationengine/doc/plugins/plugins.uml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/doc/plugins/plugins.uml	Tue Aug 10 14:29:28 2010 +0300
@@ -5527,6 +5527,727 @@
 <XPD:REF name="DiagramOwner">I0mGM2cIbES/2vP45srj7AAA</XPD:REF>
 <XPD:OBJ name="DiagramView" type="UMLClassDiagramView" guid="QrtSXmbP5Eme/v7a4ua20gAA">
 <XPD:REF name="Diagram">Oz6AUWlj3Ei96BpX7wdxtAAA</XPD:REF>
+<XPD:ATTR name="#OwnedViews" type="integer">9</XPD:ATTR>
+<XPD:OBJ name="OwnedViews[0]" type="UMLClassView" guid="/Aq0TH5t8EiVzBQ4GkGa/AAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">180</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">40</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">93</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">33</XPD:ATTR>
+<XPD:REF name="Model">CRuOLYF7gU2l1tg34dY6bgAA</XPD:REF>
+<XPD:OBJ name="NameCompartment" type="UMLNameCompartmentView" guid="L/UcrqvDV0i+pv/5+mlDPgAA">
+<XPD:OBJ name="NameLabel" type="LabelView" guid="AbxeF3TtakuwZ6FeWka0AgAA">
+<XPD:ATTR name="FontStyle" type="integer">1</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">imageml</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="LabelView" guid="BwD1d/fkmkeShIVxuy3IJQAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="LabelView" guid="j8IqWkjh5kq46YEXjpicxAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="AttributeCompartment" type="UMLAttributeCompartmentView" guid="oo6cEQcGZkCg59IpDpoW1gAA">
+<XPD:REF name="Model">CRuOLYF7gU2l1tg34dY6bgAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OperationCompartment" type="UMLOperationCompartmentView" guid="ope+PrJaFkKCz0QZuJl2YAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:REF name="Model">CRuOLYF7gU2l1tg34dY6bgAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TemplateParameterCompartment" type="UMLTemplateParameterCompartmentView" guid="NS9a+EIZ60SAXPkpGONIZwAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:REF name="Model">CRuOLYF7gU2l1tg34dY6bgAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[1]" type="UMLClassView" guid="2yz5/OUBRUKzrr3xYqPQ+AAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">168</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">124</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">113</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">98</XPD:ATTR>
+<XPD:REF name="Model">CouoggW8r0OOBNQ9jNxO6wAA</XPD:REF>
+<XPD:OBJ name="NameCompartment" type="UMLNameCompartmentView" guid="fQ0P9kJJ+kmpeHUyo6QnNwAA">
+<XPD:OBJ name="NameLabel" type="LabelView" guid="QUfsG4C1ukaVCR6Tug//eAAA">
+<XPD:ATTR name="FontStyle" type="integer">1</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">output</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="LabelView" guid="VVCoDmkVv0m8PjmGurISewAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="LabelView" guid="1DwwazkW3kO3MVGw9yaGyQAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="AttributeCompartment" type="UMLAttributeCompartmentView" guid="xT3UbHUMUE6tacvQOi3vFAAA">
+<XPD:REF name="Model">CouoggW8r0OOBNQ9jNxO6wAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OperationCompartment" type="UMLOperationCompartmentView" guid="tJ6YyShrb0qkaUZTlTqLRAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:REF name="Model">CouoggW8r0OOBNQ9jNxO6wAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TemplateParameterCompartment" type="UMLTemplateParameterCompartmentView" guid="LZMFamho/k+gl1zYCKOxLAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:REF name="Model">CouoggW8r0OOBNQ9jNxO6wAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[2]" type="UMLClassView" guid="3nJAwrIQQ02ZlQ/Rjto/1wAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">180</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">260</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">93</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">85</XPD:ATTR>
+<XPD:REF name="Model">NnSa/LdMlkaJlBQz+1Y2+AAA</XPD:REF>
+<XPD:OBJ name="NameCompartment" type="UMLNameCompartmentView" guid="zuysMyW0RUqd6/W+SN01rAAA">
+<XPD:OBJ name="NameLabel" type="LabelView" guid="/A45czPohESoXvStW2E/BAAA">
+<XPD:ATTR name="FontStyle" type="integer">1</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">input</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="LabelView" guid="3L1ztUHupUCUeFvq7/RI+AAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="LabelView" guid="2Kdu5f6R806JuDXAZERIAwAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="AttributeCompartment" type="UMLAttributeCompartmentView" guid="H6NcM+PBwUShMknSOVID3QAA">
+<XPD:REF name="Model">NnSa/LdMlkaJlBQz+1Y2+AAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OperationCompartment" type="UMLOperationCompartmentView" guid="1Mo5wmxejE6FTM5akRaAdgAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:REF name="Model">NnSa/LdMlkaJlBQz+1Y2+AAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TemplateParameterCompartment" type="UMLTemplateParameterCompartmentView" guid="TdFa+ERT2kaLfVN9wUnP8QAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:REF name="Model">NnSa/LdMlkaJlBQz+1Y2+AAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[3]" type="UMLClassView" guid="faGCnxpYz0SvcMgXl5/tzgAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">140</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">404</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">86</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">46</XPD:ATTR>
+<XPD:REF name="Model">mgS5RRx5dkWAWIQMpavygAAA</XPD:REF>
+<XPD:OBJ name="NameCompartment" type="UMLNameCompartmentView" guid="hNSqP7xfY0S4AY9TyhBmWgAA">
+<XPD:OBJ name="NameLabel" type="LabelView" guid="Pkov5xD2EEOsvccOTafdmQAA">
+<XPD:ATTR name="FontStyle" type="integer">1</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">include</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="LabelView" guid="rswzDaBDGka6E21j5ExkmAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="LabelView" guid="Kc4fD1bCK0iLlISpWHgB5AAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="AttributeCompartment" type="UMLAttributeCompartmentView" guid="kn38iT7TP0G49oA5OMx2cwAA">
+<XPD:REF name="Model">mgS5RRx5dkWAWIQMpavygAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OperationCompartment" type="UMLOperationCompartmentView" guid="qFlX0PRVlkKchtOy4x8UYQAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:REF name="Model">mgS5RRx5dkWAWIQMpavygAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TemplateParameterCompartment" type="UMLTemplateParameterCompartmentView" guid="I25jxMkN8kamWC8cZlMWkQAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:REF name="Model">mgS5RRx5dkWAWIQMpavygAAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[4]" type="UMLClassView" guid="iajjxaOU7E+x5X6fMy+ongAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">240</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">404</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">80</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">46</XPD:ATTR>
+<XPD:REF name="Model">NJ7DLEDyw0+w4FnIFdtdCQAA</XPD:REF>
+<XPD:OBJ name="NameCompartment" type="UMLNameCompartmentView" guid="jvdsIn4RSEGJCQ/rWPcGxAAA">
+<XPD:OBJ name="NameLabel" type="LabelView" guid="Dp6t6Y4RcUSIAmlZJZuQHAAA">
+<XPD:ATTR name="FontStyle" type="integer">1</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">exclude</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="LabelView" guid="Fv7AgZpYgEiyiR3vQiC29gAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="LabelView" guid="4tpRLficPUyrh0vKZqNtqgAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="AttributeCompartment" type="UMLAttributeCompartmentView" guid="0jE4q+Le8U65zLfiG9DybAAA">
+<XPD:REF name="Model">NJ7DLEDyw0+w4FnIFdtdCQAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OperationCompartment" type="UMLOperationCompartmentView" guid="KkuKK1ExWUqNI4Js4lFGVwAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:REF name="Model">NJ7DLEDyw0+w4FnIFdtdCQAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TemplateParameterCompartment" type="UMLTemplateParameterCompartmentView" guid="pmgGrKsDo0iaj680s/M4SgAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:REF name="Model">NJ7DLEDyw0+w4FnIFdtdCQAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[5]" type="UMLAssociationView" guid="2AbWyaJex0OAE4+eJk3TZAAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Points" type="Points">190,404;211,344</XPD:ATTR>
+<XPD:REF name="Model">0q7RIUYseEewHATv7QqdaQAA</XPD:REF>
+<XPD:REF name="Head">3nJAwrIQQ02ZlQ/Rjto/1wAA</XPD:REF>
+<XPD:REF name="Tail">faGCnxpYz0SvcMgXl5/tzgAA</XPD:REF>
+<XPD:OBJ name="NameLabel" type="EdgeLabelView" guid="nz/ZuAL35UCRaeXVyhOpjAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">15</XPD:ATTR>
+<XPD:REF name="Model">0q7RIUYseEewHATv7QqdaQAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="EdgeLabelView" guid="V4ilVpQd7EWyZKf5QVnbWQAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">30</XPD:ATTR>
+<XPD:REF name="Model">0q7RIUYseEewHATv7QqdaQAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="EdgeLabelView" guid="M/sNRWrTkkaPJFYpWFee9AAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">-1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">15</XPD:ATTR>
+<XPD:REF name="Model">0q7RIUYseEewHATv7QqdaQAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="HeadRoleNameLabel" type="EdgeLabelView" guid="gB3opu8rBESXdIQhV59XVgAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">-0.523598775598299</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">30</XPD:ATTR>
+<XPD:ATTR name="EdgePosition" type="EdgePositionKind">epHead</XPD:ATTR>
+<XPD:REF name="Model">aOIUpy17wEu1onMvkPLDZwAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TailRoleNameLabel" type="EdgeLabelView" guid="2eQMCtC1LUSQLYX64dgcRwAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">0.523598775598299</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">30</XPD:ATTR>
+<XPD:ATTR name="EdgePosition" type="EdgePositionKind">epTail</XPD:ATTR>
+<XPD:REF name="Model">3PfRfm/wr02VIWBqM76erwAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="HeadMultiplicityLabel" type="EdgeLabelView" guid="1DClOyS2OEWUiH4oKwzpiAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">0.523598775598299</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">25</XPD:ATTR>
+<XPD:ATTR name="EdgePosition" type="EdgePositionKind">epHead</XPD:ATTR>
+<XPD:REF name="Model">aOIUpy17wEu1onMvkPLDZwAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TailMultiplicityLabel" type="EdgeLabelView" guid="c1dxawLR7EGpg2ol4F4xKgAA">
+<XPD:ATTR name="Alpha" type="real">-0.749643646812705</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">21.4709105535839</XPD:ATTR>
+<XPD:ATTR name="EdgePosition" type="EdgePositionKind">epTail</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">0..*</XPD:ATTR>
+<XPD:REF name="Model">3PfRfm/wr02VIWBqM76erwAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="HeadPropertyLabel" type="EdgeLabelView" guid="U7rCMTFn7UeJoGquwrxotAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">-0.785398163397448</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">40</XPD:ATTR>
+<XPD:ATTR name="EdgePosition" type="EdgePositionKind">epHead</XPD:ATTR>
+<XPD:REF name="Model">aOIUpy17wEu1onMvkPLDZwAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TailPropertyLabel" type="EdgeLabelView" guid="E+2944gbJ02FZkYrAvDtcgAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">0.785398163397448</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">40</XPD:ATTR>
+<XPD:ATTR name="EdgePosition" type="EdgePositionKind">epTail</XPD:ATTR>
+<XPD:REF name="Model">3PfRfm/wr02VIWBqM76erwAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="HeadQualifierCompartment" type="UMLQualifierCompartmentView" guid="E6QllHCf30Onm2SAzLaLXgAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">-1000</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">-1000</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">50</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">8</XPD:ATTR>
+<XPD:REF name="Model">aOIUpy17wEu1onMvkPLDZwAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TailQualifierCompartment" type="UMLQualifierCompartmentView" guid="OZTqZxmCcke/+xkjwB/JoQAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">-1000</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">-1000</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">50</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">8</XPD:ATTR>
+<XPD:REF name="Model">3PfRfm/wr02VIWBqM76erwAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[6]" type="UMLAssociationView" guid="m8gZrs5j0kStnzfQ61UrrgAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Points" type="Points">270,404;244,344</XPD:ATTR>
+<XPD:REF name="Model">IFIQQJ7iSEO69Wh+e5lJygAA</XPD:REF>
+<XPD:REF name="Head">3nJAwrIQQ02ZlQ/Rjto/1wAA</XPD:REF>
+<XPD:REF name="Tail">iajjxaOU7E+x5X6fMy+ongAA</XPD:REF>
+<XPD:OBJ name="NameLabel" type="EdgeLabelView" guid="4/fEL3oefk6PU+0Nze5S8wAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">15</XPD:ATTR>
+<XPD:REF name="Model">IFIQQJ7iSEO69Wh+e5lJygAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="EdgeLabelView" guid="5vqa4svcc0Comg+i8yQQxQAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">30</XPD:ATTR>
+<XPD:REF name="Model">IFIQQJ7iSEO69Wh+e5lJygAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="EdgeLabelView" guid="U366XjrXzESRB/Bieu6tmgAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">-1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">15</XPD:ATTR>
+<XPD:REF name="Model">IFIQQJ7iSEO69Wh+e5lJygAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="HeadRoleNameLabel" type="EdgeLabelView" guid="EaPwhC1GhkG4oL0wGBBZ1AAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">-0.523598775598299</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">30</XPD:ATTR>
+<XPD:ATTR name="EdgePosition" type="EdgePositionKind">epHead</XPD:ATTR>
+<XPD:REF name="Model">M1sojijAckaHORNZ6AKvSgAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TailRoleNameLabel" type="EdgeLabelView" guid="RdOeRaBBGkWsnreusrvSfwAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">0.523598775598299</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">30</XPD:ATTR>
+<XPD:ATTR name="EdgePosition" type="EdgePositionKind">epTail</XPD:ATTR>
+<XPD:REF name="Model">69rEKoPGI0mo75lP5BvwtAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="HeadMultiplicityLabel" type="EdgeLabelView" guid="SPMybHF1eUSsFaKxqWSp3AAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">0.523598775598299</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">25</XPD:ATTR>
+<XPD:ATTR name="EdgePosition" type="EdgePositionKind">epHead</XPD:ATTR>
+<XPD:REF name="Model">M1sojijAckaHORNZ6AKvSgAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TailMultiplicityLabel" type="EdgeLabelView" guid="mlyfdg+wL0q/0vLzXffvCQAA">
+<XPD:ATTR name="Alpha" type="real">4.78795835027941</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">21.4709105535839</XPD:ATTR>
+<XPD:ATTR name="EdgePosition" type="EdgePositionKind">epTail</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">0..*</XPD:ATTR>
+<XPD:REF name="Model">69rEKoPGI0mo75lP5BvwtAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="HeadPropertyLabel" type="EdgeLabelView" guid="6j00UUyF8UevCPsWi8kQ8AAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">-0.785398163397448</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">40</XPD:ATTR>
+<XPD:ATTR name="EdgePosition" type="EdgePositionKind">epHead</XPD:ATTR>
+<XPD:REF name="Model">M1sojijAckaHORNZ6AKvSgAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TailPropertyLabel" type="EdgeLabelView" guid="wRtRzltGBUK1inpq/EC8egAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">0.785398163397448</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">40</XPD:ATTR>
+<XPD:ATTR name="EdgePosition" type="EdgePositionKind">epTail</XPD:ATTR>
+<XPD:REF name="Model">69rEKoPGI0mo75lP5BvwtAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="HeadQualifierCompartment" type="UMLQualifierCompartmentView" guid="5Rj3LCxAVEWJ8f/S+pUdHQAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">-1000</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">-1000</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">50</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">8</XPD:ATTR>
+<XPD:REF name="Model">M1sojijAckaHORNZ6AKvSgAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TailQualifierCompartment" type="UMLQualifierCompartmentView" guid="w2KVtQGYrE+EMx8cVRcgugAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">-1000</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">-1000</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">50</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">8</XPD:ATTR>
+<XPD:REF name="Model">69rEKoPGI0mo75lP5BvwtAAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[7]" type="UMLAssociationView" guid="nVRV8yqOakqLSBoMvGN3XQAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="Points" type="Points">225,260;225,221</XPD:ATTR>
+<XPD:REF name="Model">POtOWRvYQ0WO9SQIvdJpeQAA</XPD:REF>
+<XPD:REF name="Head">2yz5/OUBRUKzrr3xYqPQ+AAA</XPD:REF>
+<XPD:REF name="Tail">3nJAwrIQQ02ZlQ/Rjto/1wAA</XPD:REF>
+<XPD:OBJ name="NameLabel" type="EdgeLabelView" guid="AfGmb0HBA0itzUbEcTS/DgAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">15</XPD:ATTR>
+<XPD:REF name="Model">POtOWRvYQ0WO9SQIvdJpeQAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="EdgeLabelView" guid="RQXCZc+TbUiTJrp+ECPS3QAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">30</XPD:ATTR>
+<XPD:REF name="Model">POtOWRvYQ0WO9SQIvdJpeQAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="EdgeLabelView" guid="8mRCB/h06UqRKV2aY+W3vQAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">-1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">15</XPD:ATTR>
+<XPD:REF name="Model">POtOWRvYQ0WO9SQIvdJpeQAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="HeadRoleNameLabel" type="EdgeLabelView" guid="gWzPC9cNGk2YkCCxvmViMwAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">-0.523598775598299</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">30</XPD:ATTR>
+<XPD:ATTR name="EdgePosition" type="EdgePositionKind">epHead</XPD:ATTR>
+<XPD:REF name="Model">Z/WCj9Ir1Uua8nPwAz0BOAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TailRoleNameLabel" type="EdgeLabelView" guid="Yb5TsbsoPEuXLv0a1Oa1VgAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">0.523598775598299</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">30</XPD:ATTR>
+<XPD:ATTR name="EdgePosition" type="EdgePositionKind">epTail</XPD:ATTR>
+<XPD:REF name="Model">cDxLP9sd7EqSP+9VET4kGgAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="HeadMultiplicityLabel" type="EdgeLabelView" guid="8LRKIYEdMUKDivgFqolYewAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">0.523598775598299</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">25</XPD:ATTR>
+<XPD:ATTR name="EdgePosition" type="EdgePositionKind">epHead</XPD:ATTR>
+<XPD:REF name="Model">Z/WCj9Ir1Uua8nPwAz0BOAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TailMultiplicityLabel" type="EdgeLabelView" guid="DgdfsZ/1EUaPJtwrv9oObgAA">
+<XPD:ATTR name="Alpha" type="real">-0.856705765824159</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">19.8494332412792</XPD:ATTR>
+<XPD:ATTR name="EdgePosition" type="EdgePositionKind">epTail</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">1..*</XPD:ATTR>
+<XPD:REF name="Model">cDxLP9sd7EqSP+9VET4kGgAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="HeadPropertyLabel" type="EdgeLabelView" guid="CSH1BjC5Aky2/PkypiyIHQAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">-0.785398163397448</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">40</XPD:ATTR>
+<XPD:ATTR name="EdgePosition" type="EdgePositionKind">epHead</XPD:ATTR>
+<XPD:REF name="Model">Z/WCj9Ir1Uua8nPwAz0BOAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TailPropertyLabel" type="EdgeLabelView" guid="vRJPlJAtMEa1WsFNfA8DIgAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">0.785398163397448</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">40</XPD:ATTR>
+<XPD:ATTR name="EdgePosition" type="EdgePositionKind">epTail</XPD:ATTR>
+<XPD:REF name="Model">cDxLP9sd7EqSP+9VET4kGgAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="HeadQualifierCompartment" type="UMLQualifierCompartmentView" guid="o8D1LCtfO0KT5LUKf/6RXwAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">-1000</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">-1000</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">50</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">8</XPD:ATTR>
+<XPD:REF name="Model">Z/WCj9Ir1Uua8nPwAz0BOAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TailQualifierCompartment" type="UMLQualifierCompartmentView" guid="S+RFAzInsE6oZfmlKXcr5gAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">-1000</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">-1000</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">50</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">8</XPD:ATTR>
+<XPD:REF name="Model">cDxLP9sd7EqSP+9VET4kGgAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedViews[8]" type="UMLAssociationView" guid="NzRfVxtFpkSA1aniBttYKgAA">
+<XPD:ATTR name="LineColor" type="string">clMaroon</XPD:ATTR>
+<XPD:ATTR name="FillColor" type="string">$00B9FFFF</XPD:ATTR>
+<XPD:ATTR name="LineStyle" type="LineStyleKind">lsRectilinear</XPD:ATTR>
+<XPD:ATTR name="Points" type="Points">226,124;226,72</XPD:ATTR>
+<XPD:REF name="Model">rbj+IedETU6G6PuTN46nBAAA</XPD:REF>
+<XPD:REF name="Head">/Aq0TH5t8EiVzBQ4GkGa/AAA</XPD:REF>
+<XPD:REF name="Tail">2yz5/OUBRUKzrr3xYqPQ+AAA</XPD:REF>
+<XPD:OBJ name="NameLabel" type="EdgeLabelView" guid="3oDW+x67KkKJoi/dFuoELgAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">15</XPD:ATTR>
+<XPD:REF name="Model">rbj+IedETU6G6PuTN46nBAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="StereotypeLabel" type="EdgeLabelView" guid="8mmjDm5UV0+QfL8hYUtWmQAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">30</XPD:ATTR>
+<XPD:REF name="Model">rbj+IedETU6G6PuTN46nBAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="PropertyLabel" type="EdgeLabelView" guid="8niOI1RfT0O1WPjJpU0O9wAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">-1.5707963267949</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">15</XPD:ATTR>
+<XPD:REF name="Model">rbj+IedETU6G6PuTN46nBAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="HeadRoleNameLabel" type="EdgeLabelView" guid="b9ayalGDS0arYeNwSxzJPAAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">-0.523598775598299</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">30</XPD:ATTR>
+<XPD:ATTR name="EdgePosition" type="EdgePositionKind">epHead</XPD:ATTR>
+<XPD:REF name="Model">cR78ghIdUUaPftW/gFc/yAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TailRoleNameLabel" type="EdgeLabelView" guid="FswOCQPKf0OKYV9XBXU70wAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">0.523598775598299</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">30</XPD:ATTR>
+<XPD:ATTR name="EdgePosition" type="EdgePositionKind">epTail</XPD:ATTR>
+<XPD:REF name="Model">sJQEHCEx7kGDl0V2tep+ewAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="HeadMultiplicityLabel" type="EdgeLabelView" guid="4bpVhzadBUuAYszaNIVSawAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">0.523598775598299</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">25</XPD:ATTR>
+<XPD:ATTR name="EdgePosition" type="EdgePositionKind">epHead</XPD:ATTR>
+<XPD:REF name="Model">cR78ghIdUUaPftW/gFc/yAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TailMultiplicityLabel" type="EdgeLabelView" guid="kgoOqeIDPUix8ry7KlL4IgAA">
+<XPD:ATTR name="Alpha" type="real">-0.950546986342061</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">17.2046505340853</XPD:ATTR>
+<XPD:ATTR name="EdgePosition" type="EdgePositionKind">epTail</XPD:ATTR>
+<XPD:ATTR name="Text" type="string">0..*</XPD:ATTR>
+<XPD:REF name="Model">sJQEHCEx7kGDl0V2tep+ewAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="HeadPropertyLabel" type="EdgeLabelView" guid="D6kl60xIk0OMxRE54qI91wAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">-0.785398163397448</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">40</XPD:ATTR>
+<XPD:ATTR name="EdgePosition" type="EdgePositionKind">epHead</XPD:ATTR>
+<XPD:REF name="Model">cR78ghIdUUaPftW/gFc/yAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TailPropertyLabel" type="EdgeLabelView" guid="kKyrpkZo0Eie9EpreVwklgAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Alpha" type="real">0.785398163397448</XPD:ATTR>
+<XPD:ATTR name="Distance" type="real">40</XPD:ATTR>
+<XPD:ATTR name="EdgePosition" type="EdgePositionKind">epTail</XPD:ATTR>
+<XPD:REF name="Model">sJQEHCEx7kGDl0V2tep+ewAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="HeadQualifierCompartment" type="UMLQualifierCompartmentView" guid="2ziLW5/dfkmoaaRaHu0/gwAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">-1000</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">-1000</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">50</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">8</XPD:ATTR>
+<XPD:REF name="Model">cR78ghIdUUaPftW/gFc/yAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="TailQualifierCompartment" type="UMLQualifierCompartmentView" guid="/eclq88P0Ui5/jTyRxj/3gAA">
+<XPD:ATTR name="Visible" type="boolean">False</XPD:ATTR>
+<XPD:ATTR name="Left" type="integer">-1000</XPD:ATTR>
+<XPD:ATTR name="Top" type="integer">-1000</XPD:ATTR>
+<XPD:ATTR name="Width" type="integer">50</XPD:ATTR>
+<XPD:ATTR name="Height" type="integer">8</XPD:ATTR>
+<XPD:REF name="Model">sJQEHCEx7kGDl0V2tep+ewAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:ATTR name="#OwnedElements" type="integer">9</XPD:ATTR>
+<XPD:OBJ name="OwnedElements[0]" type="UMLClass" guid="CRuOLYF7gU2l1tg34dY6bgAA">
+<XPD:ATTR name="Name" type="string">imageml</XPD:ATTR>
+<XPD:REF name="Namespace">I0mGM2cIbES/2vP45srj7AAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">/Aq0TH5t8EiVzBQ4GkGa/AAA</XPD:REF>
+<XPD:REF name="Views[1]">oo6cEQcGZkCg59IpDpoW1gAA</XPD:REF>
+<XPD:REF name="Views[2]">ope+PrJaFkKCz0QZuJl2YAAA</XPD:REF>
+<XPD:REF name="Views[3]">NS9a+EIZ60SAXPkpGONIZwAA</XPD:REF>
+<XPD:ATTR name="#Associations" type="integer">1</XPD:ATTR>
+<XPD:REF name="Associations[0]">cR78ghIdUUaPftW/gFc/yAAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedElements[1]" type="UMLClass" guid="CouoggW8r0OOBNQ9jNxO6wAA">
+<XPD:ATTR name="Name" type="string">output</XPD:ATTR>
+<XPD:REF name="Namespace">I0mGM2cIbES/2vP45srj7AAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">2yz5/OUBRUKzrr3xYqPQ+AAA</XPD:REF>
+<XPD:REF name="Views[1]">xT3UbHUMUE6tacvQOi3vFAAA</XPD:REF>
+<XPD:REF name="Views[2]">tJ6YyShrb0qkaUZTlTqLRAAA</XPD:REF>
+<XPD:REF name="Views[3]">LZMFamho/k+gl1zYCKOxLAAA</XPD:REF>
+<XPD:ATTR name="#Associations" type="integer">2</XPD:ATTR>
+<XPD:REF name="Associations[0]">Z/WCj9Ir1Uua8nPwAz0BOAAA</XPD:REF>
+<XPD:REF name="Associations[1]">sJQEHCEx7kGDl0V2tep+ewAA</XPD:REF>
+<XPD:ATTR name="#Attributes" type="integer">5</XPD:ATTR>
+<XPD:OBJ name="Attributes[0]" type="UMLAttribute" guid="y0hZBFqyCkymwVN5N5lwVAAA">
+<XPD:ATTR name="Name" type="string">file</XPD:ATTR>
+<XPD:REF name="Owner">CouoggW8r0OOBNQ9jNxO6wAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="Attributes[1]" type="UMLAttribute" guid="bwd6reYMtU6ND4/XJpWL8AAA">
+<XPD:ATTR name="Name" type="string">tool</XPD:ATTR>
+<XPD:REF name="Owner">CouoggW8r0OOBNQ9jNxO6wAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="Attributes[2]" type="UMLAttribute" guid="lCDLD1gUpkaXfqpBvznzzwAA">
+<XPD:ATTR name="Name" type="string">palette</XPD:ATTR>
+<XPD:REF name="Owner">CouoggW8r0OOBNQ9jNxO6wAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="Attributes[3]" type="UMLAttribute" guid="sGSgO0Xa90SdqTsqA4+7UwAA">
+<XPD:ATTR name="Name" type="string">extraparams</XPD:ATTR>
+<XPD:REF name="Owner">CouoggW8r0OOBNQ9jNxO6wAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="Attributes[4]" type="UMLAttribute" guid="CxwNKyYSU0i3eKo7Md6+KgAA">
+<XPD:ATTR name="Name" type="string">tooldir</XPD:ATTR>
+<XPD:REF name="Owner">CouoggW8r0OOBNQ9jNxO6wAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedElements[2]" type="UMLClass" guid="NnSa/LdMlkaJlBQz+1Y2+AAA">
+<XPD:ATTR name="Name" type="string">input</XPD:ATTR>
+<XPD:REF name="Namespace">I0mGM2cIbES/2vP45srj7AAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">3nJAwrIQQ02ZlQ/Rjto/1wAA</XPD:REF>
+<XPD:REF name="Views[1]">H6NcM+PBwUShMknSOVID3QAA</XPD:REF>
+<XPD:REF name="Views[2]">1Mo5wmxejE6FTM5akRaAdgAA</XPD:REF>
+<XPD:REF name="Views[3]">TdFa+ERT2kaLfVN9wUnP8QAA</XPD:REF>
+<XPD:ATTR name="#Associations" type="integer">3</XPD:ATTR>
+<XPD:REF name="Associations[0]">aOIUpy17wEu1onMvkPLDZwAA</XPD:REF>
+<XPD:REF name="Associations[1]">M1sojijAckaHORNZ6AKvSgAA</XPD:REF>
+<XPD:REF name="Associations[2]">cDxLP9sd7EqSP+9VET4kGgAA</XPD:REF>
+<XPD:ATTR name="#Attributes" type="integer">4</XPD:ATTR>
+<XPD:OBJ name="Attributes[0]" type="UMLAttribute" guid="ZrqxvCV3q0aWkeuIJCQ/hwAA">
+<XPD:ATTR name="Name" type="string">dir</XPD:ATTR>
+<XPD:REF name="Owner">NnSa/LdMlkaJlBQz+1Y2+AAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="Attributes[1]" type="UMLAttribute" guid="jcCl83kZnESgDACCIY44ewAA">
+<XPD:ATTR name="Name" type="string">file</XPD:ATTR>
+<XPD:REF name="Owner">NnSa/LdMlkaJlBQz+1Y2+AAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="Attributes[2]" type="UMLAttribute" guid="l549RJF9Uku4tJAfmVNfRAAA">
+<XPD:ATTR name="Name" type="string">depth</XPD:ATTR>
+<XPD:REF name="Owner">NnSa/LdMlkaJlBQz+1Y2+AAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="Attributes[3]" type="UMLAttribute" guid="7We+4s0A+0uhw6I7fJUWZgAA">
+<XPD:ATTR name="Name" type="string">optional</XPD:ATTR>
+<XPD:REF name="Owner">NnSa/LdMlkaJlBQz+1Y2+AAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedElements[3]" type="UMLClass" guid="mgS5RRx5dkWAWIQMpavygAAA">
+<XPD:ATTR name="Name" type="string">include</XPD:ATTR>
+<XPD:REF name="Namespace">I0mGM2cIbES/2vP45srj7AAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">faGCnxpYz0SvcMgXl5/tzgAA</XPD:REF>
+<XPD:REF name="Views[1]">kn38iT7TP0G49oA5OMx2cwAA</XPD:REF>
+<XPD:REF name="Views[2]">qFlX0PRVlkKchtOy4x8UYQAA</XPD:REF>
+<XPD:REF name="Views[3]">I25jxMkN8kamWC8cZlMWkQAA</XPD:REF>
+<XPD:ATTR name="#Associations" type="integer">1</XPD:ATTR>
+<XPD:REF name="Associations[0]">3PfRfm/wr02VIWBqM76erwAA</XPD:REF>
+<XPD:ATTR name="#Attributes" type="integer">1</XPD:ATTR>
+<XPD:OBJ name="Attributes[0]" type="UMLAttribute" guid="FzFjeSzkrkW8MvZB5XA6EQAA">
+<XPD:ATTR name="Name" type="string">pattern</XPD:ATTR>
+<XPD:REF name="Owner">mgS5RRx5dkWAWIQMpavygAAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedElements[4]" type="UMLClass" guid="NJ7DLEDyw0+w4FnIFdtdCQAA">
+<XPD:ATTR name="Name" type="string">exclude</XPD:ATTR>
+<XPD:REF name="Namespace">I0mGM2cIbES/2vP45srj7AAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">iajjxaOU7E+x5X6fMy+ongAA</XPD:REF>
+<XPD:REF name="Views[1]">0jE4q+Le8U65zLfiG9DybAAA</XPD:REF>
+<XPD:REF name="Views[2]">KkuKK1ExWUqNI4Js4lFGVwAA</XPD:REF>
+<XPD:REF name="Views[3]">pmgGrKsDo0iaj680s/M4SgAA</XPD:REF>
+<XPD:ATTR name="#Associations" type="integer">1</XPD:ATTR>
+<XPD:REF name="Associations[0]">69rEKoPGI0mo75lP5BvwtAAA</XPD:REF>
+<XPD:ATTR name="#Attributes" type="integer">1</XPD:ATTR>
+<XPD:OBJ name="Attributes[0]" type="UMLAttribute" guid="dbFbN2LF4kK3rC1gNYjgiAAA">
+<XPD:ATTR name="Name" type="string">pattern</XPD:ATTR>
+<XPD:REF name="Owner">NJ7DLEDyw0+w4FnIFdtdCQAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedElements[5]" type="UMLAssociation" guid="0q7RIUYseEewHATv7QqdaQAA">
+<XPD:REF name="Namespace">I0mGM2cIbES/2vP45srj7AAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">2AbWyaJex0OAE4+eJk3TZAAA</XPD:REF>
+<XPD:REF name="Views[1]">nz/ZuAL35UCRaeXVyhOpjAAA</XPD:REF>
+<XPD:REF name="Views[2]">V4ilVpQd7EWyZKf5QVnbWQAA</XPD:REF>
+<XPD:REF name="Views[3]">M/sNRWrTkkaPJFYpWFee9AAA</XPD:REF>
+<XPD:ATTR name="#Connections" type="integer">2</XPD:ATTR>
+<XPD:OBJ name="Connections[0]" type="UMLAssociationEnd" guid="3PfRfm/wr02VIWBqM76erwAA">
+<XPD:ATTR name="Multiplicity" type="string">0..*</XPD:ATTR>
+<XPD:REF name="Association">0q7RIUYseEewHATv7QqdaQAA</XPD:REF>
+<XPD:REF name="Participant">mgS5RRx5dkWAWIQMpavygAAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">2eQMCtC1LUSQLYX64dgcRwAA</XPD:REF>
+<XPD:REF name="Views[1]">c1dxawLR7EGpg2ol4F4xKgAA</XPD:REF>
+<XPD:REF name="Views[2]">E+2944gbJ02FZkYrAvDtcgAA</XPD:REF>
+<XPD:REF name="Views[3]">OZTqZxmCcke/+xkjwB/JoQAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="Connections[1]" type="UMLAssociationEnd" guid="aOIUpy17wEu1onMvkPLDZwAA">
+<XPD:ATTR name="Aggregation" type="UMLAggregationKind">akAggregate</XPD:ATTR>
+<XPD:REF name="Association">0q7RIUYseEewHATv7QqdaQAA</XPD:REF>
+<XPD:REF name="Participant">NnSa/LdMlkaJlBQz+1Y2+AAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">gB3opu8rBESXdIQhV59XVgAA</XPD:REF>
+<XPD:REF name="Views[1]">1DClOyS2OEWUiH4oKwzpiAAA</XPD:REF>
+<XPD:REF name="Views[2]">U7rCMTFn7UeJoGquwrxotAAA</XPD:REF>
+<XPD:REF name="Views[3]">E6QllHCf30Onm2SAzLaLXgAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedElements[6]" type="UMLAssociation" guid="IFIQQJ7iSEO69Wh+e5lJygAA">
+<XPD:REF name="Namespace">I0mGM2cIbES/2vP45srj7AAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">m8gZrs5j0kStnzfQ61UrrgAA</XPD:REF>
+<XPD:REF name="Views[1]">4/fEL3oefk6PU+0Nze5S8wAA</XPD:REF>
+<XPD:REF name="Views[2]">5vqa4svcc0Comg+i8yQQxQAA</XPD:REF>
+<XPD:REF name="Views[3]">U366XjrXzESRB/Bieu6tmgAA</XPD:REF>
+<XPD:ATTR name="#Connections" type="integer">2</XPD:ATTR>
+<XPD:OBJ name="Connections[0]" type="UMLAssociationEnd" guid="69rEKoPGI0mo75lP5BvwtAAA">
+<XPD:ATTR name="Multiplicity" type="string">0..*</XPD:ATTR>
+<XPD:REF name="Association">IFIQQJ7iSEO69Wh+e5lJygAA</XPD:REF>
+<XPD:REF name="Participant">NJ7DLEDyw0+w4FnIFdtdCQAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">RdOeRaBBGkWsnreusrvSfwAA</XPD:REF>
+<XPD:REF name="Views[1]">mlyfdg+wL0q/0vLzXffvCQAA</XPD:REF>
+<XPD:REF name="Views[2]">wRtRzltGBUK1inpq/EC8egAA</XPD:REF>
+<XPD:REF name="Views[3]">w2KVtQGYrE+EMx8cVRcgugAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="Connections[1]" type="UMLAssociationEnd" guid="M1sojijAckaHORNZ6AKvSgAA">
+<XPD:ATTR name="Aggregation" type="UMLAggregationKind">akAggregate</XPD:ATTR>
+<XPD:REF name="Association">IFIQQJ7iSEO69Wh+e5lJygAA</XPD:REF>
+<XPD:REF name="Participant">NnSa/LdMlkaJlBQz+1Y2+AAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">EaPwhC1GhkG4oL0wGBBZ1AAA</XPD:REF>
+<XPD:REF name="Views[1]">SPMybHF1eUSsFaKxqWSp3AAA</XPD:REF>
+<XPD:REF name="Views[2]">6j00UUyF8UevCPsWi8kQ8AAA</XPD:REF>
+<XPD:REF name="Views[3]">5Rj3LCxAVEWJ8f/S+pUdHQAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedElements[7]" type="UMLAssociation" guid="POtOWRvYQ0WO9SQIvdJpeQAA">
+<XPD:REF name="Namespace">I0mGM2cIbES/2vP45srj7AAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">nVRV8yqOakqLSBoMvGN3XQAA</XPD:REF>
+<XPD:REF name="Views[1]">AfGmb0HBA0itzUbEcTS/DgAA</XPD:REF>
+<XPD:REF name="Views[2]">RQXCZc+TbUiTJrp+ECPS3QAA</XPD:REF>
+<XPD:REF name="Views[3]">8mRCB/h06UqRKV2aY+W3vQAA</XPD:REF>
+<XPD:ATTR name="#Connections" type="integer">2</XPD:ATTR>
+<XPD:OBJ name="Connections[0]" type="UMLAssociationEnd" guid="cDxLP9sd7EqSP+9VET4kGgAA">
+<XPD:ATTR name="Multiplicity" type="string">1..*</XPD:ATTR>
+<XPD:REF name="Association">POtOWRvYQ0WO9SQIvdJpeQAA</XPD:REF>
+<XPD:REF name="Participant">NnSa/LdMlkaJlBQz+1Y2+AAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">Yb5TsbsoPEuXLv0a1Oa1VgAA</XPD:REF>
+<XPD:REF name="Views[1]">DgdfsZ/1EUaPJtwrv9oObgAA</XPD:REF>
+<XPD:REF name="Views[2]">vRJPlJAtMEa1WsFNfA8DIgAA</XPD:REF>
+<XPD:REF name="Views[3]">S+RFAzInsE6oZfmlKXcr5gAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="Connections[1]" type="UMLAssociationEnd" guid="Z/WCj9Ir1Uua8nPwAz0BOAAA">
+<XPD:ATTR name="Aggregation" type="UMLAggregationKind">akAggregate</XPD:ATTR>
+<XPD:REF name="Association">POtOWRvYQ0WO9SQIvdJpeQAA</XPD:REF>
+<XPD:REF name="Participant">CouoggW8r0OOBNQ9jNxO6wAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">gWzPC9cNGk2YkCCxvmViMwAA</XPD:REF>
+<XPD:REF name="Views[1]">8LRKIYEdMUKDivgFqolYewAA</XPD:REF>
+<XPD:REF name="Views[2]">CSH1BjC5Aky2/PkypiyIHQAA</XPD:REF>
+<XPD:REF name="Views[3]">o8D1LCtfO0KT5LUKf/6RXwAA</XPD:REF>
+</XPD:OBJ>
+</XPD:OBJ>
+<XPD:OBJ name="OwnedElements[8]" type="UMLAssociation" guid="rbj+IedETU6G6PuTN46nBAAA">
+<XPD:REF name="Namespace">I0mGM2cIbES/2vP45srj7AAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">NzRfVxtFpkSA1aniBttYKgAA</XPD:REF>
+<XPD:REF name="Views[1]">3oDW+x67KkKJoi/dFuoELgAA</XPD:REF>
+<XPD:REF name="Views[2]">8mmjDm5UV0+QfL8hYUtWmQAA</XPD:REF>
+<XPD:REF name="Views[3]">8niOI1RfT0O1WPjJpU0O9wAA</XPD:REF>
+<XPD:ATTR name="#Connections" type="integer">2</XPD:ATTR>
+<XPD:OBJ name="Connections[0]" type="UMLAssociationEnd" guid="sJQEHCEx7kGDl0V2tep+ewAA">
+<XPD:ATTR name="Multiplicity" type="string">0..*</XPD:ATTR>
+<XPD:REF name="Association">rbj+IedETU6G6PuTN46nBAAA</XPD:REF>
+<XPD:REF name="Participant">CouoggW8r0OOBNQ9jNxO6wAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">FswOCQPKf0OKYV9XBXU70wAA</XPD:REF>
+<XPD:REF name="Views[1]">kgoOqeIDPUix8ry7KlL4IgAA</XPD:REF>
+<XPD:REF name="Views[2]">kKyrpkZo0Eie9EpreVwklgAA</XPD:REF>
+<XPD:REF name="Views[3]">/eclq88P0Ui5/jTyRxj/3gAA</XPD:REF>
+</XPD:OBJ>
+<XPD:OBJ name="Connections[1]" type="UMLAssociationEnd" guid="cR78ghIdUUaPftW/gFc/yAAA">
+<XPD:ATTR name="Aggregation" type="UMLAggregationKind">akAggregate</XPD:ATTR>
+<XPD:REF name="Association">rbj+IedETU6G6PuTN46nBAAA</XPD:REF>
+<XPD:REF name="Participant">CRuOLYF7gU2l1tg34dY6bgAA</XPD:REF>
+<XPD:ATTR name="#Views" type="integer">4</XPD:ATTR>
+<XPD:REF name="Views[0]">b9ayalGDS0arYeNwSxzJPAAA</XPD:REF>
+<XPD:REF name="Views[1]">4bpVhzadBUuAYszaNIVSawAA</XPD:REF>
+<XPD:REF name="Views[2]">D6kl60xIk0OMxRE54qI91wAA</XPD:REF>
+<XPD:REF name="Views[3]">2ziLW5/dfkmoaaRaHu0/gwAA</XPD:REF>
 </XPD:OBJ>
 </XPD:OBJ>
 </XPD:OBJ>
--- a/configurationengine/doc/plugins/ruleml-plugin/ruleplugin.rst	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/doc/plugins/ruleml-plugin/ruleplugin.rst	Tue Aug 10 14:29:28 2010 +0300
@@ -1,163 +1,262 @@
 User guide for Rule Plugin usage in ConE
-----------------------------------------
+========================================
+
+.. note::
+    RuleML v3 is now the officially supported RuleML version.
+    Support for versions 1 and 2 is still present in ConE, but they will not
+    be maintained anymore. If you have e.g. a RuleML v2 file and require some
+    new functionality, the new functionality will be added to RuleML v3 and
+    you will need to update your RuleML file to use version 3.
+    
+    Updating should be easy, since the biggest change is setting reference
+    syntax. Simply add ``${}`` around all setting references in the rules.
 
 Introduction
-'''''''''''''
-This page describes how to use ConE Rule plugin. With rule plugin one may set rule configuration 
-for the values in the confml. So for ex. one may have a case where is one confml value is been setted
-and one may create a rule configuration that if this value is for ex. 'foo' then some other value is
-'bar'. Value may be required or configures. 
+------------
+This page describes how to use the ConE Rule plugin. The plug-in provides
+support for RuleML files, which can be used to execute rules during output
+generation. The main use for RuleML is modifying the values of ConfML settings
+on run-time based on the values of other settings.
 
+The rule plug-in registers the ImplML namespace for defining rules, and the
+RuleML-specific file extension:
 
-Creating a rule configuration file
-''''''''''''''''''''''''''''''''''
-Create a new file a example.ruleml and set it's file encoding to UTF-8.
-Place the file in the impml folder in configuration project.
-The file is a XML base file. 
-First set the encoding tag 
+  * Namespace: ``http://www.s60.com/xml/ruleml/3``
+  * File extension: ``ruleml``
+
+.. note::
+
+   More information about :ref:`file extensions <implml-file-extensions>`. 
+
+Usage
+-----
+
+A RuleML file is simply an XML file that defines a set of rules. For example:
 
 .. code-block:: xml
 
-  <?xml version="1.0" encoding="UTF-8"?>* 
+    <?xml version="1.0" encoding="UTF-8"?>
+    <ruleml xmlns="http://www.s60.com/xml/ruleml/3">
+        <rule>${SomeFeature.SomeSetting} == 'testing' configures ${SomeFeature.SomeOtherSetting} = 5</rule>
+        <rule>${SomeFeature.SomeSetting} == 'xyz' configures ${SomeFeature.SomeOtherSetting} = 6</rule>
+    </ruleml>
 
-and then create a root tag
+The above example sets the value of the setting ``SomeFeature.SomeOtherSetting``
+to the integer value ``5`` or ``6`` if the value of ``SomeFeature.SomeSetting`` is
+one of the strings ``testing`` or ``xyz``.
+
+Rules can also contain multiple operations in a single rule, and can span
+multiple lines to make the rule more readable. For example:
 
 .. code-block:: xml
 
-  <ruleml xmlns="http://www.s60.com/xml/ruleml/1">*
- 
-give a set of rules for ex. 
- 
-.. code-block:: xml
+    <?xml version="1.0" encoding="UTF-8"?>
+    <ruleml xmlns="http://www.s60.com/xml/ruleml/3">
+        <rule>
+            ${SomeFeature.SomeSetting} == 'testing' configures
+                ${SomeFeature.SomeOtherSetting} = 5 and
+                ${SomeFeature.SomeOtherSetting2} = 6 and
+                ${SomeFeature.SomeOtherSetting3} = 7
+        </rule>
+    </ruleml>
 
-  <rule>mms.imagesize == 'large' configures pd.ref1 = True and pd.ref2 = True</rule>*
- 
-and close the ruleml tag.
-
-One may say use several boolean operators for the configuration rule like for ex.
- 
-.. code-block:: xml
-
-  and, or, ==, !=* 
- 
-Like for ex.
+Sometimes the case is that the rule should be executed always, regardless of
+the values of any other settings. To do this you can simply specify ``True``
+as the left-hand side expression:
 
 .. code-block:: xml
 
-  <rule>mms.imagesize == 'large' configures pd.ref1 = True and pd.ref2 = True</rule>*
+    <?xml version="1.0" encoding="UTF-8"?>
+    <ruleml xmlns="http://www.s60.com/xml/ruleml/3">
+        <rule>True configures ${SomeFeature.SomeOtherSetting} = 'Hello!'</rule>
+    </ruleml>
+
+Python expressions in rules
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+RuleML has an extension to the basic rule syntax, which allows any `Python <http://www.python.org/doc/2.5/>`_
+expressions to be used. These can be used to create more complex logic into
+rules than is possible with standard rule expressions. The Python expressions
+are defined between ``{%`` and ``%}``, and can be used in place of normal
+value expressions.
+
+You can access global ruleml namespace, from which you can find Configuration and Generation Context of the active execution.
+
+ * ruleml.configuration - links to `Configuration <../../../docbuild/epydoc/cone.public.api.Configuration-class.html>`_ object.
+ * ruleml.context - links to `Generation Context <../../../docbuild/epydoc/cone.public.plugin.GenerationContext-class.html>`_ object.
  
-means that if reference link mms/imagesize  in some confml file is set to large then reference 
-link pd/ref1 value is true and pd/ref2 value is set to true also.
 
-**All in all one may create a dependency like project configuration with ruleml files.**  
-
-Ruleml version 2 adds support for calling `Python <http://www.python.org/doc/2.5/>`_ expressions from rules. Python expression are defined between ``{%`` and ``%}``:
+*Examples of using Python scripts inside ruleml files:*
 
 .. code-block:: xml
 
-  <rule>feat1.setting2 == True configures feat2.setting2 = {% ${feat3.setting2} %}</rule>
-
-Expression return a result, that can be used in rule e.g. to set a value to some setting in configuration. These expression can be used to create more complex logic into rules that is not possible with standard rule expressions. Inside eval expressions features and feature's values can be accessed by following syntax:
-
-Accesses to the value::
+    <?xml version="1.0" encoding="UTF-8"?>
+    <ruleml xmlns="http://www.s60.com/xml/ruleml/3">
+        <rule>
+            True configures ${SomeFeature.SomeOtherSetting} = {% 2 ** 16 %}
+        </rule>
+    </ruleml>
 
-  ${Feature.Setting}
-
-Accesses to the feature object::
+This sets the value of ``SomeFeature.SomeOtherSetting`` to the evaluated value
+of the Python expression ``2 ** 16``, which is 65536.
 
-  @{Feature.Setting}
-
-Python functions or constants that can be accessed inside expressions can be defined by ``<eval_globals>`` elements:
+Obviously, simple expressions like this cannot do much, but an expression can
+also be a function call, and functions can do almost anything. Functions (and 
+also any other globals) can be specified using ``<eval_globals>`` elements.
+For example:
 
 .. code-block:: xml
 
-  <eval_globals>
-  def my_function1(attribute):
-      return attribute + 1
-  </eval_globals>
-  
-  <eval_globals>CONST_1 = "my constant"</eval_globals>
-  
-  <eval_globals file=".scripts/evals_in_file.py"/>
-  
-Definitions can be inside <eval_globals> elements or definitions can be in separate file referenced with ``file`` attribute.
-The path specified in this attribute is relative to the RuleML implementation file. So, for example, if your implementation
-file's location is ``some/layer/implml/my_rules.ruleml``, the actual path specified in the above example would be
-``some/layer/implml/.scripts/evals_in_file.py``. It is recommended to place the scripts under a directory beginning
-with a dot, so that the plug-in loader does not attempt to load the .py file as an implementation (files and directories beginning
-with a dot are ignored in the implementation loading phase).
+    <?xml version="1.0" encoding="UTF-8"?>
+    <ruleml xmlns="http://www.s60.com/xml/ruleml/3">
+        <rule>
+            True configures ${SomeFeature.SomeOtherSetting} = {% power(2, 16) %}
+        </rule>
+        <eval_globals>
+    def power(x, y):
+        result = 1
+        for i in xrange(y):
+            result *= x
+        return result
+        </eval_globals>
+    </ruleml>
+
+This does the same thing as the previous example, except that it uses a custom
+function to do it.
+
+It is also possible to use standard Python libraries or the
+`ConE API <../../epydoc/index.html>`_ from ``<eval_globals>``, and also
+some RuleML-specific things. Ruleml has all data from 
+Configuration and Generation Context classes of the active execution. For example:
+
+.. code-block:: xml
 
-Running
-'''''''''''''''''''''
-
-::
-
-  cone generate -p someproject.cpf -o c:/temp/coneoutput -i rulemlfile.ruleml
+    <?xml version="1.0" encoding="UTF-8"?>
+    <ruleml xmlns="http://www.s60.com/xml/ruleml/3">
+        <rule>
+            True configures ${SomeFeature.SomeOtherSetting} = {% power(2, 16) %}
+        </rule>
+        <eval_globals>
+    # Import the standard library urllib2 to do operations on URLs
+    import urllib2
+    
+    # Import the ConE API
+    from cone.public import api
+    
+    def get_project_path():
+        # The current configuration is available in ruleml.configuration
+        config = ruleml.configuration
+        
+        # Return the path of the storage the current project is in
+        project = config.get_project()
+        return project.storage.get_path()
+        </eval_globals>
+    </ruleml>
+    
 
-Generates files out of configuration file and takes the implementation rulemlfile.ruleml in concern,
-and the output is to been set to -o given folder 
-
-for more example see the cone documentation
+In this example configuration is got from ruleml. Generation Context can be 
+accessed in the same way, ruleml.context will have all data stored in the 
+Generation Context object.
 
-Examples
-'''''''''
+Generation Context values can be accessed inside the Python expressions using the
+ruleml.context like ruleml.context.output.
 
-
-**Ruleml version 1 file example**
+This example uses the Generation Context to get defined output folder. 
+See how to access the data from the code example below.
 
 .. code-block:: xml
 
-  <?xml version="1.0" encoding="UTF-8"?>
-  <ruleml xmlns="http://www.s60.com/xml/ruleml/1">
-  <rule>imaker.imagetarget configures imakerapi.outputLocation = imaker.imagetarget</rule>
-  <rule>mms.imagesize == 'large' configures pd.ref1 = True and pd.ref2 = True</rule>
-  <rule>mms.imagesize == 'small' configures pd.ref1 = False and pd.ref2 = True</rule>
-  <rule>mms.imagesize == 'extrasmall' configures pd.ref1 = False and pd.ref2 = False</rule>
-  <rule>mms.imagesize == 'extralarge' configures pd.ref1 = True and pd.ref2 = False</rule>
-  </ruleml>
-
-**What do the example ruleml file means**
-
-The example file set the values upon the image size. First it sets the iMaker output
-location target and then it starts to set the mms message image size settings. So if for ex.
-*mms/imagesize* refence link value in confml file is set to *extralarge* then the value of
-*pd/ref1* is set to *true* and the value *pd/ref2* is set to false.
+    <?xml version="1.0" encoding="UTF-8"?>
+    <ruleml xmlns="http://www.s60.com/xml/ruleml/3">
+        <rule>
+            True configures ${SomeFeature.output} = {% get_output_folder() %}
+        </rule>
+        <eval_globals>
+          
+    def get_output_folder():
+        output = ruleml.context.output
+        return output
+        </eval_globals>
+    </ruleml>
 
 
-**Ruleml version 2 file example**
+Accessing ConfML values inside Python expressions
+'''''''''''''''''''''''''''''''''''''''''''''''''
+
+ConfML setting values can be accessed inside the Python expressions using the
+same notation as elsewhere in the rules, i.e. using ``${`` and ``}``.
+For example:
+
+.. code-block:: xml
+
+    <?xml version="1.0" encoding="UTF-8"?>
+    <ruleml xmlns="http://www.s60.com/xml/ruleml/3">
+        <rule>
+            ${SomeFeature.SomeSetting} == 'testing' configures ${SomeFeature.SomeOtherSetting} = {% ${SomeFeature.SomeSetting}.upper() %}
+        </rule>
+    </ruleml>
+
+This sets the value of ``SomeFeature.SomeOtherSetting`` to 'TESTING'.
+
+Accessing feature objects inside Python expressions
+'''''''''''''''''''''''''''''''''''''''''''''''''''
+
+Sometimes it is necessary to access the actual feature (or setting) object that
+ConE uses internally to perform more complex operations. This can be done
+similarly to accessing the setting values, the only difference is that the
+setting reference needs to be surrounded by ``@{}``. For example:
 
 .. code-block:: xml
 
-  <?xml version="1.0" encoding="UTF-8"?>
-  <ruleml xmlns="http://www.s60.com/xml/ruleml/2">
-  <rule>feat1.setting1 == 'somevalue' configures feat2.setting1 = {% len( ${feat3.setting1} ) %}</rule>
-  <rule>feat1.setting2 == True configures feat2.setting2 = {% my_function1( ${feat3.setting2} ) %}</rule>
-  <rule>feat1.setting3 == True configures feat2.setting3 = {% CONST_1 %}</rule>
-  <rule>{% my_function2( ${feat1.setting4} ) %} configures feat2.setting4 = False</rule>
-  <rule>{% @{feat1.setting5}.get_type() %} == 'int' configures feat2.setting5 = 'integer'</rule>
-  <rule>feat1.setting6 == True configures feat2.setting6 = {% '0x%08X' % ${feat2.setting6} %}</rule>
-  <eval_globals>
-  def my_function1(attribute):
-      return attribute + 1
-  def my_function2(attribute):
-      if attribute == 'abc':
-          return True
-      else:
-          return False
-  </eval_globals>
-  <eval_globals>
-  CONST_1 = "my constant"
-  </eval_globals>
-  <eval_globals file=".scripts/evals_in_file.py"/>
-  </ruleml>
+    <?xml version="1.0" encoding="UTF-8"?>
+    <ruleml xmlns="http://www.s60.com/xml/ruleml/3">
+        <rule>
+            True configures ${SomeFeature.SomeOtherSetting} = {% get_location(@{SomeFeature.SomeSetting}) %}
+        </rule>
+        <eval_globals>
+    from cone.public import api
+    
+    def get_location(setting):
+        parent_config = setting._find_parent(type=api.Configuration)
+        return parent_config.get_path()
+        </eval_globals>
+    </ruleml>
+
+This example uses the ConE API to find the location (ConfML file) where the
+given setting is defined.
+
+
+Defining functions in a separate .py file
+'''''''''''''''''''''''''''''''''''''''''
+
+Defining the Python functions used in the rules in an ``<eval_globals>`` element
+can quickly become unwieldy for larger functions:
 
-XSD
-'''''''''
+- Things like ``<`` need to escaped using the corresponding XML entity references
+- Syntax highlighting is not available
+- Writing and running unit tests for the functions is not possible
+
+For these reasons, the code of an ``<eval_globals>`` element can also be
+specified in a separate Python file using the ``file`` attribute. For example:
+
+.. code-block:: xml
 
-Ruleml version 1: :download:`ruleml.xsd </xsd/ruleml.xsd>`
+    <?xml version="1.0" encoding="UTF-8"?>
+    <ruleml xmlns="http://www.s60.com/xml/ruleml/3">
+        <rule>
+            True configures ${SomeFeature.SomeOtherSetting} = {% some_very_complex_operation(
+                @{SomeFeature.SomeSetting1},
+                ${SomeFeature.SomeSetting2},
+                ${SomeFeature.SomeSetting3}) %}
+        </rule>
+        <eval_globals file="scripts/complex_function.py"/>
+    </ruleml>
 
-Ruleml version 2: :download:`ruleml2.xsd </xsd/ruleml2.xsd>`
+The path specified in the ``file`` attribute is relative to the implementation
+file where the rule is specified, so if the RuleML file in this example was
+located in ``assets/example/implml/some_rule.ruleml``, the referenced Python
+file would be ``assets/example/implml/scripts/complex_function.py``.
 
 FAQ
-'''''''''
-This will be updated based on the questions.
+---
+This will be updated based on any questions.
--- a/configurationengine/doc/plugins/templateml-plugin/templatemlplugin.rst	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/doc/plugins/templateml-plugin/templatemlplugin.rst	Tue Aug 10 14:29:28 2010 +0300
@@ -72,7 +72,7 @@
 output element
 **************************
 
-Output element describes how one output file is generated. Output has one mandatory attribute 'file' that defines filename for output file. If you want to generate output file to some other than default folder, it can be done by defining a output directory to 'dir' attribute. Default encoding for output file is 'UTF-8', if some other encoding is wanted, it can be defined by 'encoding' attribute.  This encoding should be one of the standard Python codecs encoding (see http://docs.python.org/library/codecs.html#standard-encodings).
+Output element describes how one output file is generated. Output has one mandatory attribute 'file' that defines filename for output file. If you want to generate output file to some other than default folder, it can be done by defining a output directory to 'dir' attribute. Default encoding for output file is 'UTF-8', if some other encoding is wanted, it can be defined by 'encoding' attribute.  This encoding should be one of the standard Python codecs encoding (see http://docs.python.org/library/codecs.html#standard-encodings). By 'newline' attribute the output file's newline characters can be defined. The default value is 'unix' that use LF (Line feed, '\n', 0x0A) in output file. LF is used Unix-like systems and web applications. If output file has to use CR (Carriage Return) followed by LF (CR+LF, '\r\n', 0x0D 0x0A) as newline characters, 'newline' attribute should have value 'win'. CR+LF is used in non-Unix systems like DOS, Windows and Symbian OS.
 
 Template element is mandatory child element for output element. One output element can have only one template element.
 Output element can also contain optional filter elements that are specific just for this output file. Global filters that are common for all output files should be defined under root templateml element. 
@@ -81,7 +81,7 @@
 
 .. code-block:: xml
 
-  <output file="my_output.txt" encoding="UTF-8" dir="output">
+  <output file="my_output.txt" encoding="UTF-8" dir="output" newline="win">
     <template>Hello world!</template>
     <filter name="filter1">lambda a,b: a+b</filter>
     <filter name="filter2">lambda a,b: a*b</filter>
--- a/configurationengine/doc/xsd/confml2.xsd	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/doc/xsd/confml2.xsd	Tue Aug 10 14:29:28 2010 +0300
@@ -1,274 +1,274 @@
-<?xml version="1.0" encoding="utf-8"?>
-	<!--
-		Scheme according to 0.84 2.6.2008 Draft s60configurationml.doc 11.08.
-		2008 initial version hajduivo 2008-08-14 hajduivo update: xlink
-		added,but generated xml files contains wrong prefix at xlink
-		attributes 2008-08-15 hajduivo update: XInclude added
-	-->
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
-	xmlns:tns="http://www.s60.com/xml/confml/2" xmlns:xlink="http://www.w3.org/1999/xlink"
-	xmlns:xi="http://www.w3.org/2001/XInclude" targetNamespace="http://www.s60.com/xml/confml/2"
-	elementFormDefault="qualified" attributeFormDefault="unqualified">
-	<xs:import id="xlink" namespace="http://www.w3.org/1999/xlink"
-		schemaLocation="xlink.xsd" />
-	<xs:import id="xs" namespace="http://www.w3.org/2001/XMLSchema"
-		schemaLocation="XMLSchema.xsd" />
-	<xs:import namespace="http://www.w3.org/2001/XInclude"
-		schemaLocation="XInclude.xsd" />
-		
-	<!-- Fixed Elements -->
-	<xs:element name="configuration" type="tns:configurationType" />
-	<xs:element name="meta" type="tns:metaType" />
-	<xs:element name="desc" type="tns:descType" />
-	<xs:element name="icon" type="tns:iconType" />
-	<xs:element name="view" type="tns:viewType" />
-	<xs:element name="group" type="tns:groupType" />
-	<xs:element name="feature" type="tns:featureType" />
-	<xs:element name="setting" type="tns:settingType" />
-	<xs:element name="data" type="tns:dataType" />
-	<xs:element name="rfs" type="tns:rfsType" />
-	<xs:element name="link" type="tns:linkType" />
-	<xs:element name="option" type="tns:optionType" />
-	<xs:element name="property" type="tns:propertyType" />
-	<xs:element name="localPath" type="tns:localTargetPathType"/>
-	<xs:element name="targetPath" type="tns:localTargetPathType"/>
-	<xs:complexType name="configurationType">
-		<xs:choice minOccurs="0" maxOccurs="unbounded">
-			<xs:element ref="tns:meta" />
-			<xs:element ref="tns:desc" />
-			<xs:element ref="tns:icon" />
-			<xs:element ref="tns:view" />
-			<xs:element ref="tns:feature" />
-			<xs:element ref="tns:link" />
-			<xs:element ref="tns:data" />
-			<xs:element ref="tns:rfs" />
-			<xs:element	ref="tns:configuration" />
-			<xs:element ref="xi:include"/>
-		</xs:choice>
-		<xs:attribute name="version" type="xs:NMTOKEN" />
-		<xs:attribute name="name" type="xs:string" />
-		<xs:attributeGroup ref="tns:CommonAttrs"></xs:attributeGroup>
-	</xs:complexType>
-	<xs:complexType name="metaType">
-		<xs:all>
-			<xs:element name="id" type="tns:idType" minOccurs="0" />
-			<xs:element name="date" type="tns:dateType" maxOccurs="1"
-				minOccurs="0" />
-			<xs:element name="owner" type="tns:ownerType" maxOccurs="1"
-				minOccurs="0" />
-			<xs:element name="editor" type="tns:editorType" maxOccurs="1"
-				minOccurs="0" />
-			<xs:element name="product" type="tns:productType"
-				maxOccurs="1" minOccurs="0" />
-			<xs:element name="status" type="tns:statusType" maxOccurs="1"
-				minOccurs="0" />
-			<xs:element name="platform" type="tns:platformType"
-				maxOccurs="1" minOccurs="0" />
-			<xs:element name="version" minOccurs="0" type="tns:versionType" />
-			<xs:element name="release" minOccurs="0" type="tns:releaseType" />
-			<xs:element name="customer" minOccurs="0" type="tns:customerType" />
-			<xs:element name="origin" minOccurs="0" type="tns:customerType" />
-			<xs:element name="target" minOccurs="0" type="tns:customerType" />
-			<xs:element name="desc" minOccurs="0" type="tns:descType" />
-			<xs:element name="icon" minOccurs="0" type="tns:iconType" />
-			<xs:element ref="tns:link" maxOccurs="1" minOccurs="0"></xs:element>
-		</xs:all>
-	</xs:complexType>
-	<xs:complexType name="descType" mixed="true">
-		<xs:attribute ref="xlink:href" />
-		<xs:attribute ref="xlink:title" />
-		<xs:attributeGroup ref="tns:CommonAttrs"></xs:attributeGroup>
-	</xs:complexType>
-	<xs:complexType name="iconType">
-		<xs:attribute ref="xlink:href" use="optional" />
-		<xs:attribute ref="xlink:title" />
-		<xs:attributeGroup ref="tns:CommonAttrs"></xs:attributeGroup>
-	</xs:complexType>
-	<xs:complexType name="linkType">
-		<xs:attribute ref="xlink:href" use="optional" />
-		<xs:attribute ref="xlink:title" />
-		<xs:attributeGroup ref="tns:CommonAttrs"></xs:attributeGroup>
-	</xs:complexType>
-	<xs:complexType name="propertyType">
-		<xs:choice minOccurs="0" maxOccurs="unbounded">
-			<xs:element ref="tns:desc" />
-			<xs:element ref="tns:icon" />
-			<xs:element ref="tns:link" />
-		</xs:choice>
-		<xs:attributeGroup ref="tns:CommonAttrs"></xs:attributeGroup>
-		<xs:attribute name="name" type="xs:NMTOKEN" use="optional"></xs:attribute>
-		<xs:attribute name="value" type="xs:string"></xs:attribute>
-		<xs:attribute name="unit" type="xs:token"></xs:attribute>
-	</xs:complexType>
-	<xs:complexType name="settingType">
-		<xs:choice minOccurs="0" maxOccurs="unbounded">
-			<xs:element ref="tns:desc" />
-			<xs:element ref="tns:icon" />
-			<xs:element ref="tns:link" />
-			<xs:element ref="tns:option" />
-			<xs:element ref="tns:property" />
-			<xs:element ref="tns:setting" />
-			<xs:element ref="tns:localPath" />
-			<xs:element ref="tns:targetPath" />
-			<xs:element ref="xs:minInclusive"></xs:element>
-			<xs:element ref="xs:maxInclusive"></xs:element>
-			<xs:element ref="xs:minExclusive"></xs:element>
-			<xs:element ref="xs:maxExclusive"></xs:element>
-			<xs:element ref="xs:pattern"></xs:element>
-			<xs:element ref="xs:length"></xs:element>
-			<xs:element ref="xs:minLength"></xs:element>
-			<xs:element ref="xs:maxLength"></xs:element>
-			<xs:element ref="xs:totalDigits"></xs:element>
-		</xs:choice>
-		<xs:attributeGroup ref="tns:CommonAttrs"></xs:attributeGroup>
-		<xs:attribute name="relevant" type="xs:token" default="true"></xs:attribute>
-		<xs:attribute name="constraint" type="xs:token" default="true">
-		</xs:attribute>
-		<xs:attribute name="readOnly" type="xs:NMTOKEN" default="true">
-		</xs:attribute>
-		<xs:attribute name="name" type="xs:string"></xs:attribute>
-		<xs:attribute name="type" type="tns:typeType" use="optional"></xs:attribute>
-		<xs:attribute name="ref" type="xs:string" use="optional"></xs:attribute>
-		<!--
-			TODO inconsistent defaults: for generic settings this does not have a
-			sense
-		-->
-		<xs:attribute name="minOccurs" type="xs:nonNegativeInteger"
-			default="0"></xs:attribute>
-		<xs:attribute name="maxOccurs" type="xs:allNNI" default="unbounded"></xs:attribute>
-		<xs:attribute name="mapKey" type="xs:string"></xs:attribute>
-		<xs:attribute name="mapValue" type="xs:string"></xs:attribute>
-		<xs:attribute name="required" type="xs:boolean" default="false"></xs:attribute>
-	</xs:complexType>
-	<xs:complexType name="featureType">
-		<xs:choice minOccurs="0" maxOccurs="unbounded">
-			<xs:element ref="tns:desc" />
-			<xs:element ref="tns:icon" />
-			<xs:element ref="tns:link" />
-			<xs:element ref="tns:setting"></xs:element>
-		</xs:choice>
-		<xs:attribute name="name" type="xs:string" />
-		<xs:attribute name="relevant" type="xs:string"></xs:attribute>
-		<xs:attribute name="ref" type="xs:NMTOKEN" use="required" />
-		<xs:attributeGroup ref="tns:CommonAttrs"></xs:attributeGroup>
-	</xs:complexType>
-	<xs:complexType name="optionType">
-		<xs:choice minOccurs="0" maxOccurs="unbounded">
-			<xs:element ref="tns:desc" />
-			<xs:element ref="tns:icon" />
-			<xs:element ref="tns:link" />
-		</xs:choice>
-		<xs:attributeGroup ref="tns:CommonAttrs"></xs:attributeGroup>
-		<xs:attribute name="name" type="xs:token" use="optional"></xs:attribute>
-		<xs:attribute name="value" type="xs:string" use="optional"></xs:attribute>
-		<xs:attribute name="relevant" type="xs:token" default="true"></xs:attribute>
-		<xs:attribute name="map" type="xs:string"></xs:attribute>
-	</xs:complexType>
-	<xs:complexType name="groupType">
-		<xs:choice minOccurs="0" maxOccurs="unbounded">
-			<xs:element ref="tns:desc" />
-			<xs:element ref="tns:icon" />
-			<xs:element ref="tns:link" />
-			<xs:element ref="tns:group" />
-			<xs:element ref="tns:setting" />
-		</xs:choice>
-		<xs:attributeGroup ref="tns:CommonAttrs"></xs:attributeGroup>
-		<xs:attribute name="name" type="xs:string" use="required"></xs:attribute>
-	</xs:complexType>
-	<xs:complexType name="viewType">
-		<xs:choice minOccurs="0" maxOccurs="unbounded">
-			<xs:element ref="tns:meta" />
-			<xs:element ref="tns:desc" />
-			<xs:element ref="tns:icon" />
-			<xs:element ref="tns:link" />
-			<xs:element ref="tns:group"></xs:element>
-		</xs:choice>
-		<xs:attributeGroup ref="tns:CommonAttrs"></xs:attributeGroup>
-		<xs:attribute name="name" type="xs:token" use="optional"></xs:attribute>
-	</xs:complexType>
-	<xs:complexType name="localTargetPathType">
-		<xs:choice minOccurs="0" maxOccurs="unbounded">
-			<xs:element ref="tns:desc" />
-			<xs:element ref="tns:icon" />
-			<xs:element ref="tns:link" />
-		</xs:choice>
-		<xs:attributeGroup ref="tns:CommonAttrs"></xs:attributeGroup>
-		<xs:attribute name="constraint" type="xs:token"/>
-		<xs:attribute name="readOnly" type="xs:NMTOKEN"/>
-		<xs:attribute name="required" type="xs:NMTOKEN"/>
-		<xs:attribute name="map" type="xs:string"></xs:attribute>
-	</xs:complexType>
-	<xs:simpleType name="idType">
-		<xs:restriction base="xs:NMTOKEN"></xs:restriction>
-	</xs:simpleType>
-	<xs:simpleType name="dateType">
-		<xs:restriction base="xs:date"></xs:restriction>
-	</xs:simpleType>
-	<xs:simpleType name="ownerType">
-		<xs:restriction base="xs:string"></xs:restriction>
-	</xs:simpleType>
-	<xs:simpleType name="editorType">
-		<xs:restriction base="xs:string"></xs:restriction>
-	</xs:simpleType>
-	<xs:simpleType name="productType">
-		<xs:restriction base="xs:string"></xs:restriction>
-	</xs:simpleType>
-	<xs:simpleType name="statusType">
-		<xs:restriction base="xs:string"></xs:restriction>
-	</xs:simpleType>
-	<xs:simpleType name="platformType">
-		<xs:restriction base="xs:string"></xs:restriction>
-	</xs:simpleType>
-	<xs:simpleType name="versionType">
-		<xs:restriction base="xs:string"></xs:restriction>
-	</xs:simpleType>
-	<xs:simpleType name="releaseType">
-		<xs:restriction base="xs:string"></xs:restriction>
-	</xs:simpleType>
-	<xs:simpleType name="customerType">
-		<xs:restriction base="xs:string"></xs:restriction>
-	</xs:simpleType>
-<!-- <xs:attribute name="id" type="xs:NMTOKEN" />-->
-	<!--
-		<xs:attribute name="href" type="xs:anyURI" /> <xs:attribute
-		name="title" type="xs:string" />
-	-->
-	<xs:attributeGroup name="CommonAttrs">
-		<xs:attribute name="id" type="xs:ID"></xs:attribute>
-	</xs:attributeGroup>
-	<xs:complexType name="dataType">
-		<xs:sequence>
-			<xs:any namespace="##any" processContents="skip" minOccurs="0"
-				maxOccurs="unbounded"></xs:any>
-		</xs:sequence>
-		<xs:attributeGroup ref="tns:CommonAttrs"></xs:attributeGroup>
-		<xs:attribute name="extensionPolicy" type="xs:NMTOKEN"
-			default="replace">
-		</xs:attribute>
-		<xs:attribute name="template" type="xs:NMTOKEN" default="false"></xs:attribute>
-	</xs:complexType>
-	<xs:complexType name="rfsType">
-		<xs:sequence>
-			<xs:any namespace="##any" processContents="skip" minOccurs="0"
-				maxOccurs="unbounded"></xs:any>
-		</xs:sequence>
-		<xs:attributeGroup ref="tns:CommonAttrs"></xs:attributeGroup>
-	</xs:complexType>
-	<xs:simpleType name="typeType">
-		<xs:restriction base="xs:string">
-			<xs:enumeration id="int" value="int"></xs:enumeration>
-			<xs:enumeration value="boolean"></xs:enumeration>
-			<xs:enumeration value="real"></xs:enumeration>
-			<xs:enumeration value="string"></xs:enumeration>
-			<xs:enumeration value="file"></xs:enumeration>
-			<xs:enumeration value="folder"></xs:enumeration>
-			<xs:enumeration value="sequence"></xs:enumeration>
-			<xs:enumeration value="selection"></xs:enumeration>
-			<xs:enumeration value="multiSelection"></xs:enumeration>
-			<xs:enumeration value="date"></xs:enumeration>
-			<xs:enumeration value="time"></xs:enumeration>
-			<xs:enumeration value="dateTime"></xs:enumeration>
-			<xs:enumeration value="duration"></xs:enumeration>
-		</xs:restriction>
-	</xs:simpleType>
-</xs:schema>
\ No newline at end of file
+<?xml version="1.0" encoding="utf-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://www.s60.com/xml/confml/2" 
+    xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xi="http://www.w3.org/2001/XInclude" 
+    targetNamespace="http://www.s60.com/xml/confml/2" elementFormDefault="qualified" 
+    attributeFormDefault="unqualified">
+    <xs:import namespace="http://www.w3.org/1999/xlink" schemaLocation="xlink.xsd" id="xlink"/>
+    <xs:import namespace="http://www.w3.org/2001/XMLSchema" schemaLocation="XMLSchema.xsd" id="xs"/>
+    <xs:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="xml.xsd" id="xml"/>
+    <xs:element name="configuration" type="tns:configurationType"/>
+    <xs:element name="meta" type="tns:metaType"/>
+    <xs:element name="desc" type="tns:descType"/>
+    <xs:element name="icon" type="tns:iconType"/>
+    <xs:element name="view" type="tns:viewType"/>
+    <xs:element name="group" type="tns:groupType"/>
+    <xs:element name="feature" type="tns:featureType"/>
+    <xs:element name="setting" type="tns:settingType"/>
+    <xs:element name="data" type="tns:dataType"/>
+    <xs:element name="rfs" type="tns:rfsType"/>
+    <xs:element name="link" type="tns:linkType"/>
+    <xs:element name="option" type="tns:optionType"/>
+    <xs:element name="property" type="tns:propertyType"/>
+    <xs:element name="localPath" type="tns:pathType"/>
+    <xs:element name="targetPath" type="tns:pathType"/>
+    <xs:complexType name="configurationType">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+			<xs:element ref="tns:meta" maxOccurs="1"/>
+			<xs:element ref="tns:desc"/>
+			<xs:element ref="tns:icon"/>
+			<xs:element ref="tns:view"/>
+			<xs:element ref="tns:feature"/>
+			<xs:element ref="tns:link"/>
+			<xs:element ref="tns:data" maxOccurs="1"/>
+			<xs:element ref="tns:rfs" maxOccurs="1"/>
+			<xs:element ref="tns:configuration"/>
+			<!-- !!!TBD check if including xs:include as an element is right thing to do 
+				If so, add also note that e.g. xpointer is not supported (by most of the tools)
+			-->
+			<xs:element ref="xs:include" minOccurs="0" maxOccurs="unbounded"/>
+		</xs:choice>
+        <xs:attribute name="version" use="required">
+            <xs:simpleType>
+                <xs:restriction base="xs:token">
+                    <!-- This regexp matches versions declared as x.y[.z] --> 
+					<xs:pattern value="[0-9]{1,3}\.[0-9]{1,3}(\.[0-9]{0,3})?"/>
+                </xs:restriction>
+            </xs:simpleType>
+        </xs:attribute>
+        <xs:attribute name="name" type="xs:token"/>
+        <xs:attributeGroup ref="tns:CommonAttrs"/>
+        <!-- allow xml:base for xinclude -->
+        <xs:attribute ref="xml:base"/>
+    </xs:complexType>
+    <xs:complexType name="metaType">
+        <xs:all>
+			<xs:element name="id" type="tns:idType" minOccurs="0"/>
+            <xs:element name="date" type="tns:dateType" minOccurs="0"/>
+            <xs:element name="owner" type="tns:ownerType" minOccurs="0"/>
+            <xs:element name="editor" type="tns:editorType" minOccurs="0"/>
+            <xs:element name="status" type="tns:statusType" minOccurs="0"/>
+            <xs:element name="version" type="tns:versionType" minOccurs="0"/>
+            <xs:element name="platform" type="tns:platformType" minOccurs="0"/>
+            <xs:element name="product" type="tns:productType" minOccurs="0"/>
+            <xs:element name="release" type="tns:releaseType" minOccurs="0"/>
+            <xs:element name="customer" type="tns:customerType" minOccurs="0"/>
+            <xs:element name="origin" type="tns:originType" minOccurs="0"/>
+            <xs:element name="target" type="tns:targetType" minOccurs="0"/>
+            <xs:element name="desc" type="tns:descType" minOccurs="0"/>
+            <xs:element name="icon" type="tns:iconType" minOccurs="0"/>
+            <xs:element ref="tns:link" minOccurs="0"/>
+        </xs:all>
+    </xs:complexType>
+    <xs:complexType name="descType" mixed="true">
+        <xs:attribute ref="xlink:href"/>
+        <xs:attribute ref="xlink:title"/>
+        <xs:attributeGroup ref="tns:CommonAttrs"/>
+    </xs:complexType>
+    <xs:complexType name="iconType">
+        <xs:attribute ref="xlink:href" use="optional"/>
+        <xs:attribute ref="xlink:title"/>
+        <xs:attributeGroup ref="tns:CommonAttrs"/>
+    </xs:complexType>
+    <xs:complexType name="linkType">
+        <xs:attribute ref="xlink:href" use="optional"/>
+        <xs:attribute ref="xlink:title"/>
+        <xs:attributeGroup ref="tns:CommonAttrs"/>
+    </xs:complexType>
+    <xs:complexType name="propertyType">
+		<xs:choice minOccurs="0" maxOccurs="unbounded">
+			<xs:element ref="tns:desc"/>
+			<xs:element ref="tns:icon"/>
+			<xs:element ref="tns:link"/>
+		</xs:choice>
+        <xs:attributeGroup ref="tns:CommonAttrs"/>
+        <xs:attribute name="name" type="xs:token" use="optional"/>
+        <xs:attribute name="value" type="xs:string" use="optional"/>
+        <xs:attribute name="unit" type="xs:token"/>
+    </xs:complexType>
+    <xs:complexType name="settingType">
+		<xs:choice minOccurs="0" maxOccurs="unbounded">
+			<xs:element ref="tns:desc"/>
+			<xs:element ref="tns:icon"/>
+			<xs:element ref="tns:link"/>
+			<xs:element ref="tns:option"/>
+			<xs:element ref="tns:property"/>
+			<xs:element ref="tns:setting"/>
+			<xs:element ref="tns:localPath"/>
+			<xs:element ref="tns:targetPath"/>
+			<xs:element ref="xs:pattern"/>
+			<xs:element ref="xs:minInclusive"/>
+			<xs:element ref="xs:maxInclusive"/>
+			<xs:element ref="xs:minExclusive"/>
+			<xs:element ref="xs:maxExclusive"/>
+			<xs:element ref="xs:length"/>
+			<xs:element ref="xs:minLength"/>
+			<xs:element ref="xs:maxLength"/>
+			<xs:element ref="xs:totalDigits"/>
+		</xs:choice>
+        <xs:attributeGroup ref="tns:CommonAttrs"/>
+        <xs:attribute name="relevant" type="xs:token" default="true"/>
+        <xs:attribute name="constraint" type="xs:token" default="true"/>
+        <xs:attribute name="readOnly" type="xs:boolean" default="false"/>
+        <xs:attribute name="name" type="xs:string"/>
+        <xs:attribute name="type" type="tns:typeType"/>
+        <xs:attribute name="ref" type="xs:NCName"/>
+        <xs:attribute name="minOccurs" type="xs:nonNegativeInteger" default="0"/>
+        <xs:attribute name="maxOccurs" type="xs:NMTOKEN" default="unbounded"/>
+        <xs:attribute name="displayName" type="xs:string"/>
+        <xs:attribute name="mapKey" type="xs:string"/>
+        <xs:attribute name="mapValue" type="xs:string"/>
+        <xs:attribute name="required" type="xs:boolean" default="false"/>
+        <!--
+            !!!TBD inconsistent defaults: for generic settings this does not have a
+            sense
+        -->
+    </xs:complexType>
+    <xs:complexType name="featureType">
+		<xs:choice minOccurs="0" maxOccurs="unbounded">
+			<xs:element ref="tns:desc"/>
+			<xs:element ref="tns:icon"/>
+			<xs:element ref="tns:link"/>
+			<xs:element ref="tns:setting"/>
+		</xs:choice>
+        <xs:attribute name="name" type="xs:token"/>
+        <xs:attribute name="relevant" type="xs:token"/>
+        <xs:attribute name="ref" type="xs:NCName" use="required"/>
+        <xs:attributeGroup ref="tns:CommonAttrs"/>
+    </xs:complexType>
+    <xs:complexType name="optionType">
+		<xs:choice minOccurs="0" maxOccurs="unbounded">
+			<xs:element ref="tns:desc"/>
+			<xs:element ref="tns:icon"/>
+			<xs:element ref="tns:link"/>
+		</xs:choice>
+        <xs:attributeGroup ref="tns:CommonAttrs"/>
+        <xs:attribute name="name" type="xs:token"/>
+        <xs:attribute name="value" type="xs:string"/>
+        <xs:attribute name="relevant" type="xs:token" default="true"/>
+        <xs:attribute name="map" type="xs:string"/>
+        <xs:attribute name="mapValue" type="xs:string"/>
+        <xs:attribute name="displayName" type="xs:string"/>
+    </xs:complexType>
+    <xs:complexType name="groupType">
+		<xs:choice minOccurs="0" maxOccurs="unbounded">
+			<xs:element ref="tns:desc"/>
+			<xs:element ref="tns:icon"/>
+			<xs:element ref="tns:link"/>
+			<xs:element ref="tns:group"/>
+			<xs:element ref="tns:setting"/>
+		</xs:choice>
+        <xs:attributeGroup ref="tns:CommonAttrs"/>
+        <xs:attribute name="name" type="xs:token"/>
+    </xs:complexType>
+    <xs:complexType name="viewType">
+		<xs:choice minOccurs="0" maxOccurs="unbounded">
+			<xs:element ref="tns:meta" maxOccurs="1"/>
+			<xs:element ref="tns:desc"/>
+			<xs:element ref="tns:icon"/>
+			<xs:element ref="tns:link"/>
+			<xs:element ref="tns:group"/>
+		</xs:choice>
+        <xs:attributeGroup ref="tns:CommonAttrs"/>
+        <xs:attribute name="name" type="xs:token"/>
+    </xs:complexType>
+    <xs:simpleType name="idType">
+        <xs:restriction base="xs:NMTOKEN"/>
+    </xs:simpleType>
+    <xs:simpleType name="dateType">
+        <xs:restriction base="xs:date"/>
+    </xs:simpleType>
+    <xs:simpleType name="ownerType">
+        <xs:restriction base="xs:string"/>
+    </xs:simpleType>
+    <xs:simpleType name="editorType">
+        <xs:restriction base="xs:string"/>
+    </xs:simpleType>
+    <xs:simpleType name="productType">
+        <xs:restriction base="xs:string"/>
+    </xs:simpleType>
+    <xs:simpleType name="statusType">
+        <xs:restriction base="xs:string"/>
+    </xs:simpleType>
+    <xs:simpleType name="platformType">
+        <xs:restriction base="xs:string"/>
+    </xs:simpleType>
+    <xs:simpleType name="versionType">
+        <xs:restriction base="xs:string"/>
+    </xs:simpleType>
+    <xs:simpleType name="releaseType">
+        <xs:restriction base="xs:string"/>
+    </xs:simpleType>
+    <xs:simpleType name="customerType">
+        <xs:restriction base="xs:string"/>
+    </xs:simpleType>
+    <xs:simpleType name="originType">
+        <xs:restriction base="xs:string"/>
+    </xs:simpleType>
+    <xs:simpleType name="targetType">
+        <xs:restriction base="xs:string"/>
+    </xs:simpleType>
+    <xs:attributeGroup name="CommonAttrs">
+        <xs:attribute name="id" type="xs:NMTOKEN"/>
+    </xs:attributeGroup>
+    <xs:complexType name="dataType">
+        <xs:sequence>
+            <xs:any namespace="##any" processContents="skip" minOccurs="0" maxOccurs="unbounded"/>
+        </xs:sequence>
+        <xs:attributeGroup ref="tns:CommonAttrs"/>
+        <xs:attribute name="extensionPolicy" type="xs:NMTOKEN" default="replace"/>
+        <xs:attribute name="template" type="xs:NMTOKEN" default="false"/>
+        <xs:attribute name="map" type="xs:string"/>
+        <xs:attribute name="empty" type="xs:NMTOKEN" default="false"/>
+    </xs:complexType>
+    <xs:complexType name="rfsType">
+        <xs:sequence>
+            <xs:any namespace="##any" processContents="skip" minOccurs="0" maxOccurs="unbounded"/>
+        </xs:sequence>
+        <xs:attributeGroup ref="tns:CommonAttrs"/>
+    </xs:complexType>
+    <xs:simpleType name="typeType">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="int"/>
+            <xs:enumeration value="boolean"/>
+            <xs:enumeration value="real"/>
+            <xs:enumeration value="string"/>
+            <xs:enumeration value="file"/>
+            <xs:enumeration value="folder"/>
+            <xs:enumeration value="sequence"/>
+            <xs:enumeration value="selection"/>
+            <xs:enumeration value="multiSelection"/>
+            <xs:enumeration value="date"/>
+            <xs:enumeration value="time"/>
+            <xs:enumeration value="dateTime"/>
+            <xs:enumeration value="duration"/>
+            <xs:enumeration value="hexBinary"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:complexType name="pathType" mixed="true">
+		<xs:choice minOccurs="0" maxOccurs="unbounded">
+			<xs:element ref="tns:desc"/>
+			<xs:element ref="tns:icon"/>
+			<xs:element ref="tns:link"/>
+			<xs:element ref="xs:pattern" />
+			<xs:element ref="xs:length" />
+			<xs:element ref="xs:minLength" />
+			<xs:element ref="xs:maxLength" />
+			<xs:element ref="tns:property" />
+		</xs:choice>
+        <xs:attributeGroup ref="tns:CommonAttrs"/>
+        <xs:attribute name="constraint" type="xs:token" default="true"/>
+        <xs:attribute name="readOnly" type="xs:boolean" default="false"/>
+        <xs:attribute name="required" type="xs:boolean" default="false"/>
+        <xs:attribute name="map" type="xs:string"/>
+    </xs:complexType>
+</xs:schema>
--- a/configurationengine/linux.properties	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/linux.properties	Tue Aug 10 14:29:28 2010 +0300
@@ -1,1 +1,4 @@
-os.linux.userbin = /home/hudson/bin
\ No newline at end of file
+os.linux.name = Linux
+os.linux.userbin = /home/hudson/bin
+os.linux.cmdname = sh
+os.linux.cmdswitch = -c
--- a/configurationengine/source/cone.cmd	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone.cmd	Tue Aug 10 14:29:28 2010 +0300
@@ -29,30 +29,33 @@
 
 set CONE_CMDARG=%*
 set CONE_BASEDIR=%~dp0
+set CONE_BASEDIR=%CONE_BASEDIR%configurationengine\win\
 set PYTHONCASEOK=1
+set PYTHONDONTWRITEBYTECODE=x
+
+if not exist "%CONE_BASEDIR%" (
+echo Cannot run ConE, the ConE base directory does not exist:
+echo %CONE_BASEDIR%
+exit /b 1
+)
 
 @rem Check that Python is available
-call python -h >nul 2>&1
+call python -c None >nul 2>&1
 if %errorlevel% neq 0 (
 echo Python is required to run ConE!
 exit /b 1
 )
 
 @REM Find out Python version
-set VERFILE=%TEMP%\cone_version_check.tmp
-python -c "import sys; print sys.version[:3]" > %VERFILE%
-set varNUM=0
-for /f "tokens=*" %%T in (%VERFILE%) do call :varSET %%T
-if exist %VERFILE% del %VERFILE% 
-
+FOR /F "tokens=*" %%i in ('PYTHON -c "import sys; sys.stdout.write(sys.version[:3])"') do SET VER1=%%i
 
 @REM Set the used base directory based on the version
 if %VER1%==2.5 (
-set CONE_BASEDIR=%CONE_BASEDIR%cone\2.5\
+set CONE_BASEDIR=%CONE_BASEDIR%2.5\
 goto EndVersionCheck
 )
 if %VER1%==2.6 (
-set CONE_BASEDIR=%CONE_BASEDIR%cone\2.6\
+set CONE_BASEDIR=%CONE_BASEDIR%2.6\
 goto EndVersionCheck
 )
 echo You are using an unsupported Python version (%VER1%)
@@ -67,19 +70,26 @@
 exit /b 1
 )
 
+@rem Set the egg cache dir to be unique to avoid egg extraction clashes
+@rem when running multiple parallel ConE instances
+FOR /F "tokens=*" %%i in ('PYTHON -c "import tempfile; d = tempfile.mkdtemp(); print d"') do SET EGG_CACHE_DIR=%%i
+@rem echo Egg cache dir: %EGG_CACHE_DIR%
+set PYTHON_EGG_CACHE=%EGG_CACHE_DIR%
 
 @rem Set environment variables and run cone_tool.py
 set CONE_LIBDIR=%CONE_BASEDIR%\lib
 set CONE_SCRIPTDIR=%CONE_BASEDIR%\scripts
 set PATH=%CONE_SCRIPTDIR%;%PATH%
 set PYTHONPATH=%CONE_LIBDIR%;%PYTHONPATH%
-call python "%CONE_SCRIPTDIR%\cone_tool.py" %CONE_CMDARG%
-exit /b %ERRORLEVEL%
+REM The cone_tool will parse the arguments from the environment variable
+call python "%CONE_SCRIPTDIR%\cone_tool.py" 
+set CONE_ERROR_CODE=%ERRORLEVEL%
 
+@rem Delete the egg cache dir
+call rd /S /Q "%EGG_CACHE_DIR%"
+
+if 0%CONE_EXITSHELL% equ 0 exit /b %CONE_ERROR_CODE%
+exit %CONE_ERROR_CODE%
 endlocal
 
-:VarSET
-set /a varNUM=%varNUM%+1
-set VER%varNUM%=%1
-
 :: END OF cone.cmd
--- a/configurationengine/source/cone.sh	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone.sh	Tue Aug 10 14:29:28 2010 +0300
@@ -7,17 +7,15 @@
 # which accompanies this distribution, and is available
 # at the URL "http://www.eclipse.org/legal/epl-v10.html".
 #
-# Initial Contributors:
+# Contributors:
 # Nokia Corporation - initial contribution.
 #
-# Contributors:
-#
-# Description: 
+# Description:
 #  ConE tool wrapper for Unix
 
 # Check that Python is available
 # ------------------------------
-python --version &> /dev/null
+python -c None &> /dev/null
 if [ $? -ne 0 ]
 then
     echo "Python is required to run ConE!"
@@ -28,19 +26,19 @@
 # Determine the path where ConE is installed
 # ------------------------------------------
 
-# Try to derefence a symlink
-SCRIPT_FILE=`readlink $0`
-if [ "$SCRIPT_FILE" = "" ]
+SCRIPT_FILE=`readlink -f $0`
+CONE_BASEDIR=`dirname "$SCRIPT_FILE"`/configurationengine/linux
+
+if [ ! -e "$CONE_BASEDIR" ]
 then
-    # Not a symlink, the first command line parameter can be used
-    SCRIPT_FILE=$0
+    echo "Cannot run ConE, the ConE base directory does not exist:"
+    echo $CONE_BASEDIR
+    exit 1
 fi
-CONE_BASEDIR=`dirname "$SCRIPT_FILE"`/cone
-
 
 # Find out the Python version
 # ---------------------------
-PYTHON_VERSION=`python -c "import sys; print sys.version[:3]"`
+PYTHON_VERSION=`python -c "import sys; sys.stdout.write(sys.version[:3])"`
 #echo "Python version: $PYTHON_VERSION"
 
 
@@ -80,4 +78,4 @@
 
 # Run cone_tool.py
 # ----------------
-python $CONE_BASEDIR/scripts/cone_tool.py $@
+python $CONE_BASEDIR/scripts/cone_tool.py "$@"
--- a/configurationengine/source/cone/__init__.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/__init__.py	Tue Aug 10 14:29:28 2010 +0300
@@ -13,6 +13,5 @@
 #
 # Description: 
 #
-
-__version__ = "1.1.5"
+__version__ = "1.2.11"
 _svnrevision = ""
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/action/__init__.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,22 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+import sys,os
+
+__all__ = ['resources','filestorage','zipstorage','stringstorage','webstorage']
+
+storages = ['filestorage','zipstorage','stringstorage','webstorage']
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/action/configroot2flat.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,169 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+#!/usr/bin/env python
+## 
+# @author Teemu Rytkonen
+
+import os, re, fnmatch, logging
+from cone.public import api, utils, exceptions
+from cone.confml import model as confml_model
+
+logger = logging.getLogger('cone')
+
+def get_config_list_from_project(project, configs, config_wildcards, config_regexes):
+    """
+    Return a list of configuration root names based on the given parameters.
+    @param project: The project from which to get the configuration list.
+    @param configs: List of configuration names to add. All of these should exist
+        in the project, or a ConfigurationNotFoundError is raised.
+    @param config_wildcards: List of wildcard patterns for including configurations.
+    @param config_regexs: List of regular expression patters for including configurations.
+    @return: A distinct list of configuration names matched by the given parameters. The
+        list contains matched configurations in the following order:
+            1. Configurations specified in configs
+            2. Configurations matched by wildcard patterns
+            3. Configurations matched by regular expressions
+        If a configuration is matched by more than one of these, the first match determines
+        its placement in the list.
+    @raise Exception: A configuration specified in configs is not
+        actually found in the project.
+    """
+    config_list = []
+    
+    # Handle configurations specified with --configuration first
+    for config in configs:
+        if not project.get_storage().is_resource(utils.resourceref.norm(config)):
+            raise Exception("No such configuration: %s" % config)
+        if config not in config_list:
+            config_list.append(config)
+    
+    # Then handle wildcards
+    #print "wilds %s" % config_wildcards
+    if config_wildcards:
+        for path in project.get_storage().list_resources('.', recurse=True):
+            for wildcard in config_wildcards:
+                if fnmatch.fnmatch(path, wildcard):
+                    if path not in config_list:
+                        config_list.append(path)
+    
+    # Lastly handle regexes
+    #print "regexes %s" % config_regexes
+    if config_regexes:
+        for path in project.get_storage().list_resources('.', recurse=True):
+            for pattern in config_regexes:
+                if re.search(pattern, path) is not None:
+                    if path not in config_list:
+                        config_list.append(path)
+    
+    return config_list
+
+def get_flat_includes(config):
+    """
+    get a flat list of configuration in which each include of configuration root is expanded.
+    The mechanism assumes all includes that end with /root.confml to be layer includes that 
+    are layers that are not expanded
+    @param config: the configuration object to process. 
+    """
+    includes = []
+    for include in config.list_configurations():
+        if include.endswith('/root.confml'):
+            includes.append(utils.resourceref.remove_begin_slash(include))
+        else:
+            subconfig = config.get_configuration(include)
+            includes += get_flat_includes(subconfig)
+    return includes
+
+def get_nested_meta(config, recursion_depth=-1):
+    """
+    Get the nested meta data for the given configuration constructed from metadata of all sub configuration meta.
+    @param config: the configuration object to fetch the metadata for
+    @param recursion_depth: the depth of the recursive nested metadata calls. default value -1 will go through 
+    all configurations.
+    @return: a ConfmlMeta object 
+    """
+    
+    meta = confml_model.ConfmlMeta()
+    if recursion_depth != 0:
+        # First recurse through all subconfigurations to get their meta     
+        for subconfig_name in config.list_configurations():
+            subconfig = config.get_configuration(subconfig_name)
+            submeta = get_nested_meta(subconfig, recursion_depth-1)
+            
+            meta.update( submeta )
+    
+    # lastly, update the meta data of the root configuration
+    if config.meta:
+        meta.update(config.meta)
+    return meta
+
+
+class Configroot2FlatFailed(exceptions.ConeException):
+    pass
+
+class ConeConfigroot2FlatAction(object):
+    def __init__(self, **kwargs):
+        self.project = kwargs.get('project')
+        self.configs = kwargs.get('configs')
+        self.config_wildcards = kwargs.get('config_wildcards')
+        self.config_regexes = kwargs.get('config_regexes')
+        self._project = None
+        
+    def run(self):
+        self._project = api.Project(api.Storage.open(self.project, 'a'))
+        prj = self._project
+        
+        configs = []
+        if self.configs or self.config_wildcards or self.config_regexes:
+            configs = get_config_list_from_project(
+                project          = prj,
+                configs          = self.configs,
+                config_wildcards = self.config_wildcards,
+                config_regexes   = self.config_regexes)
+    
+        if not configs:
+            raise Configroot2FlatFailed("At least one configuration must be given!")
+        
+        print "Processing configurations %s" % configs
+        for source_config in configs:
+            target_config= os.path.basename(source_config)
+            if source_config == target_config:
+                print "Cannot flatten configuration because the source path is the same as target!"
+            config = prj.get_configuration(source_config)
+            
+            print "opened %s for flattening" % source_config
+            
+            print "Creating a new configuration root '%s' for flattening" % target_config
+            tconf = prj.create_configuration(target_config, True)
+            # add the includes
+            for config_include in get_flat_includes(config):
+                tconf.include_configuration(config_include)
+            # add the metadata with hardcoded recursion depth count
+            newmeta = get_nested_meta(config, 2)
+            tconf.meta = newmeta
+            tconf.name = config.name
+            tconf.save()
+        
+        return True
+
+    def save(self):
+        if self._project: self._project.save()
+        
+    def close(self):
+        if self._project: self._project.close()
+
+
+def get_class():
+    return ConeConfigroot2FlatAction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/action/fix.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,81 @@
+
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+"""
+Test the configuration
+"""
+import logging
+
+from cone.public import api, exceptions
+from cone.validation import confmlvalidation
+from cone.validation.problem_type_filter import ProblemTypeFilter
+
+logger    = logging.getLogger('cone')
+
+class ConeFixAction(object):
+    def     __init__(self, **kwargs):
+        # all action attributes are given as keyword arguments
+        self.include_filter = kwargs.get('include_filter',[])
+        self.exclude_filter = kwargs.get('exclude_filter',[])
+        self.username = kwargs.get('username',None)
+        self.password = kwargs.get('password',None)
+        self.project_name = kwargs.get('project_name', '.')
+        self.configuration_name = kwargs.get('configuration_name', None)
+        self.project = kwargs.get('project', None)
+        self.config = kwargs.get('configuration', None)
+        
+        
+    def run(self):
+        filter = ProblemTypeFilter(includes = self.include_filter,
+                                   excludes = self.exclude_filter)
+        
+        # Open the project if it is not already opened
+        if self.project == None:
+            storage = api.Storage.open(self.project_name, 
+                                       "a", 
+                                       username=self.username, 
+                                       password=self.password)
+            self.project = api.Project(storage)
+        if self.config == None:
+            if not self.configuration_name:
+                logging.getLogger('cone').error("No configuration given! Use -c / --configuration")
+                return False
+            try:
+                self.config  = self.project.get_configuration(self.configuration_name)
+            except exceptions.NotFound:
+                logging.getLogger('cone').error("No such configuration: %s" % self.configuration_name)
+                return False
+        
+        fixers = confmlvalidation.get_fixer_classes(filter)
+        
+        vc = confmlvalidation.fix_configuration(self.config, None, fixers)
+        
+        if vc.fixes:
+            print "Fixed %d problem(s). See log for details" % len(vc.fixes)
+        else:
+            print "No problems to fix found. See log for details"
+        return True
+
+    def save(self):
+        self.project.save()
+        
+    def close(self):
+        self.project.close()
+
+
+def get_class():
+    return ConeFixAction
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/action/loader.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,38 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+import os
+import sys
+import fnmatch 
+import re
+import logging
+
+
+def get_class(action_name):
+    """
+    Try to get the SubAction class if it is available
+    """
+    module = get_module(action_name)
+    return module.get_class()
+
+def get_module(action_name):
+    """
+    Try to get the SubAction class if it is available
+    """
+    # trust that the scripts are all in scripts module
+    _temp = __import__('cone.action', globals(), locals(), [action_name], -1)
+    module = _temp.__getattribute__(action_name)
+    return module
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/action/tests/__init__.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,22 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+import sys,os
+
+__all__ = ['resources','filestorage','zipstorage','stringstorage','webstorage']
+
+storages = ['filestorage','zipstorage','stringstorage','webstorage']
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/action/tests/unittest_configroot2flat.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,64 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+#!/usr/bin/env python
+## 
+# @author Teemu Rytkonen
+
+import os
+
+import unittest
+from cone.action import configroot2flat
+from cone.public import api
+
+ROOT_PATH = os.path.abspath(os.path.dirname(__file__))
+
+
+class TestConfigRootFlat(unittest.TestCase):
+    def test_get_flat_configuration_with_empty_config(self):
+        conf = api.Configuration('foo.confml')
+        self.assertEquals(configroot2flat.get_flat_includes(conf), [])
+        
+    def test_get_flat_configuration_with_single_config_hierarchy(self):
+        conf = api.Configuration('foo.confml')
+        conf.include_configuration('test1/root.confml')
+        conf.include_configuration('test2/root.confml')
+        conf.include_configuration('test3/root.confml')
+        self.assertEquals(configroot2flat.get_flat_includes(conf), ['test1/root.confml',
+                                                                    'test2/root.confml',
+                                                                    'test3/root.confml'])
+    
+    def test_get_flat_configuration_with_two_level_config_hierarchy(self):
+        prj = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'temp'), 'w'))
+        rootconf1 = prj.create_configuration('product1_root.confml', True)
+        rootconf2 = prj.create_configuration('product2_root.confml', True)
+        prj.create_configuration('test/one/root.confml', True)
+        fooconf = prj.create_configuration('test/foo.confml', True)
+        rootconf1.create_configuration('layer1/root.confml')
+        rootconf1.create_configuration('layer2/root.confml')
+        rootconf1.create_configuration('layer3/root.confml')
+        fooconf.include_configuration('/product1_root.confml')
+        fooconf.include_configuration('/product2_root.confml')
+        fooconf.include_configuration('/test/one/root.confml')
+        rootconf1.create_configuration('layer5/root.confml')
+        rootconf1.create_configuration('layer6/root.confml')
+        prj.save()
+        self.assertEquals(configroot2flat.get_flat_includes(fooconf), ['layer1/root.confml',
+                                                                       'layer2/root.confml',
+                                                                       'layer3/root.confml',
+                                                                       'layer5/root.confml',
+                                                                       'layer6/root.confml',
+                                                                       'test/one/root.confml'])
+                
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/action/tests/unittest_fix.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,34 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+"""
+Test the configuration
+"""
+import unittest
+import os
+from cone.action import fix
+
+ROOT_PATH           = os.path.dirname(os.path.abspath(__file__))
+
+class TestConeFixAction(unittest.TestCase):
+    
+    def test_create_fix_action(self):
+        fixer = fix.ConeFixAction()
+        self.assertEquals(fixer.include_filter,[])
+        self.assertEquals(fixer.exclude_filter,[])
+ 
+if __name__ == '__main__':
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/action/tests/unittest_loader.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,32 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+"""
+Test the configuration
+"""
+import unittest
+from cone.action import loader
+
+
+class TestGetAction(unittest.TestCase):
+    
+    def test_create_fix_action(self):
+        
+        self.assertTrue(loader.get_module('fix'))
+        self.assertTrue(loader.get_class('fix'))
+ 
+if __name__ == '__main__':
+    unittest.main()
--- a/configurationengine/source/cone/carbon/model.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/carbon/model.py	Tue Aug 10 14:29:28 2010 +0300
@@ -27,6 +27,7 @@
 """
 from cone.public import api, exceptions, container, utils
 from cone.confml import model as confmlmodel
+from cone.carbon import resourcemapper
 
 class ResourceList(object):
     def __init__(self):
@@ -120,10 +121,10 @@
         super(CarbonConfiguration, self).__init__(ref, **kwargs)
         if self.meta == None:
             self.meta = {}
-        
-        self.name                       = kwargs.get('name') or utils.resourceref.remove_ext(utils.resourceref.psplit_ref(self.path)[-1])
-        self.meta.add('type',kwargs.get('type', 'configurationroot'))
-        self._version_identifier        = kwargs.get('version_identifier', None)
+        self.name = kwargs.get('name') or utils.resourceref.remove_ext(utils.resourceref.psplit_ref(self.path)[-1])
+        if self.type == None:
+            self.type = 'configurationroot'
+        self._version_identifier = kwargs.get('version_identifier', None)
 
     @property
     def version_identifier(self):
@@ -132,21 +133,54 @@
             self._version_identifier = "%dwk%02d" % dt.isocalendar()[0:2]
         return self._version_identifier
 
-    @property
-    def type(self):
+    def get_type(self):
         if self.meta and self.meta.get('type'):
-            return self.meta['type']
+            return self.meta.get_property_by_tag('type').value
         else:
             return 'configurationroot'
+        
+    def set_type(self, type):
+        if not self.meta:
+            self.meta = {}
+        self.meta.set_property_by_tag('type',type)
+        
+    def del_type(self):
+        del self.meta['type']
     
+    type = property(get_type, set_type, del_type)
+
+    def get_version_identifier(self):
+        if self._version_identifier == None:
+            dt = datetime.datetime.today()
+            self._version_identifier = "%dwk%02d" % dt.isocalendar()[0:2]
+        return self._version_identifier
+        
+    def set_version_identifier(self, value):
+        self._version_identifier = value
+        
+    def del_version_identifier(self):
+        del self._version_identifier
+    
+    version_identifier = property(get_version_identifier, set_version_identifier, del_version_identifier)
+
 class FeatureList(CarbonConfiguration):
     def __init__(self, ref='', **kwargs):
         if not kwargs.get('path'):
-            kwargs['path']          = str(kwargs.get('name', '')+'.confml')
-        kwargs['type'] = 'featurelist'
+            if kwargs.get('name'):
+                kwargs['path']          = str(kwargs.get('name', '')+'.confml')
+            else:
+                kwargs['path'] = ref
+        
+        pathmapper = resourcemapper.CarbonResourceMapper()
+        tpath = pathmapper.map_confml_resource("featurelist",kwargs['path'])
+        kwargs['path'] = pathmapper.map_carbon_resource(tpath)
+
         super(FeatureList, self).__init__(ref, **kwargs)
-        self.name                = kwargs.get('name', '')
-        self._version_identifier = kwargs.get('version_identifier', 'WORKING')
+        self._version_identifier = kwargs.get('version_identifier', 'working')
+        self.type = 'featurelist'
+
+    def _default_object(self, name):
+        return CarbonFeature(name)
 
 class CarbonFeature(CarbonElement, confmlmodel.ConfmlSetting):
     def __init__(self, ref,**kwargs):
@@ -155,16 +189,24 @@
         
 
 class CarbonSetting(CarbonFeature, confmlmodel.ConfmlSetting):
-    pass
+    def __init__(self, ref,**kwargs):
+        super(CarbonSetting,self).__init__(ref,**kwargs)
+        self.type = 'boolean'
 
 class CarbonIntSetting(CarbonFeature, confmlmodel.ConfmlIntSetting):
-    pass
+    def __init__(self, ref,**kwargs):
+        super(CarbonIntSetting,self).__init__(ref,**kwargs)
+        self.type = 'int'
 
 class CarbonBooleanSetting(CarbonFeature, confmlmodel.ConfmlBooleanSetting):
-    pass
+    def __init__(self, ref,**kwargs):
+        super(CarbonBooleanSetting,self).__init__(ref,**kwargs)
+        self.type = 'boolean'
 
 class CarbonSelectionSetting(CarbonFeature, confmlmodel.ConfmlSelectionSetting):
-    pass
+    def __init__(self, ref,**kwargs):
+        super(CarbonSelectionSetting,self).__init__(ref,**kwargs)
+        self.type = 'selection'
 
 class CarbonStringSetting(CarbonFeature, confmlmodel.ConfmlSetting):
     def __init__(self, ref,**kwargs):
--- a/configurationengine/source/cone/carbon/persistentjson.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/carbon/persistentjson.py	Tue Aug 10 14:29:28 2010 +0300
@@ -22,6 +22,7 @@
 """ cone specific imports """
 from cone.public import persistence, exceptions, api, utils, container
 from cone.carbon import model
+from cone.carbon.resourcemapper import CarbonResourceMapper
 
 MODEL                    = model
 
@@ -37,50 +38,6 @@
     return CarbonReader().loads(jsonstr)
 
 
-class CarbonResourceMapper(object):
-    def __init__(self):
-        self.CARBON_RESOURCE_TYPE_MAP = {'configurationroot' : self.map_carbon_configurationroot,
-                             'configurationlayer' : self.map_carbon_configurationlayer,
-                             'featurelist' : self.map_carbon_featurelist}
-        self.CONFML_RESOURCE_TYPE_MAP = {'configurationroot' : self.map_confml_configurationroot,
-                             'configurationlayer' : self.map_confml_configurationlayer,
-                             'featurelist' : self.map_confml_featurelist}
-
-    def map_carbon_resource(self, resourcepath):
-        for resourceext in self.CARBON_RESOURCE_TYPE_MAP:
-            if resourcepath.endswith(resourceext):
-                return self.CARBON_RESOURCE_TYPE_MAP[resourceext](resourcepath)
-        return resourcepath
-
-    def map_confml_resource(self, resourcetype, resourcepath):
-        return self.CONFML_RESOURCE_TYPE_MAP[resourcetype](resourcepath)
-
-    def map_carbon_configurationroot(self, resourcepath):
-        return resourcepath.replace('.configurationroot', '.confml')
-
-    def map_carbon_configurationlayer(self, resourcepath):
-        return resourcepath.replace('.configurationlayer', '/root.confml')
-
-    def map_carbon_featurelist(self, resourcepath):
-        return "featurelists/%s" % resourcepath.replace('.featurelist', '.confml')
-
-    def map_confml_configurationroot(self, resourcepath):
-        return resourcepath.replace('.confml', '.configurationroot')
-
-    def map_confml_configurationlayer(self, resourcepath):
-        return resourcepath.replace('/root.confml', '.configurationlayer')
-
-    def map_confml_featurelist(self, resourcepath):
-        path = resourcepath.replace('featurelists/','').replace('.confml', '')
-        version_identifier = 'WORKING'
-        m = re.match('^(.*) \((.*)\)', path)
-        # if the resourcepath does not have version information 
-        # use default WORKING
-        if m:
-            path = m.group(1)
-            version_identifier = m.group(2)
-        return '%s (%s).featurelist' % (path, version_identifier)
-
 class ResourceListReader(persistence.ConeReader):
     """
     """ 
@@ -230,7 +187,7 @@
         @param obj: The Configuration object 
         """
         configuration_dict = {'version_identifier': obj.version_identifier}
-
+        
         datawriter = DataWriter()
         data = datawriter.dumps(obj)
         configuration_dict['data'] =  data
@@ -295,7 +252,7 @@
         @param obj: The Configuration object 
         """
         name = dict.get('configuration_name')
-        path = name + ".confml"
+        path = name + "/root.confml"
         conf = model.CarbonConfiguration(dict.get('ref'), path=path, type='configurationlayer')
         conf.name = name
         
@@ -304,10 +261,7 @@
         """ Last read the data of this configuration and add it as a configuration """
         data_reader = DataReader()
         datacont = data_reader.loads(dict.get('data', {}))
-        proxy = api.ConfigurationProxy(datacont.path)
-        conf.add_configuration(proxy)
-        proxy._set_obj(datacont)
-        
+        conf.add_configuration(datacont)
         return conf
 
 class FeatureListCreateWriter(CarbonWriter):
@@ -455,7 +409,7 @@
                        'value_type' : self.CONFML_TO_CARBON_TYPE[mobj.type],
                        'children' : []}
         if featuredict['value_type'] != None:
-            featuredict['type_object'] = 'carbon_feature_type_normal'
+            featuredict['type_object'] = 's60_feature'
         if mobj.type == 'selection':
             featuredict['options'] = mobj.options.keys() 
 
@@ -504,8 +458,8 @@
             fea = model.CarbonStringSetting(ref, type=value_type)
         elif value_type == 'selection':
             fea = model.CarbonSelectionSetting(ref, type=value_type)
-            for option in dict.get('options'):
-                fea.add_option(option,option)
+            for option_name in dict.get('options'):
+                fea.create_option(option_name, option_name)
         elif value_type == '':
             fea = model.CarbonFeature(ref, type=value_type)
         else:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/carbon/resourcemapper.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,63 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+## 
+# @author Teemu Rytkonen
+import re
+import logging
+
+class CarbonResourceMapper(object):
+    def __init__(self):
+        self.CARBON_RESOURCE_TYPE_MAP = {'configurationroot' : self.map_carbon_configurationroot,
+                             'configurationlayer' : self.map_carbon_configurationlayer,
+                             'featurelist' : self.map_carbon_featurelist}
+        self.CONFML_RESOURCE_TYPE_MAP = {'configurationroot' : self.map_confml_configurationroot,
+                             'configurationlayer' : self.map_confml_configurationlayer,
+                             'featurelist' : self.map_confml_featurelist}
+
+    def map_carbon_resource(self, resourcepath):
+        for resourceext in self.CARBON_RESOURCE_TYPE_MAP:
+            if resourcepath.endswith(resourceext):
+                return self.CARBON_RESOURCE_TYPE_MAP[resourceext](resourcepath)
+        return resourcepath
+
+    def map_confml_resource(self, resourcetype, resourcepath):
+        return self.CONFML_RESOURCE_TYPE_MAP[resourcetype](resourcepath)
+
+    def map_carbon_configurationroot(self, resourcepath):
+        return resourcepath.replace('.configurationroot', '.confml')
+
+    def map_carbon_configurationlayer(self, resourcepath):
+        return resourcepath.replace('.configurationlayer', '/root.confml')
+
+    def map_carbon_featurelist(self, resourcepath):
+        return "featurelists/%s" % resourcepath.replace('.featurelist', '.confml')
+
+    def map_confml_configurationroot(self, resourcepath):
+        return resourcepath.replace('.confml', '.configurationroot')
+
+    def map_confml_configurationlayer(self, resourcepath):
+        return resourcepath.replace('/root.confml', '.configurationlayer')
+
+    def map_confml_featurelist(self, resourcepath):
+        path = resourcepath.replace('featurelists/','').replace('.confml', '')
+        version_identifier = 'working'
+        m = re.match('^(.*) \((.*)\)', path)
+        # if the resourcepath does not have version information 
+        # use default WORKING
+        if m:
+            path = m.group(1)
+            version_identifier = m.group(2)
+        return '%s (%s).featurelist' % (path, version_identifier)
--- a/configurationengine/source/cone/carbon/tests/__init__.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/carbon/tests/__init__.py	Tue Aug 10 14:29:28 2010 +0300
@@ -14,33 +14,3 @@
 # Description: 
 #
 
-import unittest, os, sys
-
-ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
-SOURCE_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../../..'))
-if SOURCE_ROOT not in sys.path:
-    sys.path.append(SOURCE_ROOT)
-
-# Find all unittest_*.py files in this folder
-import re
-__all__ = filter(lambda name: re.match(r'^unittest_.*\.py$', name) != None, os.listdir(ROOT_PATH))
-# Strip .py endings
-__all__ = map(lambda name: name[:-3], __all__)
-
-def collect_suite():  
-    sys.path.insert(0, ROOT_PATH)
-    try:
-        suite = unittest.TestSuite()
-        for test_module in __all__:
-            # Load the test module dynamically and add it to the test suite
-            module = __import__(test_module)
-            suite.addTests(unittest.TestLoader().loadTestsFromModule(module))
-        return suite
-    finally:
-        del sys.path[0]
-
-def runtests():
-    unittest.TextTestRunner(verbosity=2).run(collect_suite())
-
-if __name__ == '__main__':
-    runtests()
--- a/configurationengine/source/cone/carbon/tests/runtests.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/carbon/tests/runtests.py	Tue Aug 10 14:29:28 2010 +0300
@@ -16,6 +16,6 @@
 ## 
 # @author Teemu Rytkonen
 
-import __init__
-
-__init__.runtests()
+if __name__ == '__main__':
+    import nose
+    nose.core.run(argv=['collector','--include=unittest', '--verbosity=3'])
--- a/configurationengine/source/cone/carbon/tests/unittest_mapping.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/carbon/tests/unittest_mapping.py	Tue Aug 10 14:29:28 2010 +0300
@@ -20,7 +20,6 @@
 import sys
 import os
 import shutil
-import __init__
 
 from cone.public import api, exceptions
 from cone.confml import model as confmlmodel
@@ -62,7 +61,7 @@
         c1.namespace = "com.nokia"
         c2 = mapper.map_object(c1)
         self.assertTrue(isinstance(c2, confmlmodel.ConfmlConfiguration))
-        self.assertEquals(c2.name, "test")
+        self.assertEquals(c2.name, "test.confml")
         self.assertEquals(c2.namespace, "com.nokia")
         self.assertEquals(c2.path, "test")
 
@@ -71,15 +70,7 @@
         c1 = model.CarbonSetting("test")
         c2 = mapper.map_object(c1)
         self.assertTrue(isinstance(c2, confmlmodel.ConfmlSetting))
-        self.assertEquals(c2.name, "test")
-        self.assertEquals(c2.ref, "test")
-
-    def test_map_carbon_setting_with_data(self):
-        mapper = model.get_mapper('confml')
-        c1 = model.CarbonSetting("test")
-        c2 = mapper.map_object(c1)
-        self.assertTrue(isinstance(c2, confmlmodel.ConfmlSetting))
-        self.assertEquals(c2.name, "test")
+        self.assertEquals(c2.name, None)
         self.assertEquals(c2.ref, "test")
 
     def test_map_carbon_int_setting_with_data(self):
@@ -87,21 +78,21 @@
         c1 = model.CarbonIntSetting("test")
         c2 = mapper.map_object(c1)
         self.assertTrue(isinstance(c2, confmlmodel.ConfmlIntSetting))
-        self.assertEquals(c2.name, "test")
+        self.assertEquals(c2.name, None)
         self.assertEquals(c2.ref, "test")
 
-    def test_map_carbon_setting_with_data(self):
+    def test_map_carbon_boolean_setting_with_data(self):
         mapper = model.get_mapper('confml')
         c1 = model.CarbonBooleanSetting("test")
         c2 = mapper.map_object(c1)
         self.assertTrue(isinstance(c2, confmlmodel.ConfmlBooleanSetting))
-        self.assertEquals(c2.name, "test")
+        self.assertEquals(c2.name, None)
         self.assertEquals(c2.ref, "test")
 
-    def test_map_carbon_setting_with_data(self):
+    def test_map_carbon_selection_setting_with_data(self):
         mapper = model.get_mapper('confml')
         c1 = model.CarbonSelectionSetting("test")
         c2 = mapper.map_object(c1)
         self.assertTrue(isinstance(c2, confmlmodel.ConfmlSelectionSetting))
-        self.assertEquals(c2.name, "test")
+        self.assertEquals(c2.name, None)
         self.assertEquals(c2.ref, "test")
--- a/configurationengine/source/cone/carbon/tests/unittest_model.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/carbon/tests/unittest_model.py	Tue Aug 10 14:29:28 2010 +0300
@@ -20,7 +20,6 @@
 import sys
 import os
 import shutil
-import __init__
 import datetime
 
 from cone.public import api, exceptions
@@ -80,11 +79,12 @@
 
 class TestCarbonConfiguration(unittest.TestCase):
     def test_create_carbon_configuration(self):
-        config = model.CarbonConfiguration(path='foo/bar/test.confml', version_identifier='testing')
+        config = model.CarbonConfiguration(path='foo/bar/test.confml', version_identifier='testing', type="confroot")
         self.assertEquals(config.version_identifier,'testing')
         self.assertEquals(config.path,'foo/bar/test.confml')
         self.assertEquals(config.ref,'foo__bar__test_confml')
         self.assertEquals(config.name,'test')
+        self.assertEquals(config.type,'confroot')
 
         config = model.CarbonConfiguration(ref='foo/bar/test.confml')
         self.assertEquals(config.path,'foo/bar/test.confml')
@@ -125,19 +125,28 @@
         self.assertTrue(c)
         self.assertEquals(c.name, 'test')
         self.assertEquals(c.meta.get('type'), 'featurelist')
-        self.assertEquals(c.path, 'test.confml')
+        self.assertEquals(c.path, 'featurelists/test (working).confml')
+        self.assertEquals(c.get_ref(), 'featurelists__test_working__confml')
+
+    def test_create_with_ref(self):
+        c = model.FeatureList('test_foo.confml')
+        self.assertTrue(c)
+        self.assertEquals(c.name, 'test_foo (working)')
+        self.assertEquals(c.meta.get('type'), 'featurelist')
+        self.assertEquals(c.path, 'featurelists/test_foo (working).confml')
+        self.assertEquals(c.get_ref(), 'featurelists__test_foo_working__confml')
 
     def test_create_with_path(self):
         c = model.FeatureList(path='featurelists/test.confml')
         self.assertTrue(c)
-        self.assertEquals(c.name, '')
+        self.assertEquals(c.name, 'test (working)')
         self.assertEquals(c.meta.get('type'), 'featurelist')
-        self.assertEquals(c.path, 'featurelists/test.confml')
-        self.assertEquals(c.version_identifier, 'WORKING')
+        self.assertEquals(c.path, 'featurelists/test (working).confml')
+        self.assertEquals(c.version_identifier, 'working')
 
 class TestFeature(unittest.TestCase):
     def test_create(self):
-        c = model.CarbonFeature(ref='test')
+        c = model.CarbonFeature(ref='test', name="test1")
         self.assertTrue(c)
-        self.assertEquals(c.name, 'test')
+        self.assertEquals(c.name, 'test1')
         self.assertEquals(c.ref, 'test')
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/carbon/tests/unittest_resourcemapper.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,40 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+
+import unittest
+import string
+import sys
+import os
+import shutil
+import datetime
+
+from cone.public import api, exceptions
+from cone.carbon import resourcemapper, model
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+class TestCarbonResourceMapper(unittest.TestCase):
+    def test_map_confmL_configuration_to_carbon_path(self):
+        self.assertEquals(resourcemapper.CarbonResourceMapper().map_confml_resource("configurationroot","test.confml"),"test.configurationroot")
+        self.assertEquals(resourcemapper.CarbonResourceMapper().map_confml_resource("configurationlayer","test/root.confml"),"test.configurationlayer")
+        self.assertEquals(resourcemapper.CarbonResourceMapper().map_confml_resource("featurelist","featurelists/test (WORKING).confml"),"test (WORKING).featurelist")
+
+    def test_map_carbon_configuration_to_confml_path(self):
+        self.assertEquals(resourcemapper.CarbonResourceMapper().map_carbon_resource("test.configurationroot"),"test.confml")
+        self.assertEquals(resourcemapper.CarbonResourceMapper().map_carbon_resource("foobar_test_one.configurationroot"),"foobar_test_one.confml")
+        self.assertEquals(resourcemapper.CarbonResourceMapper().map_carbon_resource("foobar (WORKING).featurelist"),"featurelists/foobar (WORKING).confml")
+        self.assertEquals(resourcemapper.CarbonResourceMapper().map_carbon_resource("foobar.featurelist"),"featurelists/foobar.confml")
+
--- a/configurationengine/source/cone/confml/model.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/confml/model.py	Tue Aug 10 14:29:28 2010 +0300
@@ -21,9 +21,15 @@
  All Confml element attributes become attributes of this instance.
 """
 import types
+import sys
+import re
 from cone.public import api, exceptions, container, utils
 
 class ConfmlElement(api.Base):
+    def __init__(self, ref="", **kwargs):
+        super(ConfmlElement,self).__init__(ref, **kwargs)
+        self.lineno = None
+
     def _get_mapper(self,modelname):
         """
         Return a instance of appropriate mapper for given model.
@@ -48,6 +54,18 @@
             pass
     """ The description as a property """
     desc = property(get_desc,set_desc,del_desc)
+    
+class ConfmlData(api.Data):
+    """
+    The data element can contain any data setting for a feature. The data element can be 
+    a value definition for any type of data. It basically just links some data to a feature. 
+    The default Data attribute is 'data', but it can be any string. For example current use case 
+    is 'rfs'.
+    """
+    def __init__(self, **kwargs):
+        super(ConfmlData,self).__init__(**kwargs)
+        self.lineno = None
+
 class ConfmlConfiguration(ConfmlElement, api.Configuration):
     """
     Confml configuration class. 
@@ -59,6 +77,14 @@
         if kwargs.get('desc'):
             self.desc = kwargs.get('desc')
 
+    def _view_class(self):
+        return ConfmlView
+
+    def _feature_class(self):
+        return ConfmlFeature
+
+    def _configuration_class(self):
+        return ConfmlConfiguration
 
     def get_desc(self): 
         """
@@ -84,7 +110,7 @@
 
     def get_meta(self): 
         """
-        @return: The description of the Configuration.
+        @return: The meta element of the Configuration.
         """
         try:
             meta = getattr(self,ConfmlMeta.refname)
@@ -104,88 +130,13 @@
     """ The meta element as a property """
     meta = property(get_meta,set_meta,del_meta)
 
-
-class ConfmlGroup(ConfmlElement, api.Group):
-    """
-    Confml view.
+class ConfmlSettingAttributes(ConfmlElement):
     """
-    def __init__(self, ref="", **kwargs):
-        super(ConfmlGroup,self).__init__(ref,**kwargs)
-        if kwargs.get('icon'):
-            self.icon = kwargs.get('icon')
-        if kwargs.get('desc'):
-            self.desc = kwargs.get('desc')
-
-    def get_icon(self): 
-        try:
-            icon = getattr(self,ConfmlIcon.refname)
-            return icon.href
-        except AttributeError:
-            return None
-    def set_icon(self,value): self._add(ConfmlIcon(value))
-    def del_icon(self): 
-        try:
-            self._remove(ConfmlIcon.refname)
-        except exceptions.NotFound:
-            pass
-    """ The icon as a property """
-    icon = property(get_icon,set_icon,del_icon)
-
-    def get_desc(self): 
-        try:
-            desc = getattr(self,ConfmlDescription.refname)
-            return desc.text
-        except AttributeError:
-            return None
-    def set_desc(self,value): self._add(ConfmlDescription(value))
-    def del_desc(self): 
-        try:
-            self._remove(ConfmlDescription.refname)
-        except exceptions.NotFound:
-            pass
-    """ The description as a property """
-    desc = property(get_desc,set_desc,del_desc)
-
-
-class ConfmlView(api.View):
+    Abstract base class for setting attributes. This is used as 
+    a base in actual ConfmlSetting and ConfmlFeatureLink.
     """
-    Confml view.
-    """
-    def __init__(self, ref="", **kwargs):
-        super(ConfmlView,self).__init__(ref,**kwargs)
-        if kwargs.get('desc'):
-            self.desc = kwargs.get('desc')
-
-
-    def get_desc(self): 
-        try:
-            desc = getattr(self,ConfmlDescription.refname)
-            return desc.text
-        except AttributeError:
-            return None
-    def set_desc(self,value): self._add(ConfmlDescription(value))
-    def del_desc(self): 
-        try:
-            self._remove(ConfmlDescription.refname)
-        except exceptions.NotFound:
-            pass
-    """ The description as a property """
-    desc = property(get_desc,set_desc,del_desc)
-
-class ConfmlFeature(ConfmlElement, api.Feature):
-    pass
-
-class ConfmlSetting(ConfmlElement, api.Feature):
-    """
-    Confml setting class. Attribute 'options' contains options of this setting.
-    """
-    supported_types = ['int',
-                       'string',
-                       'boolean',
-                       'selection']
     def __init__(self, ref,**kwargs):
-        super(ConfmlSetting,self).__init__(ref,**kwargs)
-        self.type = kwargs.get('type',None)
+        super(ConfmlSettingAttributes,self).__init__(ref,**kwargs)
         if kwargs.get('desc'):
             self.desc = kwargs.get('desc')
         if kwargs.get('minOccurs'):
@@ -196,10 +147,10 @@
             self.maxLength = kwargs.get('maxLength')
         if kwargs.get('minLength'):
             self.minLength = kwargs.get('minLength')
-        if kwargs.get('mapKey'):
-            self.mapKey = kwargs.get('mapKey')
-        if kwargs.get('mapValue'):
-            self.mapValue = kwargs.get('mapValue')
+        self.mapKey = kwargs.get('mapKey')
+        self.mapValue = kwargs.get('mapValue')
+        self.displayName = kwargs.get('displayName')
+
         
         self.readOnly = kwargs.get('readOnly',None)
         self.constraint = kwargs.get('constraint',None)
@@ -212,39 +163,6 @@
         """
         return api.ValueRe('.*')
 
-    def add_property(self, **kwargs):
-        """
-        @param name=str: property name 
-        @param value=str: property value
-        @param unit=str: property unit, e.g. kB
-        """
-        self._add(ConfmlProperty(**kwargs), container.APPEND)
-
-    def get_property(self, name):
-        """
-        @param name: The name of the property
-        """
-        for property in utils.get_list(self._get(ConfmlProperty.refname)):
-            if property.name == name:
-                return property
-        raise exceptions.NotFound("ConfmlProperty with name %s not found!" % name)
-
-    def remove_property(self, name):
-        """
-        remove a given option from this feature by name. 
-        @param name: 
-        """
-        for property in self._get(ConfmlProperty.refname):
-            if property.name == name:
-                return self._remove(property.get_fullref())
-        raise exceptions.NotFound("ConfmlProperty with name %s not found!" % name)
-
-    def list_properties(self):
-        """
-        Return a array of all Feature children references under this object.
-        """
-        return [obj.name for obj in utils.get_list(self._get(ConfmlProperty.refname))]
-
     def get_maxlength(self): 
         try:
             return getattr(self,ConfmlMaxLength.refname).value
@@ -259,7 +177,7 @@
             self._remove(ConfmlMaxLength.refname)
         except exceptions.NotFound:
             pass
-    """ The description as a property """
+    """ The maxLength as a property """
     maxLength = property(get_maxlength,set_maxlength,del_maxlength)
 
     def get_minlength(self): 
@@ -276,8 +194,25 @@
             self._remove(ConfmlMinLength.refname)
         except exceptions.NotFound:
             pass
-    """ The description as a property """
+    """ The minLength as a property """
     minLength = property(get_minlength,set_minlength,del_minlength)
+    
+    def get_length(self): 
+        try:
+            return getattr(self,ConfmlLength.refname).value
+        except AttributeError:
+            return None
+
+    def set_length(self,value): 
+        self._add(ConfmlLength(value))
+
+    def del_length(self): 
+        try:
+            self._remove(ConfmlLength.refname)
+        except exceptions.NotFound:
+            pass
+    """ The length as a property """
+    length = property(get_length,set_length,del_length)
 
     def get_minInclusive(self): 
         try:
@@ -390,22 +325,112 @@
 
     @property
     def properties(self):
-        dict = {}
-        for property in utils.get_list(self._get(ConfmlProperty.refname)):
-            dict[property.name] = property
-        return  dict
+        propdict = {}
+        for prop in self._objects(type=api.Property):
+            propdict[prop.name] = prop
+        return  propdict
 
-    def get_rfs(self,):
-        return super(ConfmlSetting,self).get_value('rfs')
+    def get_rfs(self):
+        return super(ConfmlSettingAttributes,self).get_value('rfs')
 
     def set_rfs(self, value):
-        super(ConfmlSetting,self).set_value('rfs',value)
+        super(ConfmlSettingAttributes,self).set_value('rfs',value)
 
     def del_rfs(self):
-        super(ConfmlSetting,self).del_value('rfs')
+        super(ConfmlSettingAttributes,self).del_value('rfs')
 
     rfs = property(get_rfs,set_rfs,del_rfs)
 
+
+class ConfmlGroup(ConfmlElement, api.Group):
+    """
+    Confml view.
+    """
+    def __init__(self, ref="", **kwargs):
+        super(ConfmlGroup,self).__init__(ref,**kwargs)
+        if kwargs.get('icon'):
+            self.icon = kwargs.get('icon')
+        if kwargs.get('desc'):
+            self.desc = kwargs.get('desc')
+
+    def _group_class(self):
+        return ConfmlGroup
+
+    def _featurelink_class(self):
+        return ConfmlFeatureLink
+
+    def get_icon(self): 
+        try:
+            icon = getattr(self,ConfmlIcon.refname)
+            return icon.href
+        except AttributeError:
+            return None
+    def set_icon(self,value): self._add(ConfmlIcon(value))
+    def del_icon(self): 
+        try:
+            self._remove(ConfmlIcon.refname)
+        except exceptions.NotFound:
+            pass
+    """ The icon as a property """
+    icon = property(get_icon,set_icon,del_icon)
+
+    def get_desc(self): 
+        try:
+            desc = getattr(self,ConfmlDescription.refname)
+            return desc.text
+        except AttributeError:
+            return None
+    def set_desc(self,value): self._add(ConfmlDescription(value))
+    def del_desc(self): 
+        try:
+            self._remove(ConfmlDescription.refname)
+        except exceptions.NotFound:
+            pass
+    """ The description as a property """
+    desc = property(get_desc,set_desc,del_desc)
+
+
+class ConfmlView(api.View, ConfmlGroup):
+    """
+    Confml view.
+    """
+    def __init__(self, ref="", **kwargs):
+        super(ConfmlView,self).__init__(ref,**kwargs)
+        if kwargs.get('desc'):
+            self.desc = kwargs.get('desc')
+    
+    def get_desc(self): 
+        try:
+            desc = getattr(self,ConfmlDescription.refname)
+            return desc.text
+        except AttributeError:
+            return None
+    def set_desc(self,value): self._add(ConfmlDescription(value))
+    def del_desc(self): 
+        try:
+            self._remove(ConfmlDescription.refname)
+        except exceptions.NotFound:
+            pass
+    """ The description as a property """
+    desc = property(get_desc,set_desc,del_desc)
+
+
+class ConfmlFeature(ConfmlElement, api.Feature):
+    def _feature_class(self):
+        return ConfmlSetting
+
+class ConfmlSetting(ConfmlSettingAttributes, api.Feature):
+    """
+    Confml setting class. Attribute 'options' contains options of this setting.
+    """
+    supported_types = ['int',
+                       'string',
+                       'boolean',
+                       'selection']
+    def __init__(self, ref,**kwargs):
+        super(ConfmlSetting,self).__init__(ref,**kwargs)
+        self.type = kwargs.get('type',None)
+
     def get_value_cast(self, value, attr=None):
         """
         A function to perform the value type casting in get operation  
@@ -425,13 +450,17 @@
         @param value: the value to cast 
         @param attr: the attribute which is fetched from model (normally in confml either None='data' or 'rfs')
         """
+        # Add a exception case for None value, because the data casting will always fail for it
+        if value == None:
+            return value
+        
         if not attr or attr == 'data':
             return self.set_data_cast(value)
         elif attr == 'rfs':
             return self.set_rfs_cast(value)
         else:
             return value
-
+        
     def get_data_cast(self, value):
         """
         A function to perform the data type casting in get operation  
@@ -600,48 +629,78 @@
     """
     Confml setting class for multiSelection type.
     """
-
+    
+    # Pattern for checking whether a data value should be interpreted
+    # in the old style (e.g. '"opt1" "opt2" "opt3"')
+    OLD_STYLE_DATA_PATTERN = re.compile(r'"[^"]*([^"]*" ")*[^"]*"')
+    
     def __init__(self, ref,**kwargs):
         kwargs['type'] = 'multiSelection'
         ConfmlSetting.__init__(self,ref,**kwargs)
         
-
+    def add_data(self, data):
+        """
+        Add a data value.
+        @param data: A Data object  
+        """
+        # If there are existing data objects added to the proxy, and they
+        # are not in the same DataContainer (ConfML data section), change the
+        # policy to replace
+        if self.dataproxy.datas.get(data.attr):
+            existing_data_obj = self.dataproxy.datas[data.attr][-1]
+            existing_obj_parent = existing_data_obj._find_parent_or_default(type=api.DataContainer)
+            new_obj_parent = data._find_parent_or_default(type=api.DataContainer)
+            
+            if existing_obj_parent is not new_obj_parent:
+                self.dataproxy.datas[data.attr] = []
+        
+        self.dataproxy._add_data(data)
+    
     def get_valueset(self):
         """
         Get the ValueSet object for this feature, that has the list of available values.
         """
         return api.Feature.get_valueset(self)
-
-    def get_data_cast(self, value):
-        """
-        A function to perform the value type casting in get operation  
-        """
-        try:
-            if not isinstance(value, types.ListType):
-                values = value.split('" "')
-                for i in range(len(values)):
-                    if values[i].startswith('"'):
-                        values[i] = values[i][1:] 
-                    if values[i].endswith('"'):
-                        values[i] = values[i][:-1]
-                return values
-            return value
-        except AttributeError:
-            return None
     
-    def set_data_cast(self, value):
-        """
-        A function to perform the value type casting in the set operation  
-        """
+    def convert_data_to_value(self, data_objects, cast=True, attr=None):
+        if len(data_objects) == 1:
+            d = data_objects[0]
+            
+            # Special handling for cases where the data is in the old format
+            # (pre-2.88 ConfML spec)
+            if d.value is not None:
+                if self.OLD_STYLE_DATA_PATTERN.match(d.value):
+                    return tuple([v.rstrip('"').lstrip('"') for v in d.value.split('" "')])
+            
+            # Single data object with empty="true" means that nothing is selected
+            if d.empty: return ()
         
-        if isinstance(value, list):
-            value = " ".join(['"%s"' % elem for elem in value])
-        return value
+        # Read each data value (or name-ID mapped value) into result
+        result = []
+        for data_obj in data_objects:
+            if data_obj.map:
+                value = self._resolve_name_id_mapped_value(data_obj.map, cast_value=cast)
+            else:
+                value = data_obj.value
+            result.append(value)
+        result = utils.distinct_array(result)
+        
+        # Handle None in the result (data element with no text data)
+        if None in result:
+            # If the empty string is a valid option, change the None to that,
+            # otherwise ignore
+            index = result.index(None)
+            if '' in self.get_valueset():   result[index] = ''
+            else:                           del result[index]
+        
+        return tuple(result)
     
-    def set_value(self, value):
-        if not isinstance(value, types.ListType):
-            raise ValueError("Only list types are allowed.")
-        self.value = value
+    def convert_value_to_data(self, value, attr=None):
+        if not isinstance(value, (types.ListType, types.TupleType, types.NoneType)):
+            raise ValueError("Only list, tuple and None types are allowed.")
+        
+        if value:   return [api.Data(fqr=self.fqr, value=v, attr=attr) for v in value]
+        else:       return [api.Data(fqr=self.fqr, empty=True, attr=attr)]
 
 class ConfmlDateSetting(ConfmlSetting):
     """
@@ -667,6 +726,32 @@
         kwargs['type'] = 'dateTime'
         ConfmlSetting.__init__(self,ref,**kwargs)
 
+class ConfmlHexBinarySetting(ConfmlSetting):
+    """
+    Confml setting class for hex-binary type.
+    """
+    def __init__(self, ref,**kwargs):
+        kwargs['type'] = 'hexBinary'
+        ConfmlSetting.__init__(self,ref,**kwargs)
+    
+    def get_valueset(self):
+        return api.ValueRe(r'^([0123456789ABCDEF]{2})*$')
+
+    def get_data_cast(self, value):
+        value = value or '' # Handle None
+        if value not in self.get_valueset():
+            raise ValueError("Cannot convert value %r of setting '%s' into binary data: Not a valid hex string", value)
+        
+        temp = []
+        for i in xrange(len(value) / 2):
+            start = i * 2
+            end   = start + 2 
+            temp.append(chr(int(value[start:end], 16)))
+        return ''.join(temp)
+    
+    def set_data_cast(self, value):
+        return ''.join(['%02X' % ord(c) for c in value])
+
 class ConfmlDurationSetting(ConfmlSetting):
     """
     Confml setting class for date type.
@@ -711,10 +796,12 @@
 
 class ConfmlLocalPath(ConfmlElement, api.Feature):
     """
-    Confml file class. Attribute setting.
+    Confml file class. Attribute setting. 
+    The localPath "name" is always the same as its ref 'localPath'
     """
     def __init__(self, ref='localPath', **kwargs):
         kwargs['type'] = 'string'
+        kwargs['name'] = ref
         ConfmlElement.__init__(self, **kwargs)
         api.Feature.__init__(self, ref, **kwargs)
         self.readOnly = kwargs.get('readOnly', None)
@@ -723,14 +810,45 @@
 class ConfmlTargetPath(ConfmlElement, api.Feature):
     """
     Confml file class. Attribute setting.
+    The targetPath "name" is always the same as its ref 'targetPath'
     """
     def __init__(self, ref='targetPath', **kwargs):
         kwargs['type'] = 'string'
+        kwargs['name'] = ref
         ConfmlElement.__init__(self, **kwargs)
         api.Feature.__init__(self, ref, **kwargs)
         self.readOnly = kwargs.get('readOnly', None)
 
 
+class ConfmlFeatureLink(ConfmlSettingAttributes, api.FeatureLink):
+    """
+    ConfmlFeatureLink object is the setting reference object inside confml 
+    group / view. It can populate the actual FeatureProxy objects under the
+    particular group / view object.
+    """
+
+    """ the override_attributes explicitly states which feature link attributes can be overridden """
+    override_attributes = ['name', 
+                           'desc', 
+                           'minLength',
+                           'maxLength',
+                           'minOccurs',
+                           'maxOccurs',
+                           'minInclusive',
+                           'maxInclusive',
+                           'minExclusive',
+                           'maxExclusive',
+                           'pattern',
+                           'totalDigits',
+                           'options',
+                           'properties',
+                           'readOnly'
+                           ]
+    def __init__(self, ref,**kwargs):
+        ConfmlSettingAttributes.__init__(self, ref,**kwargs)
+        api.FeatureLink.__init__(self, ref, **kwargs)
+        self.type = kwargs.get('type',None)
+
 class ConfmlMeta(api.Base):
     """
     Confml meta element
@@ -751,6 +869,9 @@
     def __setitem__(self, key, value):
         self.array[key] = value
 
+    def __len__(self):
+        return len(self.array)
+    
     def __str__(self):
         tempstr = "ConfmlMeta object\n"
         counter = 0
@@ -790,6 +911,16 @@
     def replace(self, index, tag, value, ns=None, dict=None):
         self.array[index] = ConfmlMetaProperty(tag, value, ns, attrs=dict)
 
+    def update(self, data):
+        """
+        Update this the ConfmlMeta object meta with the given data.
+        @param data: The input ConfmlMeta data to update for this object
+        """
+        if data:
+            for property in data.array:
+                self.set_property_by_tag(property.tag, property.value, property.ns, property.attrs)
+
+
     def clear(self, value):
         self.array = []
 
@@ -807,22 +938,38 @@
         return -1
 
     def find_by_attribute(self, name, value):
-        for item in self.array:
-            if item.attrs.has_key(name) and item.attrs[name] == value: 
+        for item in self.array:            
+            if item.attrs.has_key(name) and item.attrs[name] == value:
                 return self.array.index(item)
         return -1
 
-    def get_property_by_tag(self, tag):
+    def get_property_by_tag(self, tag, attrs={}):
         """
         Try to find the element by its tag in the meta elem array.
         @param tag: the tag that is searched
         @return: the ConfmlMetaProperty object if it is found. None if element with tag is not found.
-        """
+        """ 
         for item in self.array:
             if item.tag == tag:
-                return item
+                if not item.attrs or (item.attrs.get("name", None) == attrs.get("name", None)):
+                    return item
         return None
 
+    def set_property_by_tag(self, tag, value, ns=None, attributes=None):
+        """
+        Try to find the element by its tag and set it the meta elem array. 
+        This will either create a new element to the meta or replace first 
+        encountered elem in array. 
+        @param tag: the tag that is searched
+        @return: the ConfmlMetaProperty object if it is found. None if element with tag is not found.
+        """
+                
+        if self.get_property_by_tag(tag, attributes):
+            property = self.get_property_by_tag(tag, attributes) 
+            property.value = value
+            property.attrs = attributes or {}
+        else:
+            self.add(tag, value, ns, attributes)
 
 class ConfmlDescription(api.Base):
     """
@@ -844,21 +991,6 @@
         self.href = href
 
 
-class ConfmlProperty(api.Base):
-    """
-    Confml meta element
-    """
-    refname = "_property"
-    def __init__(self, **kwargs):
-        """
-        @param name=str: name string 
-        @param value=str: value for the property, string 
-        @param unit=str: unit of the property
-        """
-        super(ConfmlProperty,self).__init__(self.refname)
-        self.name = kwargs.get('name',None)
-        self.value = kwargs.get('value',None)
-        self.unit = kwargs.get('unit',None)
 
 
 class ConfmlMetaProperty(api.Base):
@@ -873,10 +1005,7 @@
         self.tag = tag
         self.value = value
         self.ns = ns
-        if kwargs.has_key("attrs") and kwargs["attrs"] != None:
-            self.attrs = dict(kwargs["attrs"])
-        else:
-            self.attrs = {}
+        self.attrs = dict(kwargs.get('attrs') or {})
 
     def __cmp__(self, other):
         try:
@@ -890,9 +1019,28 @@
     def __str__(self):
         return "Tag: %s Value: %s Namespace: %s Attributes: % s" % (self.tag, self.value, self.ns, repr(self.attrs))         
         
-            
 
-class ConfmlLength(api.Base):
+class ConfmlNumericValue(api.Base):
+    """
+    Confml base class for all float type properties.
+    Performs a simple value casting from string to int in value setting.
+    """
+    def __init__(self, ref="", **kwargs):
+        super(ConfmlNumericValue,self).__init__(ref, **kwargs)
+        self._value = None
+        
+    def get_value(self): return self._value
+    def del_value(self): self._value = None
+    def set_value(self, value): 
+        if utils.is_float(value):
+            self._value = float(value) 
+        else:
+            self._value = int(value)
+    """ The value as a property """
+    value = property(get_value,set_value,del_value)
+
+
+class ConfmlLength(ConfmlNumericValue):
     """
     Confml length element
     """
@@ -901,7 +1049,7 @@
         super(ConfmlLength,self).__init__(self.refname)
         self.value = value
 
-class ConfmlMaxLength(api.Base):
+class ConfmlMaxLength(ConfmlNumericValue):
     """
     Confml max element
     """
@@ -910,7 +1058,7 @@
         super(ConfmlMaxLength,self).__init__(self.refname)
         self.value = value
 
-class ConfmlMinLength(api.Base):
+class ConfmlMinLength(ConfmlNumericValue):
     """
     Confml min element
     """
@@ -919,7 +1067,7 @@
         super(ConfmlMinLength,self).__init__(self.refname)
         self.value = value
 
-class ConfmlMinInclusive(api.Base):
+class ConfmlMinInclusive(ConfmlNumericValue):
     """
     Confml minInclusive element
     """
@@ -928,7 +1076,7 @@
         super(ConfmlMinInclusive,self).__init__(self.refname)
         self.value = value
 
-class ConfmlMaxInclusive(api.Base):
+class ConfmlMaxInclusive(ConfmlNumericValue):
     """
     Confml minInclusive element
     """
@@ -937,7 +1085,7 @@
         super(ConfmlMaxInclusive,self).__init__(self.refname)
         self.value = value
 
-class ConfmlMinExclusive(api.Base):
+class ConfmlMinExclusive(ConfmlNumericValue):
     """
     Confml minExclusive element
     """
@@ -946,7 +1094,7 @@
         super(ConfmlMinExclusive,self).__init__(self.refname)
         self.value = value
 
-class ConfmlMaxExclusive(api.Base):
+class ConfmlMaxExclusive(ConfmlNumericValue):
     """
     Confml maxExclusive element
     """
@@ -964,7 +1112,7 @@
         super(ConfmlPattern,self).__init__(self.refname)
         self.value = value   
 
-class ConfmlTotalDigits(api.Base):
+class ConfmlTotalDigits(ConfmlNumericValue):
     """
     Confml totalDigits element
     """
--- a/configurationengine/source/cone/confml/persistentconfml.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/confml/persistentconfml.py	Tue Aug 10 14:29:28 2010 +0300
@@ -13,9 +13,9 @@
 #
 # Description: 
 #
+import os
 import re
 import logging
-import xml.parsers.expat
 try:
     from cElementTree import ElementTree
 except ImportError:
@@ -27,8 +27,8 @@
         except ImportError:
             from xml.etree import ElementTree
 
-""" cone specific imports """
-from cone.public import persistence, exceptions, api, utils, container
+# cone specific imports
+from cone.public import persistence, exceptions, api, utils, container, parsecontext
 from cone.confml import model
 
 CONFIGURATION_NAMESPACES = ["http://www.s60.com/xml/confml/2","http://www.s60.com/xml/confml/1"]
@@ -42,12 +42,29 @@
     etree = ConfmlWriter().dumps(obj)
     if indent:
         persistence.indent(etree)
-    return ElementTree.tostring(etree)
+    result = ElementTree.tostring(etree)
+    
+    # To make the output the same in linux and windows
+    # (needed to make testing easier)
+    if os.linesep != '\r\n':
+        result = result.replace(os.linesep, '\r\n')
+    
+    return result
 
 def loads(xml):
     return ConfmlReader().loads(xml)
 
+def add_parse_warning(msg, line, type='model.confml'):
+    parsecontext.get_confml_context().handle_problem(
+        api.Problem(msg,
+                    severity = api.Problem.SEVERITY_WARNING,
+                    type     = type,
+                    line     = line))
 
+def add_unknown_element_warning(elem):
+    add_parse_warning("Unknown element '%s'" % elem.tag,
+                      utils.etree.get_lineno(elem),
+                      type='model.confml.unknown_element')
 
 class ConfmlWriter(persistence.ConeWriter):
     """
@@ -69,7 +86,11 @@
         @param xml: The xml which to read. reads only the first object. 
         """
         reader = get_reader_for_elem("configuration")
-        etree = utils.etree.fromstring(xmlstr)
+        try:
+            etree = utils.etree.fromstring(xmlstr)
+        except exceptions.XmlParseError, e:
+            e.problem_type = 'xml.confml'
+            raise e
         return reader.loads(etree)
 
 
@@ -105,7 +126,13 @@
             elem.set("xmlns:xlink",self.xlink_namespace)
         if self.schema_namespace:
             elem.set("xmlns:xs",self.schema_namespace)
-        elem.set("name",obj.get_name()) 
+        if obj.get_name():
+            elem.set("name", obj.get_name()) 
+        if obj.version != None:
+            elem.set("version", obj.version) 
+        if obj.get_id():
+            elem.set('id', obj.get_id())
+
         for child in obj._objects():
             """ Make sure that the object is mapped to an object in this model """
             mobj = child._get_mapper('confml').map_object(child)
@@ -137,8 +164,11 @@
         self.schema_namespaces         = SCHEMA_NAMESPACES
 
     def loads(self, etree):
-        configuration = model.ConfmlConfiguration("")
-        configuration.set_name(etree.get("name") or 'unknown') 
+        configuration = model.ConfmlConfiguration(name=etree.get("name"),
+                                                  id=etree.get("id"),
+                                                  version=etree.get("version"))
+        configuration.lineno = utils.etree.get_lineno(etree)
+        # configuration.set_name(etree.get("name") or 'unknown') 
         configuration.set_ref(etree.get("name") or 'unknown')
         for elem in etree.getchildren():
             # At the moment we ignore the namespace of elements
@@ -149,7 +179,7 @@
                 if obj:
                     configuration.add(obj)
             except exceptions.ConePersistenceError,e:
-                logging.getLogger('cone').warning("Could not parse element %s. Exception: %s" % (elem,e))
+                add_unknown_element_warning(elem)
                 continue
         return configuration
 
@@ -202,6 +232,7 @@
 
     def loads(self,etree):
         metaelem = model.ConfmlMeta()
+        metaelem.lineno = utils.etree.get_lineno(etree)
         for elem in etree.getchildren():            
             (namespace,elemname) = get_elemname(elem.tag)
             attributes = {}
@@ -250,6 +281,7 @@
 
     def loads(self,elem):
         desc = model.ConfmlDescription(elem.text)
+        desc.lineno = utils.etree.get_lineno(elem)
         return desc
 
 class ConfigurationProxyWriter(ConfmlWriter):
@@ -295,8 +327,9 @@
         """
         @param elem: The xml include elem
         """
-        
-        return api.ConfigurationProxy(self.parse_include(elem))
+        proxy = api.ConfigurationProxy(self.parse_include(elem))
+        # proxy.lineno = utils.etree.get_lineno(elem)
+        return proxy
 
     def parse_include(self,include):
         #print "Found include %s" % include.get('href').replace('#/','')
@@ -321,10 +354,17 @@
         @param obj: The Configuration object 
         """
         elem = ElementTree.Element('feature', 
-                                   {'ref' : obj.get_ref(),
-                                    'name' : obj.get_name()})
+                                   {'ref' : obj.get_ref()})
+        if obj.get_name():
+            elem.set('name', obj.get_name())
         if obj.get_type():
             elem.set('type', obj.get_type())
+        if obj.get_id() != None:
+            elem.set('id', obj.get_id())
+        if obj.get_relevant() != None:
+            elem.set('relevant', obj.get_relevant())
+        if obj.get_constraint() != None:
+            elem.set('constraint', obj.get_constraint())
         for child in obj._objects():
             """ Make sure that the object is mapped to an object in this model """
             mobj = child._get_mapper('confml').map_object(child)
@@ -360,7 +400,14 @@
             feature = model.ConfmlFeature(elem.get('ref'))
         if elem.get('name'):
             feature.set_name(elem.get('name'))
+        if elem.get('id') != None:
+            feature.set_id(elem.get('id'))
+        if elem.get('relevant') != None:
+            feature.set_relevant(elem.get('relevant'))
+        if elem.get('constraint') != None:
+            feature.set_constraint(elem.get('constraint'))
         feature.set_type(type)
+        feature.lineno = utils.etree.get_lineno(elem)
         for elem in elem.getchildren():
             # At the moment we ignore the namespace of elements
             (namespace,elemname) = get_elemname(elem.tag)
@@ -369,7 +416,7 @@
                 obj = reader.loads(elem)
                 feature.add(obj)
             except exceptions.ConePersistenceError,e:
-                logging.getLogger('cone').warning("Could not parse element %s. Exception: %s" % (elem,e))
+                add_unknown_element_warning(elem)
                 continue
         return feature
 
@@ -396,6 +443,9 @@
         if obj.get_value() is not None: objdict['value'] = obj.get_value()
         if obj.map is not None: objdict['map'] = obj.map
         if obj.relevant is not None: objdict['relevant'] = obj.relevant
+        if obj.display_name is not None: objdict['displayName'] = obj.display_name
+        if obj.map_value is not None: objdict['mapValue'] = obj.map_value
+
         elem = ElementTree.Element('option', objdict)
         
         return elem
@@ -422,11 +472,16 @@
         name = elem.get('name')
         value = elem.get('value')
         optmap = elem.get('map')
+
         if value == None and optmap == None:
             logging.getLogger('cone').warning("Encountered option with no value")
             option = None
         else:
-            option = api.Option(name, value, map=optmap, relevant=elem.get('relevant'))
+            option = api.Option(name, value, map=optmap, 
+                                relevant=elem.get('relevant'),
+                                map_value=elem.get('mapValue'), 
+                                display_name=elem.get('displayName'))
+            option.lineno = utils.etree.get_lineno(elem) 
         return option
 
 
@@ -471,6 +526,7 @@
         """
         href = elem.get('{%s}href' % XLINK_NAMESPACES[0])
         obj = model.ConfmlIcon(href)
+        obj.lineno = utils.etree.get_lineno(elem)
         return obj
 
 
@@ -481,7 +537,7 @@
         Class method to determine if this ConfmlWriter supports writing
         of the given class name
         """
-        if classname=="ConfmlProperty":
+        if classname=="Property":
             return True
         else:
             return False
@@ -518,7 +574,8 @@
         """
         @param elem: The xml include elem
         """
-        option = model.ConfmlProperty(name=elem.get('name'),value=elem.get('value'), unit=elem.get('unit'))
+        option = api.Property(name=elem.get('name'),value=elem.get('value'), unit=elem.get('unit'))
+        option.lineno = utils.etree.get_lineno(elem)
         return option
 
 
@@ -574,6 +631,7 @@
         elem_name = utils.xml.split_tag_namespace(elem.tag)[1]
         facet_class = self.MAPPING[elem_name]
         obj = facet_class(elem.get('value'))
+        obj.lineno = utils.etree.get_lineno(elem)
         return obj
 
 
@@ -584,9 +642,8 @@
         Class method to determine if this ConfmlWriter supports writing
         of the given class name
         """
-        if classname=="Data":
-            return True
-        if classname=="DataContainer":
+        if classname=="Data" or \
+           classname=="DataContainer":
             return True
         else:
             return False
@@ -597,14 +654,16 @@
         """
         # Create a data hierarchy of the 
         elem = ElementTree.Element(obj.get_ref())
-        if hasattr(obj,'get_value') and obj.get_value() and not obj.get_map():
+        if hasattr(obj,'get_map') and obj.get_map() is not None:
+            elem.set('map', obj.get_map())
+        elif hasattr(obj,'get_value') and obj.get_value() is not None:
             elem.text = obj.get_value()
-        elif hasattr(obj,'get_map') and obj.get_map():
-            elem.set('map', obj.get_map())
         if hasattr(obj,'template') and obj.template == True:
             elem.set('template','true')
         if hasattr(obj,'policy') and obj.policy != '':
             elem.set('extensionPolicy',obj.policy)
+        if hasattr(obj,'empty') and obj.empty == True:
+            elem.set('empty','true')
         for child in obj._objects():
             writer = DataWriter()
             childelem = writer.dumps(child)
@@ -634,13 +693,14 @@
         
         (namespace,elemname) = get_elemname(elem.tag)
         obj = api.DataContainer(elemname, container=True)
+        obj.lineno = utils.etree.get_lineno(elem)
         for elem in elem.getchildren():
             try:
                 reader = ElemReader(attr='data')
                 childobj = reader.loads(elem)
                 obj.add(childobj)
             except exceptions.ConePersistenceError,e:
-                logging.getLogger('cone').warning("Could not parse element %s. Exception: %s" % (elem,e))
+                add_unknown_element_warning(elem)
                 continue
         return obj
 
@@ -663,8 +723,9 @@
         @param obj: The Configuration object 
         """
         elem = ElementTree.Element('view', 
-                                   {'id' : obj.get_ref(),
-                                    'name' : obj.get_name()})
+                                   {'name' : obj.get_name()})
+        if obj.id != None:  
+            elem.set('id', obj.id)
         for child in obj._objects():
             """ Make sure that the object is mapped to an object in this model """
             mobj = child._get_mapper('confml').map_object(child)
@@ -696,6 +757,7 @@
         vid = elem.get('id')
         name = elem.get('name')
         view = model.ConfmlView(name, id=vid)
+        view.lineno = utils.etree.get_lineno(elem)
         for elem in elem.getchildren():
             # At the moment we ignore the namespace of elements
             (namespace,elemname) = get_elemname(elem.tag)
@@ -704,7 +766,7 @@
                 obj = reader.loads(elem)
                 view.add(obj)
             except exceptions.ConePersistenceError,e:
-                logging.getLogger('cone').warning("Could not parse element %s. Exception: %s" % (elem,e))
+                add_unknown_element_warning(elem)
                 continue
         return view
 
@@ -727,6 +789,9 @@
         """
         elem = ElementTree.Element('group', 
                                    {'name' : obj.get_name()})
+        if obj.get_id():
+            elem.set('id', obj.get_id())
+
         for child in obj._objects():
             """ Make sure that the object is mapped to an object in this model """
             mobj = child._get_mapper('confml').map_object(child)
@@ -758,6 +823,9 @@
         gname = elem.get('name')
         gref = utils.resourceref.to_dref(gname).replace('.','_')
         group = model.ConfmlGroup(gref, name=gname)
+        group.lineno = utils.etree.get_lineno(elem)
+        if elem.get('id'):
+            group.set_id(elem.get('id'))
         for elem in elem.getchildren():
             # At the moment we ignore the namespace of elements
             (namespace,elemname) = get_elemname(elem.tag)
@@ -767,58 +835,11 @@
                 if obj != None:
                     group.add(obj)
             except exceptions.ConePersistenceError,e:
-                logging.getLogger('cone').warning("Could not parse element %s. Exception: %s" % (elem,e))
+                add_unknown_element_warning(elem)
                 continue
         return group
 
 
-class GroupSettingWriter(ConfmlWriter):
-    """
-    """ 
-    @classmethod
-    def supported_class(cls, classname):
-        """
-        Class method to determine if this ConfmlWriter supports writing
-        of the given class name
-        """
-        if classname=="FeatureLink":
-            return True
-        else:
-            return False
-
-    def dumps(self, obj):
-        """
-        @param obj: The Configuration object 
-        """
-        ref = obj.fqr.replace('.','/')
-        elem = ElementTree.Element('setting', 
-                                   {'ref' : ref})
-        return elem
-
-class GroupSettingReader(ConfmlReader):
-    """
-    """ 
-    @classmethod
-    def supported_elem(cls, elemname, parent=None):
-        """
-        Class method to determine if this ConfmlWriter supports reading
-        of the given elem name
-        """
-        if elemname=='setting' and parent=='group':
-            return True
-        else:
-            return False
-
-    def loads(self, elem):
-        """
-        @param elem: The xml include elem
-        """
-        ref = elem.get('ref') or ''
-        ref = ref.replace('/','.')
-        return api.FeatureLink(ref)
-
-
-
 class ConfmlSettingWriter(ConfmlWriter):
     @classmethod
     def supported_class(cls, classname):
@@ -837,6 +858,7 @@
            classname=="ConfmlTimeSetting" or \
            classname=="ConfmlDateTimeSetting" or \
            classname=="ConfmlDurationSetting" or \
+           classname=="ConfmlHexBinarySetting" or \
            classname=="ConfmlFileSetting" or \
            classname=="ConfmlFolderSetting" or \
            classname=="FeatureSequence" or \
@@ -850,10 +872,20 @@
         @param obj: The Configuration object 
         """
         elem = ElementTree.Element('setting', 
-                                   {'ref' : obj.get_ref(),
-                                    'name' : obj.get_name()})
+                                   {'ref' : obj.get_ref()})
+        self._set_setting_properties(elem, obj)
+        return elem
+
+    def _set_setting_properties(self, elem, obj):
+        """
+        Set the setting properties for the given elm from the given feature object
+        """
+        if obj.get_name():
+            elem.set('name', obj.get_name())
         if obj.type:
             elem.set('type', obj.get_type())
+        if obj.get_id():
+            elem.set('id', obj.get_id())
         if hasattr(obj,'minOccurs'):
             elem.set('minOccurs', str(obj.minOccurs))
         if hasattr(obj,'maxOccurs'):
@@ -870,6 +902,8 @@
             elem.set('mapKey', str(obj.mapKey))
         if hasattr(obj,'mapValue') and obj.mapValue is not None:
             elem.set('mapValue', str(obj.mapValue))
+        if hasattr(obj,'displayName') and obj.displayName is not None:
+            elem.set('displayName', str(obj.displayName))
             
         for child in obj._objects():
             """ Make sure that the object is mapped to an object in this model """
@@ -878,7 +912,6 @@
             childelem = writer.dumps(child)
             if childelem != None:
                 elem.append(childelem)
-        return elem
 
 
 class ConfmlSettingReader(ConfmlReader):
@@ -891,7 +924,7 @@
         of the given elem name
         """
         if parent and not (parent=='feature' or parent=='setting'):
-             return False
+            return False
         if elemname=='setting':
             return True
         else:
@@ -905,7 +938,8 @@
         if typedef == 'sequence':
             map_key = elem.get('mapKey')
             map_value = elem.get('mapValue')
-            feature = model.ConfmlSequenceSetting(elem.get('ref'), mapKey=map_key, mapValue=map_value)
+            display_name = elem.get('displayName')
+            feature = model.ConfmlSequenceSetting(elem.get('ref'), mapKey=map_key, mapValue=map_value, displayName=display_name)
         elif typedef == 'int':
             feature = model.ConfmlIntSetting(elem.get('ref'))
         elif typedef == 'boolean':
@@ -930,14 +964,25 @@
             feature = model.ConfmlDateTimeSetting(elem.get('ref'))
         elif typedef == 'duration':
             feature = model.ConfmlDurationSetting(elem.get('ref'))
+        elif typedef == 'hexBinary':
+            feature = model.ConfmlHexBinarySetting(elem.get('ref'))
         
            
         else:
             # Handle the default setting as int type
-            feature = model.ConfmlSetting(elem.get('ref'), type=None)
+            feature = model.ConfmlSetting(elem.get('ref'), type=typedef)
+        feature.lineno = utils.etree.get_lineno(elem)
+        self._get_setting_properties(elem, feature)
+        return feature
         
+    def _get_setting_properties(self, elem, feature):
+        """
+        Get the setting properties for the given feature from the given xml elem
+        """
         if elem.get('name'):
             feature.set_name(elem.get('name'))
+        if elem.get('id'):
+            feature.set_id(elem.get('id'))
         if elem.get('minOccurs'):
             feature.minOccurs = int(elem.get('minOccurs'))
         if elem.get('maxOccurs'):
@@ -960,12 +1005,63 @@
                 if obj != None:
                     feature.add(obj,container.APPEND)
                 else:
-                    logging.getLogger('cone').warning("Invalid child %s in %s" % (elem,feature.name))
+                    add_parse_warning("Invalid child %s in %s" % (elem, feature.name),
+                                      utils.etree.get_lineno(elem))
             except exceptions.ConePersistenceError,e:
-                logging.getLogger('cone').warning("Could not parse element %s. Exception: %s" % (elem,e))
+                add_unknown_element_warning(elem)
                 continue
-        return feature
+
+
+class GroupSettingWriter(ConfmlSettingWriter):
+    """
+    """ 
+    @classmethod
+    def supported_class(cls, classname):
+        """
+        Class method to determine if this ConfmlWriter supports writing
+        of the given class name
+        """
+        if classname=="FeatureLink" or \
+           classname=="ConfmlFeatureLink":
+            return True
+        else:
+            return False
 
+    def dumps(self, obj):
+        """
+        @param obj: The Configuration object 
+        """
+        ref = obj.fqr.replace('.','/')
+        elem = ElementTree.Element('setting', 
+                                   {'ref' : ref})
+        self._set_setting_properties(elem, obj)
+        return elem
+
+
+class GroupSettingReader(ConfmlSettingReader):
+    """
+    """ 
+    @classmethod
+    def supported_elem(cls, elemname, parent=None):
+        """
+        Class method to determine if this ConfmlWriter supports reading
+        of the given elem name
+        """
+        if elemname=='setting' and parent=='group':
+            return True
+        else:
+            return False
+
+    def loads(self, elem):
+        """
+        @param elem: The xml include elem
+        """
+        ref = elem.get('ref') or ''
+        ref = ref.replace('/','.')
+        feature_link = model.ConfmlFeatureLink(ref)
+        feature_link.lineno = utils.etree.get_lineno(elem)
+        self._get_setting_properties(elem, feature_link)
+        return feature_link
 
 class ConfmlLocalPathWriter(ConfmlWriter):
     @classmethod
@@ -1007,7 +1103,9 @@
         """
         @param elem: The xml include elem
         """
-        return model.ConfmlLocalPath(readOnly=elem.get('readOnly'))
+        obj = model.ConfmlLocalPath(readOnly=elem.get('readOnly'))
+        obj.lineno = utils.etree.get_lineno(elem)
+        return obj
 
 
 class ConfmlTargetPathWriter(ConfmlWriter):
@@ -1050,7 +1148,9 @@
         """
         @param elem: The xml include elem
         """
-        return model.ConfmlTargetPath(readOnly=elem.get('readOnly'))
+        obj = model.ConfmlTargetPath(readOnly=elem.get('readOnly'))
+        obj.lineno = utils.etree.get_lineno(elem)
+        return obj
 
 
 class DummyWriter(ConfmlWriter):
@@ -1094,13 +1194,14 @@
         
         (namespace,elemname) = get_elemname(elem.tag)
         obj = api.DataContainer(elemname, container=True)
+        obj.lineno = utils.etree.get_lineno(elem)
         for elem in elem.getchildren():
             try:
                 reader = ElemReader(attr='rfs')
                 childobj = reader.loads(elem)
                 obj.add(childobj)
             except exceptions.ConePersistenceError,e:
-                logging.getLogger('cone').warning("Could not parse element %s. Exception: %s" % (elem,e))
+                add_unknown_element_warning(elem)
                 continue
         return obj
 
@@ -1118,10 +1219,15 @@
         datavalue = None
         if len(list(elem)) == 0:
             datavalue = elem.text
-        datatemplate = elem.get('template') == 'true' or self.template
-        dataextensionpolicy = elem.get('extensionPolicy') or ''
-        datamap = elem.get('map')
-        obj = api.Data(ref=elemname,value=datavalue, template=datatemplate, attr=self.attr,policy=dataextensionpolicy,map=datamap)
+        obj = model.ConfmlData(
+            ref      = elemname,
+            value    = datavalue,
+            template = elem.get('template') == 'true' or self.template,
+            attr     = self.attr,
+            policy   = elem.get('extensionPolicy') or '',
+            map      = elem.get('map'),
+            empty    = elem.get('empty') == 'true')
+        obj.lineno = utils.etree.get_lineno(elem)
         for elem in elem.getchildren():
             try:
                 reader = ElemReader(**self.args)
@@ -1152,13 +1258,13 @@
         
 
 def get_reader_for_elem(elemname, parent=None):
-    for reader in ConfmlReader.__subclasses__():
+    for reader in utils.all_subclasses(ConfmlReader):
         if reader.supported_elem(elemname,parent):
             return reader()
     raise exceptions.ConePersistenceError("No reader for given elem %s under %s found!" % (elemname, parent))
 
 def get_writer_for_class(classname):
-    for writer in ConfmlWriter.__subclasses__():
+    for writer in utils.all_subclasses(ConfmlWriter):
         if writer.supported_class(classname):
             return writer ()
     raise exceptions.ConePersistenceError("No writer for given class found! %s" % classname)
--- a/configurationengine/source/cone/confml/tests/__init__.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/confml/tests/__init__.py	Tue Aug 10 14:29:28 2010 +0300
@@ -14,33 +14,3 @@
 # Description: 
 #
 
-import unittest, os, sys
-
-ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
-SOURCE_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../../..'))
-if SOURCE_ROOT not in sys.path:
-    sys.path.insert(0, SOURCE_ROOT)
-
-# Find all unittest_*.py files in this folder
-import re
-__all__ = filter(lambda name: re.match(r'^unittest_.*\.py$', name) != None, os.listdir(ROOT_PATH))
-# Strip .py endings
-__all__ = map(lambda name: name[:-3], __all__)
-
-def collect_suite():  
-    sys.path.insert(0, ROOT_PATH)
-    try:
-        suite = unittest.TestSuite()
-        for test_module in __all__:
-            # Load the test module dynamically and add it to the test suite
-            module = __import__(test_module)
-            suite.addTests(unittest.TestLoader().loadTestsFromModule(module))
-        return suite
-    finally:
-        del sys.path[0]
-
-def runtests():
-    unittest.TextTestRunner(verbosity=2).run(collect_suite())
-
-if __name__ == '__main__':
-    runtests()
--- a/configurationengine/source/cone/confml/tests/data/multiselection.confml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/confml/tests/data/multiselection.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -47,7 +47,7 @@
 	      </user_udafiles>
 	</uda_content>
     <uda_selection>
-      <selectedfiles></selectedfiles>
+      <selectedfiles empty="true"/>
     </uda_selection>   
     
   </data>
--- a/configurationengine/source/cone/confml/tests/runtests.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/confml/tests/runtests.py	Tue Aug 10 14:29:28 2010 +0300
@@ -14,6 +14,6 @@
 # Description: 
 #
 
-import __init__
-
-__init__.runtests()
+if __name__ == '__main__':
+    import nose
+    nose.core.run(argv=['collector','--include=unittest', '--verbosity=3'])
--- a/configurationengine/source/cone/confml/tests/testdata/read_write/basic_setting_types_test.confml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/confml/tests/testdata/read_write/basic_setting_types_test.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -36,6 +36,10 @@
       <confml:option name="Option 3" value="opt 3"/>
       <confml:option name="Option 4" value="opt 4"/>
     </confml:setting>
+    
+    <confml:setting ref="HexBinarySetting" name="Hex-binary setting" type="hexBinary">
+      <confml:desc>A hex-binary setting</confml:desc>
+    </confml:setting>
   </confml:feature>
   
   <confml:data>
@@ -46,6 +50,7 @@
       <confml:BooleanSetting>true</confml:BooleanSetting>
       <confml:SelectionSetting>1</confml:SelectionSetting>
       <confml:MultiSelectionSetting>"opt 0" "opt 2" "opt 4"</confml:MultiSelectionSetting>
+      <confml:HexBinarySetting>00112233445566778899AABBCCDDEEFF</confml:HexBinarySetting>
     </confml:BasicSettingTypesTest>
   </confml:data>
   
@@ -57,6 +62,7 @@
       <confml:BooleanSetting>true</confml:BooleanSetting>
       <confml:SelectionSetting>true</confml:SelectionSetting>
       <confml:MultiSelectionSetting>true</confml:MultiSelectionSetting>
+      <confml:HexBinarySetting>false</confml:HexBinarySetting>
     </confml:BasicSettingTypesTest>
   </confml:rfs>
 </confml:configuration>
Binary file configurationengine/source/cone/confml/tests/testdata/read_write/configuration_version_test.confml has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/tests/testdata/read_write/data.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/2" name="data">
+    <data>
+        <TestFeature>
+            <Template template="true"/>
+            <InvalidMap map="foobar"/>
+            <EmptyMap map=""/>
+            <InvalidExtensionPolicy extensionPolicy="foobar"/>
+            <Empty empty="true"/>
+        </TestFeature>
+    </data>
+</configuration>
\ No newline at end of file
Binary file configurationengine/source/cone/confml/tests/testdata/read_write/empty_attributes_test.confml has changed
Binary file configurationengine/source/cone/confml/tests/testdata/read_write/facets.confml has changed
--- a/configurationengine/source/cone/confml/tests/testdata/read_write/feature1.confml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/confml/tests/testdata/read_write/feature1.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -96,6 +96,8 @@
         <SelectionSubSetting>1</SelectionSubSetting>
         <MultiSelectionSubSetting>"opt 2"</MultiSelectionSubSetting>
       </SequenceSetting>
+      
+      <FooBar empty="true"/>
     </Feature1>
   </data>
   
--- a/configurationengine/source/cone/confml/tests/testdata/read_write/name_id_mapping_test.confml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/confml/tests/testdata/read_write/name_id_mapping_test.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -5,7 +5,7 @@
             <setting ref="Value" name="Value sub-setting" type="string"/>
         </setting>
         
-        <setting ref="StringToStringSequence" name="String-to-string sequence" type="sequence" mapKey="Name" mapValue="Value">
+        <setting ref="StringToStringSequence" name="String-to-string sequence" type="sequence" mapKey="Name" mapValue="Value" displayName="Name">
             <setting ref="Name" name="Name sub-setting" type="string"/>
             <setting ref="Value" name="Value sub-setting" type="string"/>
         </setting>
@@ -25,7 +25,7 @@
     <feature ref="NameIdMappingTestTargetSettings" name="Target settings for name-ID mappings">
         <setting ref="Selection" name="Selection setting" type="selection">
             <option map="NameIdMappingTestSourceSequences/StringSequence"/>
-            <option map="NameIdMappingTestSourceSequences/StringToStringSequence"/>
+            <option map="NameIdMappingTestSourceSequences/StringToStringSequence" displayName="Name" mapValue="Value"/>
             <option name="None" value="none"/>
         </setting>
         
--- a/configurationengine/source/cone/confml/tests/testdata/read_write/view.confml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/confml/tests/testdata/read_write/view.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -25,7 +25,7 @@
     
     <confml:group name="Settings for testing attribute 'relevant'">
         <confml:group name="In options">
-            <confml:setting ref="RelevantOptionTest/*"/>
+            <confml:setting ref="RelevantOptionTest/*" readOnly="true"/>
         </confml:group>
         <confml:group name="In settings">
             <confml:setting ref="RelevantSettingTest/*"/>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/tests/testdata/seq_template/expected/complex_seq.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,80 @@
+<configuration name="write_complex_seq_confml" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+  <feature name="Test feature" ref="TestFeature">
+    <setting name="Sequence setting" ref="SequenceSetting" type="sequence">
+      <setting name="File setting" ref="File" type="file">
+        <localPath />
+      <targetPath />
+      </setting>
+    <setting name="Folder setting" ref="Folder" type="folder">
+        <localPath />
+      <targetPath />
+      </setting>
+    <setting name="String setting" ref="String" type="string" />
+    <setting name="Int setting" ref="Int" type="int" />
+    <setting name="Real setting" ref="Real" type="real" />
+    <setting name="Boolean setting" ref="Boolean" type="boolean" />
+    <setting name="Date setting" ref="Date" type="date" />
+    <setting name="Time setting" ref="Time" type="time" />
+    <setting name="Date-time setting" ref="DateTime" type="dateTime" />
+    <setting name="Duration setting" ref="Duration" type="duration" />
+    </setting>
+  </feature>
+<data>
+    <TestFeature>
+      <SequenceSetting template="true">
+        <File>
+          <localPath>file lp</localPath>
+        <targetPath>file tp</targetPath>
+        </File>
+      <Folder>
+          <localPath>folder lp</localPath>
+        <targetPath>folder tp</targetPath>
+        </Folder>
+      <String>string</String>
+      <Int>0</Int>
+      <Real>0.1</Real>
+      <Boolean>false</Boolean>
+      <Date>2010-02-10</Date>
+      <Time>00:00:00</Time>
+      <DateTime>2010-02-10-00:00:00</DateTime>
+      <Duration>P5Y4M3DT12H25M15S</Duration>
+      </SequenceSetting>
+    <SequenceSetting>
+        <File>
+          <localPath>file lp1</localPath>
+        <targetPath>file tp1</targetPath>
+        </File>
+      <Folder>
+          <localPath>folder lp1</localPath>
+        <targetPath>folder tp1</targetPath>
+        </Folder>
+      <String>string1</String>
+      <Int>1</Int>
+      <Real>1.1</Real>
+      <Boolean>true</Boolean>
+      <Date>2009-02-01</Date>
+      <Time>01:30:15</Time>
+      <DateTime>2009-02-01-01:00:00</DateTime>
+      <Duration>PT1S</Duration>
+      </SequenceSetting>
+    <SequenceSetting>
+        <File>
+          <localPath>file lp2</localPath>
+        <targetPath>file tp2</targetPath>
+        </File>
+      <Folder>
+          <localPath>folder lp2</localPath>
+        <targetPath>folder tp2</targetPath>
+        </Folder>
+      <String>string2</String>
+      <Int>2</Int>
+      <Real>1.2</Real>
+      <Boolean>false</Boolean>
+      <Date>2009-02-02</Date>
+      <Time>02:30:15</Time>
+      <DateTime>2009-02-02-02:00:00</DateTime>
+      <Duration>PT2S</Duration>
+      </SequenceSetting>
+    </TestFeature>
+  </data>
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/tests/testdata/seq_template/expected/complex_seq_with_nones.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,60 @@
+<configuration name="write_complex_seq_with_nones_confml" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+  <feature name="Test feature" ref="TestFeature">
+    <setting name="Sequence setting" ref="SequenceSetting" type="sequence">
+      <setting name="File setting" ref="File" type="file">
+        <localPath />
+      <targetPath />
+      </setting>
+    <setting name="Folder setting" ref="Folder" type="folder">
+        <localPath />
+      <targetPath />
+      </setting>
+    <setting name="String setting" ref="String" type="string" />
+    <setting name="Int setting" ref="Int" type="int" />
+    <setting name="Real setting" ref="Real" type="real" />
+    <setting name="Boolean setting" ref="Boolean" type="boolean" />
+    <setting name="Date setting" ref="Date" type="date" />
+    <setting name="Time setting" ref="Time" type="time" />
+    <setting name="Date-time setting" ref="DateTime" type="dateTime" />
+    <setting name="Duration setting" ref="Duration" type="duration" />
+    </setting>
+  </feature>
+<data>
+    <TestFeature>
+      <SequenceSetting template="true">
+        <File>
+          <localPath>file lp</localPath>
+        </File>
+      <Folder>
+          <targetPath>folder tp</targetPath>
+        </Folder>
+      <String>string</String>
+      <Real>0.1</Real>
+      <Date>2010-02-10</Date>
+      <DateTime>2010-02-10-00:00:00</DateTime>
+      <Int />
+      <Boolean />
+      <Time />
+      <Duration />
+      </SequenceSetting>
+    <SequenceSetting>
+        <File>
+          <localPath>file lp1</localPath>
+        <targetPath />
+        </File>
+      <Folder>
+          <localPath />
+        <targetPath>folder tp1</targetPath>
+        </Folder>
+      <String>string1</String>
+      <Int />
+      <Real>1.1</Real>
+      <Boolean />
+      <Date>2009-02-01</Date>
+      <Time />
+      <DateTime>2009-02-01-01:00:00</DateTime>
+      <Duration />
+      </SequenceSetting>
+    </TestFeature>
+  </data>
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/tests/testdata/seq_template/expected/simple_seq.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,40 @@
+<configuration name="foo" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+  <feature name="Test feature" ref="TestFeature">
+    <setting name="Sequence setting" ref="SequenceSetting" type="sequence">
+      <setting name="String 1" ref="String1" type="string" />
+    <setting name="File setting" ref="File" type="file">
+        <localPath />
+      <targetPath />
+      </setting>
+    <setting name="String 2" ref="String2" type="string" />
+    </setting>
+  </feature>
+<data>
+    <TestFeature>
+      <SequenceSetting template="true">
+        <String1>c1</String1>
+      <File>
+          <localPath>lp</localPath>
+        <targetPath>tp</targetPath>
+        </File>
+      <String2>c2</String2>
+      </SequenceSetting>
+    <SequenceSetting>
+        <String1>row 1</String1>
+      <File>
+          <localPath>lp1</localPath>
+        <targetPath>tp1</targetPath>
+        </File>
+      <String2>x</String2>
+      </SequenceSetting>
+    <SequenceSetting>
+        <String1>row 2</String1>
+      <File>
+          <localPath>lp2</localPath>
+        <targetPath>tp2</targetPath>
+        </File>
+      <String2>y</String2>
+      </SequenceSetting>
+    </TestFeature>
+  </data>
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/confml/tests/testdata/seq_template/expected/simple_seq_no_template.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,32 @@
+<configuration name="write_simple_seq_no_template_confml" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+  <feature name="Test feature" ref="TestFeature">
+    <setting name="Sequence setting" ref="SequenceSetting" type="sequence">
+      <setting name="String 1" ref="String1" type="string" />
+    <setting name="File setting" ref="File" type="file">
+        <localPath />
+      <targetPath />
+      </setting>
+    <setting name="String 2" ref="String2" type="string" />
+    </setting>
+  </feature>
+<data>
+    <TestFeature>
+      <SequenceSetting>
+        <String1>row 1</String1>
+      <File>
+          <localPath>lp1</localPath>
+        <targetPath>tp1</targetPath>
+        </File>
+      <String2>x</String2>
+      </SequenceSetting>
+    <SequenceSetting>
+        <String1>row 2</String1>
+      <File>
+          <localPath>lp2</localPath>
+        <targetPath>tp2</targetPath>
+        </File>
+      <String2>y</String2>
+      </SequenceSetting>
+    </TestFeature>
+  </data>
+</configuration>
\ No newline at end of file
--- a/configurationengine/source/cone/confml/tests/unittest_confmlxml.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/confml/tests/unittest_confmlxml.py	Tue Aug 10 14:29:28 2010 +0300
@@ -23,7 +23,6 @@
 import sys
 import os
 import shutil
-import __init__
 
 from cone.public import api, exceptions, persistence
 from cone.storage import filestorage
--- a/configurationengine/source/cone/confml/tests/unittest_implml.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/confml/tests/unittest_implml.py	Tue Aug 10 14:29:28 2010 +0300
@@ -16,7 +16,6 @@
 
 import unittest
 import os
-import __init__
 from cone.public.exceptions import NotSupportedException
 
 from cone.confml import implml
--- a/configurationengine/source/cone/confml/tests/unittest_mapping.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/confml/tests/unittest_mapping.py	Tue Aug 10 14:29:28 2010 +0300
@@ -20,7 +20,6 @@
 import sys
 import os
 import shutil
-import __init__
 
 from cone.public import api, exceptions
 from cone.confml import model, mapping
@@ -84,7 +83,7 @@
 
     def test_map_carbon_setting_with_data(self):
         mapper = model.get_mapper('carbon')
-        c1 = model.ConfmlSetting("test")
+        c1 = model.ConfmlSetting("test", name="test")
         c2 = mapper.map_object(c1)
         self.assertTrue(isinstance(c2, carbonmodel.CarbonSetting))
         self.assertEquals(c2.name, "test")
@@ -92,7 +91,7 @@
 
     def test_map_carbon_setting_with_desc(self):
         mapper = model.get_mapper('carbon')
-        c1 = model.ConfmlSetting("test")
+        c1 = model.ConfmlSetting("test", name="test")
         c1.desc = 'Testing man'
         c2 = mapper.map_object(c1)
         self.assertTrue(isinstance(c2, carbonmodel.CarbonSetting))
@@ -102,7 +101,7 @@
         
     def test_map_carbon_int_setting_with_data(self):
         mapper = model.get_mapper('carbon')
-        c1 = model.ConfmlIntSetting("test")
+        c1 = model.ConfmlIntSetting("test", name="test")
         c2 = mapper.map_object(c1)
         self.assertTrue(isinstance(c2, carbonmodel.CarbonIntSetting))
         self.assertEquals(c2.name, "test")
@@ -110,7 +109,7 @@
 
     def test_map_carbon_setting_with_data(self):
         mapper = model.get_mapper('carbon')
-        c1 = model.ConfmlBooleanSetting("test")
+        c1 = model.ConfmlBooleanSetting("test", name="test")
         c2 = mapper.map_object(c1)
         self.assertTrue(isinstance(c2, carbonmodel.CarbonBooleanSetting))
         self.assertEquals(c2.name, "test")
@@ -118,7 +117,7 @@
 
     def test_map_carbon_setting_with_data(self):
         mapper = model.get_mapper('carbon')
-        c1 = model.ConfmlSelectionSetting("test")
+        c1 = model.ConfmlSelectionSetting("test", name="test")
         c2 = mapper.map_object(c1)
         self.assertTrue(isinstance(c2, carbonmodel.CarbonSelectionSetting))
         self.assertEquals(c2.name, "test")
@@ -126,7 +125,7 @@
 
     def test_map_carbon_feature(self):
         mapper = model.get_mapper('carbon')
-        c1 = model.ConfmlFeature("test")
+        c1 = model.ConfmlFeature("test", name="test")
         c2 = mapper.map_object(c1)
         self.assertTrue(isinstance(c2, carbonmodel.CarbonFeature))
         self.assertEquals(c2.name, "test")
--- a/configurationengine/source/cone/confml/tests/unittest_model.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/confml/tests/unittest_model.py	Tue Aug 10 14:29:28 2010 +0300
@@ -15,10 +15,7 @@
 #
 
 import unittest
-import string
 import sys
-import __init__
-
 from cone.public import api, exceptions
 from cone.confml import model
 
@@ -26,7 +23,7 @@
 class TestConfmlMeta(unittest.TestCase):
     def test_create_meta(self):
         metaelem = model.ConfmlMeta()
-        self.assertTrue(metaelem)
+        self.assertEquals(str(metaelem),"ConfmlMeta object\n")
 
     def test_create_with_data(self):
         prop1 = model.ConfmlMetaProperty("foo", 123)
@@ -37,6 +34,7 @@
                                          attrs={"name":"name1", "value": "value1"})            
         metaelem = model.ConfmlMeta([prop1, prop2, prop3, prop4])
         self.assertEquals(metaelem[0].tag, "foo")
+        self.assertEquals(metaelem[0].attrs, {})
         self.assertEquals(metaelem[0].value, 123)
         self.assertEquals(metaelem[1].tag, "bar")
         self.assertEquals(metaelem[1].value, 312)
@@ -54,15 +52,50 @@
         self.assertEquals(metaelem[0].ns, "abc")
         self.assertEquals(metaelem[0].attrs, {"foo":"bar", "abc":1})
 
+    def test_update_data(self):
+        metaelem = model.ConfmlMeta()
+        metaelem.append(model.ConfmlMetaProperty('test', 123, "abc", attrs = {"foo":"bar", "abc":1}))
+        metaelem.set_property_by_tag('foo', 3)
+        metaelem.set_property_by_tag('bar', None, 'http://me.com', {'name':'me', 'value':1})
+        self.assertEquals(metaelem[0].tag, 'test')
+        self.assertEquals(metaelem[0].value, 123)
+        self.assertEquals(metaelem[0].ns, "abc")
+        self.assertEquals(metaelem[0].attrs, {"foo":"bar", "abc":1})
+        self.assertEquals(metaelem[1].tag, 'foo')
+        self.assertEquals(metaelem[1].value, 3)
+        self.assertEquals(metaelem[2].tag, "bar")
+        self.assertEquals(metaelem[2].attrs, {'name':'me', 'value':1})
+
+        metaelem1 = model.ConfmlMeta()
+        metaelem.set_property_by_tag('foo', 2)
+        metaelem.set_property_by_tag('bar', None, 'http://me.com', {'name':'me', 'value':2})
+        metaelem.update(metaelem1)
+        self.assertEquals(len(metaelem), 3)
+        self.assertEquals(metaelem[0].tag, 'test')
+        self.assertEquals(metaelem[0].value, 123)
+        self.assertEquals(metaelem[0].ns, "abc")
+        self.assertEquals(metaelem[0].attrs, {"foo":"bar", "abc":1})
+        self.assertEquals(metaelem[1].tag, 'foo')
+        self.assertEquals(metaelem[1].value, 2)
+        self.assertEquals(metaelem[2].tag, "bar")
+        self.assertEquals(metaelem[2].attrs, {'name':'me', 'value':2})
+        
+        
     def test_find_data(self):
         metaelem = model.ConfmlMeta()
         metaelem.append(model.ConfmlMetaProperty('test', 123, "abc",\
                                                   attrs = {"foo":"bar", "abc":1}))
         metaelem.append(model.ConfmlMetaProperty('abc', "efg", None,\
                                                   attrs = {"foo2":"bar2", "abc2":2}))
+        metaelem.append(model.ConfmlMetaProperty('test', None, "demons",\
+                                                  attrs = {"name":"bar1", "value":"foo1"}))
+        metaelem.append(model.ConfmlMetaProperty('test', None, "demons",\
+                                                  attrs = {"name":"bar2", "value":"foo2"}))
         self.assertEquals(metaelem.find_by_tag("test"), 0)
         self.assertEquals(metaelem.get_property_by_tag("test").tag, 'test')
         self.assertEquals(metaelem.get_property_by_tag("test").value, 123)
+        self.assertEquals(metaelem.get_property_by_tag("test", {'name' : 'bar1'}).tag, 'test')
+        self.assertEquals(metaelem.get_property_by_tag("test", {'name' : 'bar1'}).attrs['value'], 'foo1')
         self.assertEquals(metaelem.get("test"), 123)
         self.assertEquals(metaelem.get("test", 'ddd'), 123)
         # test get_value with not found elem
@@ -79,7 +112,20 @@
         metaelem2 = metaelem1.clone()
         self.assertEquals(metaelem1, metaelem2)
 
-
+    def test_meta_set_property_by_tag(self):
+        meta = model.ConfmlMeta()
+        meta.set_property_by_tag('test', 'fooval')
+        self.assertEquals(meta.get('test'), 'fooval')
+        self.assertEquals(meta.get_property_by_tag('test').attrs, {})
+        meta.set_property_by_tag('test', 'newval')
+        self.assertEquals(meta.get_property_by_tag('test').attrs, {})
+        self.assertEquals(meta.get('test'), 'newval')
+        meta.add('test', 'twoval')
+        self.assertEquals(meta.get_property_by_tag('test').attrs, {})
+        self.assertEquals(meta.get('test'), 'newval')
+        meta.set_property_by_tag('test', 'trheval')
+        self.assertEquals(meta.get('test'), 'trheval')
+        
 class TestConfmlDescription(unittest.TestCase):
     def test_create_desc(self):
         descelem1 = model.ConfmlDescription("testing")
@@ -141,19 +187,28 @@
         self.assertEquals(elem.constraint, None)
         self.assertEquals(elem.required, None)
         self.assertEquals(elem.relevant, None)
+        self.assertEquals(elem.id, None)
+
+    def test_setting_id(self):
+        elem = model.ConfmlSetting('foo', id="test id")
+        self.assertEquals(elem.id,'test id')
+        elem.id = "new id"
+        self.assertEquals(elem.id,'new id')
+        del elem.id
+        self.assertEquals(elem.id,None)
 
     def test_getters(self):
-        elem = model.ConfmlSetting('foo')
-        self.assertTrue(elem.get_ref(),'foo')
+        elem = model.ConfmlSetting('foo', name="foo")
+        self.assertEquals(elem.get_ref(),'foo')
         self.assertEquals(elem.get_type(),None)
-        self.assertTrue(elem.get_name(),'foo')
+        self.assertEquals(elem.get_name(),'foo')
 
     def test_set_type(self):
-        elem = model.ConfmlSetting('foo')
+        elem = model.ConfmlSetting('foo', name="bar")
         elem.type = 'string'
-        self.assertTrue(elem.ref,'foo')
-        self.assertTrue(elem.type,'string')
-        self.assertTrue(elem.name,'foo')
+        self.assertEquals(elem.ref,'foo')
+        self.assertEquals(elem.type,'string')
+        self.assertEquals(elem.name, "bar")
 
     def test_setting_with_options(self):
         elem = model.ConfmlSetting('foo',type='selection')
@@ -165,15 +220,20 @@
         self.assertEquals(elem.options['1'].value, '1')
         self.assertEquals(elem.options['bar'].name, 'bar')
 
+    def test_create_options(self):
+        elem = model.ConfmlSetting('foo',type='property', name='foo')
+        self.assertEquals(elem.name, 'foo')
+        self.assertEquals(elem.type, 'property')
+
     def test_setting_create_with_nonetype(self):
         elem = model.ConfmlSetting('foo',type=None)
         self.assertEqual(elem.type,None) 
 
     def test_setting_with_properties(self):
         elem = model.ConfmlSetting('foo')
-        elem.add_property(name='foo',value='bar/foo')
-        elem.add_property(name='bar',value='only/bar')
-        elem.add_property(name='testing',value='1', unit='mB')
+        elem.create_property(name='foo',value='bar/foo')
+        elem.create_property(name='bar',value='only/bar')
+        elem.create_property(name='testing',value='1', unit='mB')
         self.assertEquals(elem.list_properties(), ['foo','bar','testing'])
         self.assertEquals(elem.get_property('foo').value, 'bar/foo')
         elem.remove_property('foo')
@@ -190,11 +250,11 @@
 
     def test_setting_with_properties_property(self):
         elem = model.ConfmlSetting('foo')
-        elem.add_property(name='foo',value='bar/foo')
-        elem.add_property(name='bar',value='only/bar')
-        elem.add_property(name='testing',value='1', unit='mB')
-        self.assertEquals(elem.properties['foo'].value,'bar/foo')
-        self.assertEquals(elem.properties['bar'].value,'only/bar')
+        elem.create_property(name='foo',value='bar/foo')
+        elem.create_property(name='bar',value='only/bar')
+        elem.create_property(name='testing',value='1', unit='mB')
+        self.assertEquals(elem.property_foo.value,'bar/foo')
+        self.assertEquals(elem.property_bar.value,'only/bar')
 
     def test_setting_with_readOnly_value(self):
         elem = model.ConfmlSetting('foo', readOnly=True)
@@ -235,6 +295,14 @@
         elem.minLength = 20
         self.assertEquals(elem.minLength,20)
         self.assertTrue(elem._has(model.ConfmlMinLength.refname))
+    
+    def test_setting_with_length(self):
+        elem = model.ConfmlSetting('foo', length=10)
+        self.assertEquals(elem.length,10)
+        elem.length = 20
+        self.assertEquals(elem.length,20)
+        self.assertTrue(elem._has(model.ConfmlLength.refname))
+        self.assertEquals(elem._get(model.ConfmlLength.refname).value, 20)
 
     def test_setting_rfs_casting(self):
         elem = model.ConfmlSetting('foo', minLength=10)
@@ -243,13 +311,63 @@
         self.assertEquals(elem.set_rfs_cast(True),'true')
         self.assertEquals(elem.set_rfs_cast(False),'false')
         self.assertEquals(elem.set_rfs_cast(1),'true')
+    
+    def test_get_rfs_with_no_value(self):
+        conf = api.Configuration("test.confml")
+        conf.add_feature(model.ConfmlSetting("foo"))
+        
+        # Test that initially the RFS value is None
+        fea = conf.get_default_view().get_feature('foo')
+        self.assertEquals(fea.get_value(attr='rfs'), None)
+        self.assertEquals(fea.get_original_value(attr='rfs'), None)
+    
+    def test_get_rfs_true(self):
+        conf = api.Configuration("test.confml")
+        conf.add_feature(model.ConfmlSetting("foo"))
+        conf.add_data(api.Data(ref='foo', attr='rfs', value='true'))
+        
+        fea = conf.get_default_view().get_feature('foo')
+        self.assertEquals(fea.get_value(attr='rfs'), True)
+        self.assertEquals(fea.get_original_value(attr='rfs'), 'true')
+    
+    def test_get_rfs_false(self):
+        conf = api.Configuration("test.confml")
+        conf.add_feature(model.ConfmlSetting("foo"))
+        conf.add_data(api.Data(ref='foo', attr='rfs', value='false'))
+        
+        fea = conf.get_default_view().get_feature('foo')
+        self.assertEquals(fea.get_value(attr='rfs'), False)
+        self.assertEquals(fea.get_original_value(attr='rfs'), 'false')
+    
+    def test_set_rfs(self):
+        conf = api.Configuration("test.confml")
+        conf.add_feature(model.ConfmlSetting("foo"))
+        
+        def check_data_elements(expected):
+            actual = []
+            for d in conf._traverse(type=api.Data):
+                actual.append((d.fqr, d.attr, d.value))
+            self.assertEquals(actual, expected)
+        
+        fea = conf.get_default_view().get_feature('foo')
+        
+        fea.set_value(True, attr='rfs')
+        self.assertEquals(fea.get_value(attr='rfs'), True)
+        self.assertEquals(fea.get_original_value(attr='rfs'), 'true')
+        check_data_elements([('foo', 'rfs', 'true')])
+        
+        fea.set_value(False, attr='rfs')
+        self.assertEquals(fea.get_value(attr='rfs'), False)
+        self.assertEquals(fea.get_original_value(attr='rfs'), 'false')
+        check_data_elements([('foo', 'rfs', 'false')])
 
 class TestConfmlSelectionSetting(unittest.TestCase):
     def test_create_selection_setting(self):
-        elem = model.ConfmlSelectionSetting('foo')
+        elem = model.ConfmlSelectionSetting('foo', desc="Test desc", name="Foo fea")
         self.assertTrue(elem)
         self.assertEquals(elem.type, 'selection')
-        self.assertEquals(elem.desc, None)
+        self.assertEquals(elem.name, 'Foo fea')
+        self.assertEquals(elem.desc, "Test desc")
         self.assertEquals(elem.readOnly, None)
         self.assertEquals(elem.constraint, None)
         self.assertEquals(elem.required, None)
@@ -265,10 +383,11 @@
 
 class TestConfmlMultiSelectionSetting(unittest.TestCase):
     def test_create_multiselection_setting(self):
-        elem = model.ConfmlMultiSelectionSetting('mset1')
+        elem = model.ConfmlMultiSelectionSetting('mset1', name="Setting 1", desc="de")
         self.assertTrue(elem)
         self.assertEquals(elem.type, 'multiSelection')
-        self.assertEquals(elem.desc, None)
+        self.assertEquals(elem.name, "Setting 1")
+        self.assertEquals(elem.desc, "de")
         self.assertEquals(elem.readOnly, None)
         self.assertEquals(elem.constraint, None)
         self.assertEquals(elem.required, None)
@@ -286,33 +405,19 @@
         conf = model.ConfmlConfiguration('test.confml')
         elem = model.ConfmlMultiSelectionSetting('mset2', type='multiSelection')
         conf.add_feature(elem)
-        elem.value = "\"sel1\" \"sel2\""
+        elem.value = ["sel1", "sel2"]
         self.assertEquals(elem.type, 'multiSelection')
-        self.assertEquals(elem.get_data_cast("\"sel1\" \"sel2\""), ["sel1", "sel2"])
-        self.assertEquals(elem.get_value(), ["sel1", "sel2"])
-
-    def test_set_data_cast(self):
-        elem = model.ConfmlMultiSelectionSetting('mset3', type='multiSelection')
-        self.assertEquals(elem.set_data_cast('"sel1" "sel2 with some spaces"'), '"sel1" "sel2 with some spaces"')
-        self.assertEquals(elem.set_data_cast(["sel1", "sel2 with some spaces"]), '"sel1" "sel2 with some spaces"')
-        self.assertEquals(elem.set_data_cast(["1", "1"]), '"1" "1"')
-        self.assertEquals(elem.set_data_cast([1, 2, 3]), '"1" "2" "3"')
-
-
-    def test_get_data_cast(self):
-        elem = model.ConfmlMultiSelectionSetting('mset3', type='multiSelection')
-        self.assertEquals(elem.get_data_cast('"sel1" "sel2 with some spaces"'), ["sel1", "sel2 with some spaces"])
-        self.assertEquals(elem.get_data_cast('"sel1" "sel2 space" "foo bar"'), ["sel1", "sel2 space", "foo bar"])
+        self.assertEquals(elem.get_value(), ("sel1", "sel2"))
 
     def test_setting_value_to_multiselection2(self):
         conf = model.ConfmlConfiguration('test.confml')
         elem = model.ConfmlMultiSelectionSetting('mset3', type='multiSelection')
         conf.add_feature(elem)
-        elem.value = '"sel1" "sel2 with some spaces"'
+        elem.value = ["sel1", "sel2 with some spaces"]
         self.assertEquals(elem.type, 'multiSelection')
-        self.assertEquals(elem.get_value(), ["sel1", "sel2 with some spaces"])
+        self.assertEquals(elem.get_value(), ("sel1", "sel2 with some spaces"))
         elem.value = ["sel1", "sel2 with some spaces"]
-        self.assertEquals(elem.get_value(), ["sel1", "sel2 with some spaces"])
+        self.assertEquals(elem.get_value(), ("sel1", "sel2 with some spaces"))
         
     def test_setting_not_list_value_to_multiselection(self):
         conf = model.ConfmlConfiguration('test.confml')
@@ -325,8 +430,119 @@
         elem = model.ConfmlMultiSelectionSetting('mset5', type='multiSelection')
         conf.add_feature(elem)
         elem.set_value(["li1", "li2"])
-        self.assertEquals(elem.get_value(), ["li1", "li2"])
-        self.assertEquals(elem.get_data().get_value(), '"li1" "li2"')
+        self.assertEquals(elem.get_value(), ("li1", "li2"))
+        self.assertEquals(elem.get_datas()[0].get_value(), 'li1')
+        self.assertEquals(elem.get_datas()[1].get_value(), 'li2')
+    
+    def test_get_value_from_old_style_data(self):
+        def check(data_value, expected):
+            config = api.Configuration('foo.confml')
+            fea = model.ConfmlMultiSelectionSetting('multisel', type='multiSelection')
+            config.add_feature(fea)
+            config.add_data(api.Data(ref='multisel', value=data_value))
+            
+            dview = config.get_default_view()
+            foofea = dview.get_feature('multisel')
+            self.assertEquals(foofea.value, expected)
+
+        check('x', ('x',))
+        check('"x"', ('x',))
+        check('"x" "y"', ('x', 'y'))
+        check('"x" "y" "" "z"', ('x', 'y', '', 'z'))
+    
+    def test_get_value_with_new_style_data(self):
+        def check(data_object_values, expected_value, empty_option=False):
+            config = api.Configuration('foo.confml')
+            fea = model.ConfmlMultiSelectionSetting('multisel', type='multiSelection')
+            if empty_option:
+                fea.add_option(api.Option('Empty option', ''))
+            config.add_feature(fea)
+            for dv in data_object_values:
+                config.add_data(api.Data(ref='multisel', value=dv), policy=api.container.APPEND)
+            
+            dview = config.get_default_view()
+            foofea = dview.get_feature('multisel')
+            self.assertEquals(foofea.value, expected_value)
+        
+        check([], ())
+        check(['x'], ('x',))
+        check(['x', 'y'], ('x', 'y'))
+        check(['y', 'x', 'y',], ('y', 'x'))
+        check(['"foo"', '"bar"'], ('"foo"', '"bar"'))
+        check(['foo bar'], ('foo bar',))
+        check(['foo bar', 'foo baz'], ('foo bar', 'foo baz'))
+        check(['foo "bar"'], ('foo "bar"',))
+        
+        # Element with no data is interpreted as meaning the option ''
+        # if it is allowed, otherwise it is ignored
+        check([None], (), empty_option=False)
+        check([None], ('',), empty_option=True)
+    
+    def test_get_value_from_data_with_empty_attribute(self):
+        config = api.Configuration('foo.confml')
+        fea = model.ConfmlMultiSelectionSetting('multisel', type='multiSelection')
+        config.add_feature(fea)
+        config.add_data(api.Data(ref='multisel', empty=True))
+        
+        dview = config.get_default_view()
+        foofea = dview.get_feature('multisel')
+        self.assertEquals(foofea.value, ())
+        
+        
+    def test_set_value(self):
+        def check(value, expected_data_object_values):
+            config = api.Configuration('foo.confml')
+            fea = model.ConfmlMultiSelectionSetting('multisel', type='multiSelection')
+            config.add_feature(fea)
+            
+            dview = config.get_default_view()
+            foofea = dview.get_feature('multisel')
+            self.assertEquals(foofea.value, ())
+            
+            foofea.value = value
+            # Check that the value is visible directly after setting
+            # (the 'or' is because setting to None actually set the value
+            # to an empty tuple)
+            self.assertEquals(foofea.value, value or ())
+            
+            # Check that the data elements have been set as expected
+            actual = []
+            for d in config._traverse(type=api.Data):
+                actual.append((d.fqr, d.value, d.empty))
+            expected = []
+            for val, empty in expected_data_object_values:
+                expected.append(('multisel', val, empty))
+            self.assertEquals(actual, expected)
+
+        # Setting empty should create a single data object with empty=True
+        check((), [(None, True)])
+        check([], [(None, True)])
+        check(None, [(None, True)])
+        
+        check(('x',), [('x', False)])
+        check(('x', 'y'), [('x', False), ('y', False)])
+        check(('"foo"', '"bar"'), [('"foo"', False), ('"bar"', False)])
+        check(('foo bar',), [('foo bar', False)])
+        check(('foo bar', 'foo baz'), [('foo bar', False), ('foo baz', False)])
+        check(('foo "bar"',), [('foo "bar"', False)])
+    
+    def test_old_style_data_pattern(self):
+        def check(value, expected):
+            m = model.ConfmlMultiSelectionSetting.OLD_STYLE_DATA_PATTERN.match(value)
+            self.assertEquals(m is not None, expected)
+        
+        check('', False)
+        check('""', True)
+        check('foo', False)
+        check('foo bar', False)
+        check('"foo bar"', True)
+        check('"foo bar " " foo baz" "  yeah  " ""', True)
+        check('"foo"', True)
+        check('"foo" "bar"', True)
+        check('"foo" "bar" "baz"', True)
+        check('"a" "b" "c" "d" "e" "f" "g" "h"', True)
+        check('a b c d e f g h', False)
+        check('"a b c d e f g h"', True)
 
 class TestConfmlIntSetting(unittest.TestCase):
     def test_create_setting(self):
@@ -338,6 +554,8 @@
         self.assertEquals(elem.constraint, None)
         self.assertEquals(elem.required, None)
         self.assertEquals(elem.relevant, None)
+        self.assertEquals(elem.get_valueset().fromvalue, 0)
+        self.assertEquals(elem.get_valueset().tovalue, sys.maxint)
 
     def test_setting_value_to_int(self):
         conf = model.ConfmlConfiguration('test.confml')
@@ -364,7 +582,7 @@
         del elem.value
         self.assertEquals(elem.value, None)
 
-    def test_setting_value_to_int(self):
+    def test_setting_value_to_int_with_aritmethic_operations(self):
         conf = model.ConfmlConfiguration('test.confml')
         elem1 = model.ConfmlIntSetting('foo')
         elem2 = model.ConfmlIntSetting('bar')
@@ -377,6 +595,79 @@
         elem1.value = elem1.value + elem2.value + 5
         self.assertEquals(elem1.value,8)
 
+class TestConfmlHexBinarySetting(unittest.TestCase):
+    def test_hexbinary_default_value_set(self):
+        setting = model.ConfmlHexBinarySetting('test')
+        vset = setting.get_valueset()
+        self.assertTrue('' in vset)
+        self.assertTrue('0123456789ABCDEF' in vset)
+        self.assertTrue('00112233445566778899AABBCCDDEEFF' in vset)
+        
+        self.assertFalse('foobar' in vset)
+        self.assertFalse('1' in vset)
+        self.assertFalse('F' in vset)
+        self.assertFalse('1G' in vset)
+        self.assertFalse('0123456789abcdef' in vset)
+        self.assertFalse('00112233445566778899aabbccddeeff' in vset)
+        
+        self.assertTrue('foobar' not in vset)
+
+    def test_hexbinary_get_value_none(self):
+        conf = model.ConfmlConfiguration('test.confml')
+        setting = model.ConfmlHexBinarySetting('foo')
+        conf.add_feature(setting)
+        self.assertEquals(setting.value, None)
+    
+    def test_hexbinary_get_value_empty(self):
+        conf = model.ConfmlConfiguration('test.confml')
+        setting = model.ConfmlHexBinarySetting('foo')
+        conf.add_feature(setting)
+        conf.add_data(api.Data(ref='foo', value=None))
+        self.assertEquals(setting.value, '')
+    
+    def test_hexbinary_get_value(self):
+        conf = model.ConfmlConfiguration('test.confml')
+        setting = model.ConfmlHexBinarySetting('foo')
+        conf.add_feature(setting)
+        conf.add_data(api.Data(ref='foo', value='0123456789ABCDEF'))
+        self.assertEquals(setting.value, '\x01\x23\x45\x67\x89\xab\xcd\xef')
+        self.assertEquals(setting.get_original_value(), '0123456789ABCDEF')
+    
+    def test_hexbinary_set_value(self):
+        conf = model.ConfmlConfiguration('test.confml')
+        setting = model.ConfmlHexBinarySetting('foo')
+        conf.add_feature(setting)
+        
+        setting.value = '\x01\xab'
+        self.assertEquals(setting.value, '\x01\xab')
+        
+        data_list = conf.get_all_datas()
+        self.assertEquals(len(data_list), 1)
+        d = data_list[0]
+        self.assertEquals(d.attr, 'data')
+        self.assertEquals(d.fqr, 'foo')
+        self.assertEquals(d.value, '01AB')
+        self.assertEquals(d.empty, False)
+    
+    def test_hexbinary_get_data_cast(self):
+        setting = model.ConfmlHexBinarySetting('foo')
+        
+        self.assertEquals(setting.get_data_cast(''), '')
+        self.assertEquals(setting.get_data_cast(None), '')
+        self.assertEquals(setting.get_data_cast('0123456789ABCDEF'), '\x01\x23\x45\x67\x89\xab\xcd\xef')
+        
+        self.assertRaises(ValueError, setting.get_data_cast, 'X')
+        self.assertRaises(ValueError, setting.get_data_cast, '1')
+        self.assertRaises(ValueError, setting.get_data_cast, 'XX')
+    
+    def test_hexbinary_set_data_cast(self):
+        setting = model.ConfmlHexBinarySetting('foo')
+        
+        self.assertEquals(setting.set_data_cast(''), '')
+        self.assertEquals(setting.set_data_cast('\x01'), '01')
+        self.assertEquals(setting.set_data_cast('x'), '78')
+        self.assertEquals(setting.set_data_cast('\x01\x23\x45\x67\x89\xab\xcd\xef'), '0123456789ABCDEF')
+        
 class TestConfmlBooleanSetting(unittest.TestCase):
     def test_create_setting(self):
         elem = model.ConfmlBooleanSetting('test')
@@ -438,17 +729,30 @@
 
 class TestConfmlSequenceSetting(unittest.TestCase):
     def test_create_setting(self):
-        elem = model.ConfmlSequenceSetting('test')
+        elem = model.ConfmlSequenceSetting('test', name="testing fea", desc="Test desc")
         self.assertTrue(elem)
-        self.assertEquals(elem.desc, None)
+        self.assertEquals(elem.name, "testing fea")
+        self.assertEquals(elem.desc, "Test desc")
+        subfea = elem.create_feature("subfea")
+        self.assertEquals(subfea.is_sequence(), True)
+        subfea.is_sequence = lambda : False
+        self.assertEquals(subfea.is_sequence(), False)
+        
+    def test_create_sequence_setting_with_mapping(self):
+        elem = model.ConfmlSequenceSetting('test', name="testing fea", desc="Test desc", mapKey="setting", mapValue="setval")
+        self.assertTrue(elem)
+        self.assertEquals(elem.name, "testing fea")
+        self.assertEquals(elem.desc, "Test desc")
+        self.assertEquals(elem.mapKey, "setting")
+        self.assertEquals(elem.mapValue, "setval")
 
     def test_setting_with_properties_property(self):
         elem = model.ConfmlSequenceSetting('foo')
-        elem.add_property(name='foo',value='bar/foo')
-        elem.add_property(name='bar',value='only/bar')
-        elem.add_property(name='testing',value='1', unit='mB')
-        self.assertEquals(elem.properties['foo'].value,'bar/foo')
-        self.assertEquals(elem.properties['bar'].value,'only/bar')
+        elem.create_property(name='foo',value='bar/foo')
+        elem.create_property(name='bar',value='only/bar')
+        elem.create_property(name='testing',value='1', unit='mB')
+        self.assertEquals(elem.property_foo.value,'bar/foo')
+        self.assertEquals(elem.property_bar.value,'only/bar')
 
     def test_setting_with_min_occurs(self):
         elem = model.ConfmlSequenceSetting('foo', minOccurs=1)
@@ -462,9 +766,16 @@
         elem.maxOccurs = 20
         self.assertEquals(elem.maxOccurs,20)
 
-    def test_create_feature_seq_with_int_bool_settings_access_feature_value_with_property(self):
+    def test_create_feature_seq_with_values(self):
+        import logging
+        logger = logging.getLogger('cone')
+        logger.setLevel(logging.DEBUG)
+        ch = logging.StreamHandler()
+        ch.setLevel(logging.DEBUG)
+        logger.addHandler(ch)
+        
         config = api.Configuration('foo.confml')
-        fea= model.ConfmlSequenceSetting("foo")
+        fea= model.ConfmlSequenceSetting("foo", displayName='TestDisplayName')
         fea.add_feature(model.ConfmlIntSetting('child1'))
         fea.add_feature(model.ConfmlBooleanSetting('child2'))
         fea.add_feature(model.ConfmlSetting('child3'))
@@ -472,26 +783,398 @@
         dview = config.get_default_view()
         foofea = dview.get_feature('foo')
         # Test adding a data row with array
-        foofea.set_value([['1','2','3'],
-                         ['4','5','6'],
-                         ['7','8','9']
+        foofea.set_value([[1,True,'foo'],
+                         [2,False,'bar'],
+                         [3,True,'sumthin']
                          ])
-        self.assertEquals(foofea.value, [['1','2','3'],
-                                         ['4','5','6'],
-                                         ['7','8','9']
+        
+        self.assertEquals(foofea.displayName, 'TestDisplayName')
+        self.assertEquals(foofea.data[0][0].get_original_value(), '1')
+        self.assertEquals(foofea.data[0].get_original_value(), ['1', 'true', 'foo'])
+        
+        self.assertEquals(foofea.value, [[1,True,'foo'],
+                                        [2,False,'bar'],
+                                        [3,True,'sumthin']
                                         ])
 
-        foofea.value = [['1','2','3'],
-                         ['7','8','9']
+        self.assertEquals(foofea.get_original_value(), [['1','true','foo'],
+                                                        ['2','false','bar'],
+                                                        ['3','true','sumthin']
+                                                        ])
+        self.assertEquals(foofea.data[0].get_original_value(), ['1','true','foo'])
+        self.assertEquals(foofea.data[1].get_original_value(), ['2','false','bar'])
+        self.assertEquals(foofea.data[2].get_original_value(), ['3', 'true', 'sumthin'])
+        self.assertEquals(foofea.child1.get_original_value(), ['1', '2', '3'])
+        self.assertEquals(foofea.child2.get_original_value(), ['true', 'false', 'true'])
+        self.assertEquals(foofea.child3.get_original_value(), ['foo', 'bar', 'sumthin'])
+
+        foofea.value = [[1,True,'foo'],
+                        [2,False,'bar']
                         ]
         
-        self.assertEquals(foofea.data[0].value,['1','2','3'])
-        self.assertEquals(foofea.data[1].value,['7','8','9'])
-        self.assertEquals(foofea.data[1][1].value,'8')
-        self.assertEquals(foofea.get_value(), [['1','2','3'],
-                                               ['7','8','9']
+        self.assertEquals(foofea.data[0].value,[1,True,'foo'])
+        self.assertEquals(foofea.data[1].value,[2,False,'bar'])
+        self.assertEquals(foofea.data[1][1].value,False)
+        self.assertEquals(foofea.get_value(), [[1,True,'foo'],
+                                               [2,False,'bar']
                                                ])
-        self.assertEquals(foofea.child1.value,['1','7'])
+        self.assertEquals(foofea.child1.value,[1,2])
+    
+    def test_sequence_with_mapped_data(self):
+        config = api.Configuration('foo.confml')
+        
+        fea = model.ConfmlSequenceSetting("SourceSequence", mapKey='KeySubSetting', mapValue="ValueSubSetting")
+        fea.add_feature(model.ConfmlIntSetting("KeySubSetting"))
+        fea.add_feature(model.ConfmlStringSetting("ValueSubSetting"))
+        config.add_feature(fea)
+        
+        fea = model.ConfmlSelectionSetting('TargetSetting')
+        config.add_feature(fea)
+        
+        data = api.Data(ref='SourceSequence')
+        data.add(api.Data(ref='KeySubSetting', value='1'))
+        data.add(api.Data(ref='ValueSubSetting', value='Value 1'))
+        config.add_data(data)
+        
+        data = api.Data(ref='TargetSetting', map="SourceSequence[@key='1']")
+        config.add_data(data)
+        
+        fea = config.get_default_view().get_feature('TargetSetting')
+        self.assertEquals(fea.get_value(), 'Value 1')
+    
+    def test_sequence_with_mapped_data_in_sequence(self):
+        config = api.Configuration('foo.confml')
+        
+        fea = model.ConfmlSequenceSetting("SourceSequence", mapKey='KeySubSetting', mapValue="ValueSubSetting")
+        fea.add_feature(model.ConfmlIntSetting("KeySubSetting"))
+        fea.add_feature(model.ConfmlStringSetting("ValueSubSetting"))
+        config.add_feature(fea)
+        
+        fea = model.ConfmlSequenceSetting('TargetSequence')
+        fea.add_feature(model.ConfmlSelectionSetting("Setting"))
+        config.add_feature(fea)
+        
+        data = api.Data(ref='SourceSequence')
+        data.add(api.Data(ref='KeySubSetting', value='1'))
+        data.add(api.Data(ref='ValueSubSetting', value='Value 1'))
+        config.add_data(data)
+       
+        data = api.Data(ref='TargetSequence')
+        data.add(api.Data(ref='Setting', map="SourceSequence[@key='1']"))
+        config.add_data(data)
+        
+        fea = config.get_default_view().get_feature('TargetSequence')
+        self.assertEquals(fea.get_value(), [['Value 1']])
+    
+    def test_sequence_with_multiselection_set_value(self):
+        config = api.Configuration('foo.confml')
+        
+        fea = model.ConfmlSequenceSetting("fooseq")
+        fea.add_feature(model.ConfmlMultiSelectionSetting("msel"))
+        config.add_feature(fea)
+        
+        dview = config.get_default_view()
+        fea = dview.get_feature(fea.fqr)
+        self.assertEquals(fea.value, [])
+        
+        def check_data_elements(expected_data_object_values):
+            actual = []
+            for d in config._traverse(type=api.Data):
+                actual.append((d.fqr, d.value, d.empty))
+            expected = []
+            for fqr, val, empty in expected_data_object_values:
+                expected.append((fqr, val, empty))
+            self.assertEquals(actual, expected)
+        
+        fea.value = []
+        self.assertEquals(fea.value, [])
+        check_data_elements(
+            [('fooseq', None, False),])
+        
+        fea.value = [[()]]
+        self.assertEquals(fea.value, [[()]])
+        check_data_elements(
+            [('fooseq', None, False),
+             ('fooseq.msel', None, True),])
+        
+        fea.value = [[('x',)]]
+        self.assertEquals(fea.value, [[('x',)]])
+        check_data_elements(
+            [('fooseq', None, False),
+             ('fooseq.msel', 'x', False),])
+        
+        fea.value = [[('x',)], [('y',)]]
+        self.assertEquals(fea.value, [[('x',)], [('y',)]])
+        check_data_elements(
+            [('fooseq', None, False),
+             ('fooseq.msel', 'x', False),
+             ('fooseq', None, False),
+             ('fooseq.msel', 'y', False),])
+        
+        fea.value = [[('x', 'y')],
+                     [('a', 'b', 'c')],
+                     [()],
+                     [('d', 'e', 'f')]]
+        self.assertEquals(fea.value, [[('x', 'y')],
+                                      [('a', 'b', 'c')],
+                                      [()],
+                                      [('d', 'e', 'f')]])
+        check_data_elements(
+            [('fooseq', None, False),
+             ('fooseq.msel', 'x', False),
+             ('fooseq.msel', 'y', False),
+             ('fooseq', None, False),
+             ('fooseq.msel', 'a', False),
+             ('fooseq.msel', 'b', False),
+             ('fooseq.msel', 'c', False),
+             ('fooseq', None, False),
+             ('fooseq.msel', None, True),
+             ('fooseq', None, False),
+             ('fooseq.msel', 'd', False),
+             ('fooseq.msel', 'e', False),
+             ('fooseq.msel', 'f', False),])
+    
+    def test_sequence_with_multiselection_get_value(self):
+        config = api.Configuration('foo.confml')
+        fea = model.ConfmlSequenceSetting("fooseq")
+        fea.add_feature(model.ConfmlMultiSelectionSetting("msel"))
+        config.add_feature(fea)
+        
+        seqdata1 = api.Data(ref='fooseq')
+        seqdata1._add([api.Data(ref='msel', value='x'),
+                       api.Data(ref='msel', value='y')])
+        seqdata2 = api.Data(ref='fooseq')
+        seqdata2._add([api.Data(ref='msel', empty=True)])
+        seqdata3 = api.Data(ref='fooseq')
+        seqdata3._add([api.Data(ref='msel', value='a'),
+                       api.Data(ref='msel', value='b'),
+                       api.Data(ref='msel', value='c')])
+        config.add_data([seqdata1, seqdata2, seqdata3])
+        
+        dview = config.get_default_view()
+        fea = dview.get_feature(fea.fqr)
+        self.assertEquals(fea.value, [[('x', 'y')], [()], [('a', 'b', 'c')]])
+    
+    def test_simple_name_id_mapping(self):
+        config = api.Configuration('foo.confml')
+        seq = model.ConfmlSequenceSetting('seq', mapKey='strsub', mapValue='strsub')
+        seq.add_feature(model.ConfmlStringSetting('strsub'))
+        seq.add_feature(model.ConfmlIntSetting('intsub'))
+        seq.add_feature(model.ConfmlRealSetting('realsub'))
+        seq.add_feature(model.ConfmlBooleanSetting('boolsub'))
+        config.add_feature(seq)
+        config.add_feature(api.Feature('target'))
+        
+        config.add_data(api.Data(fqr='seq.strsub', value='foo'))
+        config.add_data(api.Data(fqr='seq.intsub', value='123'))
+        config.add_data(api.Data(fqr='seq.realsub', value='1.5'))
+        config.add_data(api.Data(fqr='seq.boolsub', value='true'))
+        config.add_data(api.Data(fqr='target', map="seq[@key='foo']"))
+        
+        fea = config.get_default_view().get_feature('target')
+        self.assertEquals(fea.value, 'foo')
+        self.assertEquals(fea.get_original_value(), 'foo')
+        
+        seq.mapValue = 'intsub'
+        self.assertEquals(fea.value, 123)
+        self.assertEquals(fea.get_original_value(), '123')
+        
+        seq.mapValue = 'realsub'
+        self.assertEquals(fea.value, 1.5)
+        self.assertEquals(fea.get_original_value(), '1.5')
+        
+        seq.mapValue = 'boolsub'
+        self.assertEquals(fea.value, True)
+        self.assertEquals(fea.get_original_value(), 'true')
+    
+    def test_simple_name_id_mapping_with_multiselection(self):
+        config = api.Configuration('foo.confml')
+        seq = model.ConfmlSequenceSetting('seq', mapKey='strsub', mapValue='intsub')
+        seq.add_feature(model.ConfmlStringSetting('strsub'))
+        seq.add_feature(model.ConfmlIntSetting('intsub'))
+        config.add_feature(seq)
+        config.add_feature(model.ConfmlMultiSelectionSetting('target'))
+        
+        d = api.Data(fqr='seq')
+        d.add(api.Data(ref='strsub', value='foo'))
+        d.add(api.Data(ref='intsub', value='123'))
+        config.add_data(d, api.container.APPEND)
+        
+        d = api.Data(fqr='seq')
+        d.add(api.Data(ref='strsub', value='bar'))
+        d.add(api.Data(ref='intsub', value='321'))
+        config.add_data(d, api.container.APPEND)
+        
+        d = api.Data(fqr='seq')
+        d.add(api.Data(ref='strsub', value='baz'))
+        d.add(api.Data(ref='intsub', value='456'))
+        config.add_data(d, api.container.APPEND)
+        
+        config.add_data([api.Data(fqr='target', map="seq[@key='bar']"),
+                         api.Data(ref='target', map="seq[@key='baz']"),
+                         api.Data(ref='target', map="seq[@key='foo']")])
+        
+        fea = config.get_default_view().get_feature('target')
+        self.assertEquals(fea.value, (321, 456, 123))
+        self.assertEquals(fea.get_original_value(), ('321', '456', '123'))
+    
+    def test_simple_name_id_mapping_with_file_and_folder_setting(self):
+        def _run_test(subsetting_class):
+            config = api.Configuration('foo.confml')
+            seq = model.ConfmlSequenceSetting('seq')
+            seq.add_feature(subsetting_class('filefoldersub'))
+            config.add_feature(seq)
+            config.add_feature(model.ConfmlSelectionSetting('target'))
+            
+            def _add_seq_data(local_path, target_path):
+                d = api.Data(fqr='seq')
+                subd = api.Data(ref='filefoldersub')
+                subd.add(api.Data(ref='localPath', value=local_path))
+                subd.add(api.Data(ref='targetPath', value=target_path))
+                d.add(subd)
+                config.add_data(d, api.container.APPEND)
+            _add_seq_data('local/path/1', 'target/path/1')
+            _add_seq_data('local/path/2', 'target/path/2')
+            _add_seq_data('local/path/3', 'target/path/3')
+            target_data = api.Data(fqr='target')
+            config.add_data(target_data)
+
+            fea = config.get_default_view().get_feature('target')
+    
+            seq.mapKey = 'filefoldersub'
+            seq.mapValue = 'filefoldersub'
+            target_data.map = "seq[@key='local/path/1']"
+            self.assertEquals(fea.value, 'local/path/1')
+            
+            seq.mapKey = 'filefoldersub/localPath'
+            seq.mapValue = 'filefoldersub/localPath'
+            target_data.map = "seq[@key='local/path/1']"
+            self.assertEquals(fea.value, 'local/path/1')
+            
+            seq.mapKey = 'filefoldersub/targetPath'
+            seq.mapValue = 'filefoldersub/targetPath'
+            target_data.map = "seq[@key='target/path/2']"
+            self.assertEquals(fea.value, 'target/path/2')
+            
+            seq.mapKey = 'filefoldersub/localPath'
+            seq.mapValue = 'filefoldersub/targetPath'
+            target_data.map = "seq[@key='local/path/3']"
+            self.assertEquals(fea.value, 'target/path/3')
+        
+        _run_test(subsetting_class=model.ConfmlFileSetting)
+        _run_test(subsetting_class=model.ConfmlFolderSetting)
+    
+    def test_simple_name_id_mapping_override_map_value_in_option(self):
+        config = api.Configuration('foo.confml')
+        fea = model.ConfmlFeature('fea')
+        config.add_feature(fea)
+        seq = model.ConfmlSequenceSetting('seq', mapKey='strsub', mapValue='strsub')
+        seq.add_feature(model.ConfmlStringSetting('strsub'))
+        seq.add_feature(model.ConfmlIntSetting('intsub'))
+        fea.add_feature(seq)
+        target = api.Feature('target')
+        target.add_option(api.Option(None, None, map='fea/seq', map_value='intsub'))
+        fea.add_feature(target)
+        
+        config.add_data(api.Data(fqr='fea.seq.strsub', value='foo'))
+        config.add_data(api.Data(fqr='fea.seq.intsub', value='123'))
+        config.add_data(api.Data(fqr='fea.target', map="fea/seq[@key='foo']"))
+        
+        fea = config.get_default_view().get_feature('fea.target')
+        self.assertEquals(fea.value, 123)
+        self.assertEquals(fea.get_original_value(), '123')
+    
+    def _assert_raises(self, exception_class, func, *args, **kwargs):
+        try:
+            func(*args, **kwargs)
+            self.fail("No exception raised")
+        except exception_class, e:
+            return e
+    
+    def test_name_id_mapping_errors(self):
+        config = api.Configuration('foo.confml')
+        seq = model.ConfmlSequenceSetting('seq')
+        seq.add_feature(model.ConfmlStringSetting('strsub'))
+        seq.add_feature(model.ConfmlIntSetting('intsub'))
+        config.add_feature(seq)
+        
+        config.add_feature(model.ConfmlIntSetting('foosetting'), 'foofea')
+        
+        target = api.Feature('target')
+        target_option = api.Option(None, None, map='seq')
+        target.add_option(target_option)
+        config.add_feature(target)
+        
+        config.add_data(api.Data(fqr='seq.strsub', value='foo'))
+        config.add_data(api.Data(fqr='seq.intsub', value='123'))
+        target_data = api.Data(fqr='target', map="seq[@key='123']")
+        config.add_data(target_data)
+        
+        fea = config.get_default_view().get_feature('target')
+        
+        e = self._assert_raises(exceptions.NameIdMappingError, fea.get_value)
+        self.assertEquals(str(e), "Source sequence 'seq' must have both mapKey and mapValue specified")
+        
+        seq.mapKey = 'strsub'
+        e = self._assert_raises(exceptions.NameIdMappingError, fea.get_value)
+        self.assertEquals(str(e), "Source sequence 'seq' must have both mapKey and mapValue specified")
+        
+        seq.mapKey = None
+        seq.mapValue = 'strsub'
+        e = self._assert_raises(exceptions.NameIdMappingError, fea.get_value)
+        self.assertEquals(str(e), "Source sequence 'seq' must have both mapKey and mapValue specified")
+        
+        seq.mapKey = 'intsub'
+        seq.mapValue = 'strsub'
+        
+        target_data.map = "foobar"
+        e = self._assert_raises(exceptions.NameIdMappingError, fea.get_value)
+        self.assertEquals(str(e), "Malformed mapping expression: foobar")
+        
+        target_data.map = "foo/bar[key='321']"
+        e = self._assert_raises(exceptions.NameIdMappingError, fea.get_value)
+        self.assertEquals(str(e), "Malformed mapping expression: foo/bar[key='321']")
+        
+        target_data.map = "foo/bar[@key='321'"
+        e = self._assert_raises(exceptions.NameIdMappingError, fea.get_value)
+        self.assertEquals(str(e), "Malformed mapping expression: foo/bar[@key='321'")
+        
+        target_data.map = "foo/nonexistent[@key='321']"
+        e = self._assert_raises(exceptions.NameIdMappingError, fea.get_value)
+        self.assertEquals(str(e), "Mapping source sequence 'foo.nonexistent' does not exist")
+        
+        target_data.map = "foofea/foosetting[@key='321']"
+        e = self._assert_raises(exceptions.NameIdMappingError, fea.get_value)
+        self.assertEquals(str(e), "Mapping source setting 'foofea.foosetting' is not a sequence setting")
+        
+        target_data.map = "seq[@key='321']"
+        e = self._assert_raises(exceptions.NameIdMappingError, fea.get_value)
+        self.assertEquals(str(e), "No item-setting in source sequence 'seq' matches key '321'")
+        
+        seq.mapKey = 'foo'
+        target_data.map = "seq[@key='321']"
+        e = self._assert_raises(exceptions.NameIdMappingError, fea.get_value)
+        self.assertEquals(str(e), "Invalid mapKey in source sequence 'seq': no sub-setting with ref 'foo'")
+        
+        seq.mapKey = 'intsub'
+        seq.mapValue = 'foo'
+        target_data.map = "seq[@key='321']"
+        e = self._assert_raises(exceptions.NameIdMappingError, fea.get_value)
+        self.assertEquals(str(e), "Invalid mapValue in source sequence 'seq': no sub-setting with ref 'foo'")
+        
+        seq.mapValue = 'strsub'
+        target_data.map = "seq[@key='123']"
+        target_option.map_value = 'foobar'
+        e = self._assert_raises(exceptions.NameIdMappingError, fea.get_value)
+        self.assertEquals(str(e), "Invalid mapValue override in option: sub-setting 'foobar' does not exist under source sequence 'seq'")
+        
+        # Test successful mapping for good measure
+        seq.mapKey = 'intsub'
+        seq.mapValue = 'strsub'
+        target_data.map = "seq[@key='123']"
+        target_option.map_value = 'intsub'
+        self.assertEquals(fea.get_value(), 123)
+        self.assertEquals(fea.get_original_value(), '123')
 
 class TestConfmlFile(unittest.TestCase):
     def test_create_localpath_elem(self):
@@ -511,6 +1194,8 @@
         self.assertEquals(elem.list_features(), ['localPath','targetPath'])
         self.assertEquals(elem.get_feature('localPath').fqr, 'test.localPath')
         self.assertEquals(elem.get_feature('targetPath').fqr, 'test.targetPath')
+        self.assertEquals(elem.get_feature('localPath').name, 'localPath')
+        self.assertEquals(elem.get_feature('targetPath').name, 'targetPath')
 
     def test_create_file_elem_and_set_value(self):
         config = api.Configuration('test.confml')
@@ -529,6 +1214,31 @@
         elem2 = elem1._clone(recursion=True)
         
 
+    def test_create_file_elem_to_a_sequence(self):
+        config = model.ConfmlConfiguration('foo.confml')
+        seq = model.ConfmlSequenceSetting('foo')
+        elem = model.ConfmlFileSetting('test')
+        seq.add_feature(elem)
+        config.add_feature(seq)
+        seq.value = [[['local file', 'targetfile']],
+                     [['local file2', 'targetfile2']]]
+        
+        self.assertEquals(seq.test.localPath.get_value(), ['local file',
+                                                           'local file2'])
+        
+    def test_create_folder_elem_to_a_sequence(self):
+        config = model.ConfmlConfiguration('foo.confml')
+        seq = model.ConfmlSequenceSetting('foo')
+        elem = model.ConfmlFolderSetting('test')
+        seq.add_feature(elem)
+        config.add_feature(seq)
+        seq.value = [[['local file', 'targetfile']],
+                     [['local file2', 'targetfile2']]]
+        
+        self.assertEquals(seq.test.localPath.get_value(), ['local file',
+                                                           'local file2'])
+
+        
 class TestConfmlIcon(unittest.TestCase):
     def test_create_icon(self):
         icon = model.ConfmlIcon("test/foo/bar.jpg")
@@ -545,24 +1255,72 @@
 class TestLengths(unittest.TestCase):
     def test_create_maxLength(self):
         max = model.ConfmlMaxLength('100')
-        self.assertEquals(max.value, '100')
-
+        self.assertEquals(max.value, 100)
+        max.value = 10
+        self.assertEquals(max.value, 10)
+        max.value = '1000'
+        self.assertEquals(max.value, 1000)
+        
     def test_create_minLength(self):
         min = model.ConfmlMinLength('100')
-        self.assertEquals(min.value, '100')
+        self.assertEquals(min.value, 100)
+        min.value = 10
+        self.assertEquals(min.value, 10)
+        min.value = '1000'
+        self.assertEquals(min.value, 1000)
+
+    def test_create_length(self):
+        len = model.ConfmlLength('100')
+        self.assertEquals(len.value, 100)
+        len.value = 10
+        self.assertEquals(len.value, 10)
+        len.value = '1000'
+        self.assertEquals(len.value, 1000)
 
 class TestConfmlFacets(unittest.TestCase):
+    def test_numeric_base_classs(self):
+        numeric = model.ConfmlNumericValue()
+        numeric.value = 3
+        self.assertEquals(numeric.value, 3)
+        numeric.value = 0.3
+        self.assertEquals(numeric.value, 0.3)
+        numeric.value = '22'
+        self.assertEquals(numeric.value, 22)
+        numeric.value = '0.1'
+        self.assertEquals(numeric.value, 0.1)
+        try:
+            numeric.value = 'foo'
+            self.fail("setting string to float property succeeded!")
+        except ValueError:
+            pass
+
     def test_create_inclusive(self):
         min = model.ConfmlMinInclusive('-10')
         max = model.ConfmlMaxInclusive('10')
-        self.assertEquals(min.value, '-10')
-        self.assertEquals(max.value, '10')
+        self.assertEquals(min.value, -10)
+        self.assertEquals(max.value, 10)
+        min.value = 10
+        self.assertEquals(min.value, 10)
+        min.value = '1000'
+        self.assertEquals(min.value, 1000)
+        max.value = 10
+        self.assertEquals(max.value, 10)
+        max.value = '1000'
+        self.assertEquals(max.value, 1000)
 
     def test_create_exclusive(self):
         min = model.ConfmlMinExclusive('0')
         max = model.ConfmlMaxExclusive("9")
-        self.assertEquals(min.value, '0')
-        self.assertEquals(max.value, '9')
+        self.assertEquals(min.value, 0)
+        self.assertEquals(max.value, 9)
+        max.value = 10
+        self.assertEquals(max.value, 10)
+        max.value = '1000'
+        self.assertEquals(max.value, 1000)
+        min.value = 10
+        self.assertEquals(min.value, 10)
+        min.value = '1000'
+        self.assertEquals(min.value, 1000)
 
     def test_create_pattern(self):
         pattern = model.ConfmlPattern("[a-zA-Z]")
@@ -570,7 +1328,11 @@
 
     def test_create_totalDigits(self):
         digits = model.ConfmlTotalDigits("3")
-        self.assertEquals(digits.value, '3')
+        self.assertEquals(digits.value, 3)
+        digits.value = 10
+        self.assertEquals(digits.value, 10)
+        digits.value = '1000'
+        self.assertEquals(digits.value, 1000)
 
 class TestConfmlConfiguration(unittest.TestCase):
     def test_create_configuration(self):
@@ -581,14 +1343,24 @@
         self.assertEquals(config.ref, 'test__foo__bar_jpg')
         self.assertEquals(config.path, 'test/foo/bar.jpg')
 
-#    def test_configuration_access_meta(self):
-#        config = model.ConfmlConfiguration("test/foo/bar.jpg", meta={'test':'foo','bar':' hd dd'})
-#        self.assertEquals(config.meta.dict, {'test':'foo','bar':' hd dd'})
-#        self.assertEquals(config.meta['test'],'foo')
-#        config.meta = {'test':'123'}
-#        self.assertEquals(config.meta['test'],'123')
-#        del config.meta
-#        self.assertEquals(config.meta, None)
+    def test_create_configuration_and_features(self):
+        conf = model.ConfmlConfiguration("simple.confml")
+        fea = conf.create_feature("test")
+        self.assertTrue(isinstance(fea, model.ConfmlFeature))
+        self.assertEquals(conf.get_feature('test'), fea)
+        fea = conf.create_feature("test1", name="test name")
+        self.assertEquals(conf.get_feature('test1').name, 'test name')
+        subfea = fea.create_feature("subfea", name="subfea name")
+        self.assertTrue(isinstance(subfea, model.ConfmlSetting))
+        self.assertEquals(conf.list_all_features(), ['test','test1','test1.subfea'])
+
+    def test_configuration_get_default_view(self):
+        config = model.ConfmlConfiguration("test/foo/bar.jpg")
+        config.add_feature(model.ConfmlFeature("test"))
+        view = config.create_view("testview")
+        group = view.create_group("group1")
+        group.create_featurelink("test")
+        self.assertEquals(config.list_all_features(), ['test'])
         
     def test_configuration_access_desc(self):
         config = model.ConfmlConfiguration("test/foo/bar.jpg", desc="testing description")
@@ -598,14 +1370,107 @@
         del config.desc
         self.assertEquals(config.desc, None)
 
-class TestConfmlProperty(unittest.TestCase):
-    def test_create_property(self):
-        property = model.ConfmlProperty(name='test',value='foo', unit='kB')
-        self.assertEquals(property.name, 'test')
-        self.assertEquals(property.value, 'foo')
-        self.assertEquals(property.unit, 'kB')
-        property.name = 'testnew'
-        property.value = 'foo faa'
-        self.assertEquals(property.name, 'testnew')
-        self.assertEquals(property.value, 'foo faa')
-        
\ No newline at end of file
+    def test_use_create_configuration(self):
+        config = model.ConfmlConfiguration("test/foo/bar.jpg")
+        subconfig = config.create_configuration("sub/jee.confml")
+        self.assertEquals(subconfig.get_full_path(),'test/foo/sub/jee.confml')
+        self.assertTrue(isinstance(subconfig,model.ConfmlConfiguration))
+
+        
+class TestConfmlView(unittest.TestCase):
+    def test_create_view(self):
+        view = model.ConfmlView("test", id="test")
+        self.assertTrue(view)
+        self.assertEquals(view.get_ref(),'test')
+        self.assertEquals(view.id,"test")
+
+    def test_create_view_with_create_view(self):
+        config = model.ConfmlConfiguration("test")
+        view = config.create_view("test")
+        group = view.create_group("group1")
+        fl = group.create_featurelink("intset1")
+        self.assertTrue(isinstance(view, model.ConfmlView))
+        self.assertTrue(isinstance(group, model.ConfmlGroup))
+        self.assertTrue(isinstance(fl, model.ConfmlFeatureLink))
+
+    def test_create_confml_featurelink(self):
+        fealink = model.ConfmlFeatureLink("test")
+        self.assertTrue(fealink)
+        self.assertEquals(fealink.get_ref(),'link_test')
+
+    def test_create_confml_featurelink_with_overrides(self):
+        fealink = model.ConfmlFeatureLink("test")
+        fealink.desc = "test desc"
+        self.assertEquals(fealink.desc,'test desc')
+        self.assertEquals(fealink._has('_desc'),True)
+        self.assertEquals(fealink.get_attributes(),{'properties': {},'options': {}, 'desc' : 'test desc'})
+
+    def test_create_confml_featurelink_with_option_overrides(self):
+        fealink = model.ConfmlFeatureLink("test")
+        fealink.add(api.Option('opt2', '2'))
+        self.assertEquals(fealink.options['2'].name,'opt2')
+
+    def test_create_view_with_groups(self):
+        view = model.ConfmlView("test")
+        view.create_group("group1")
+        view.create_group("group2")
+        self.assertEquals(view.list_groups(),['group1','group2'])
+
+    def test_create_configuration_with_featurelinks(self):
+        config = model.ConfmlConfiguration("test")
+        config.add_feature(model.ConfmlFeature("fea1", name="Feature 1"))
+        intset1 = model.ConfmlIntSetting("intset1", name="Setting 1")
+        intset1.desc = "int setting desc"
+        config.add_feature(intset1, "fea1")
+
+        view = config.create_view("test")
+        group = view.create_group("group1")
+        fl = group.create_featurelink("intset1")
+        self.assertTrue(isinstance(fl, model.ConfmlFeatureLink))
+        self.assertTrue(len(config.get_default_view().get_features('**')), 2)
+        
+        
+    def test_create_configuration_with_view_and_featurelink_overrides(self):
+        config = model.ConfmlConfiguration("test")
+        config.add_feature(model.ConfmlFeature("fea1", name="Feature 1"))
+        intset1 = model.ConfmlIntSetting("intset1", name="Setting 1")
+        intset1.desc = "int setting desc"
+        config.add_feature(intset1, "fea1")
+        
+        view = config.create_view("test")
+        view.create_group("group1")
+        fl = model.ConfmlFeatureLink("fea1.intset1", name="override name")
+        fl.desc = "override desc"
+        fl.minLength = 2
+        fl.maxLength = 10
+        fl.minOccurs = 2
+        fl.maxOccurs = 10
+        
+        fl.pattern = '^.*@.*$'
+        fl.totalDigits = 10
+        fl.minInclusive = 0
+        fl.maxInclusive = 10
+        fl.minExclusive = 0
+        fl.maxExclusive = 10
+        
+        fl.add(api.Option('opt1', '1'))
+        
+        view.get_group('group1').add(fl)
+        view.populate()
+        self.assertEquals(view.list_all_features(),['group1.proxy_fea1_intset1'])
+        self.assertEquals(view.get_feature('group1.proxy_fea1_intset1').desc, "override desc")
+        self.assertEquals(view.get_feature('group1.proxy_fea1_intset1').name, "override name")
+        self.assertEquals(view.get_feature('group1.proxy_fea1_intset1').minLength, 2)
+        self.assertEquals(view.get_feature('group1.proxy_fea1_intset1').maxLength, 10)
+        self.assertEquals(view.get_feature('group1.proxy_fea1_intset1').minOccurs, 2)
+        self.assertEquals(view.get_feature('group1.proxy_fea1_intset1').maxOccurs, 10)
+        self.assertEquals(view.get_feature('group1.proxy_fea1_intset1').pattern, '^.*@.*$')
+        self.assertEquals(view.get_feature('group1.proxy_fea1_intset1').totalDigits, 10)
+        self.assertEquals(view.get_feature('group1.proxy_fea1_intset1').minInclusive, 0)
+        self.assertEquals(view.get_feature('group1.proxy_fea1_intset1').maxInclusive, 10)
+        self.assertEquals(view.get_feature('group1.proxy_fea1_intset1').minExclusive, 0)
+        self.assertEquals(view.get_feature('group1.proxy_fea1_intset1').maxExclusive, 10)
+        self.assertEquals(view.get_feature('group1.proxy_fea1_intset1').options['1'].name,'opt1')
+        
+if __name__ == '__main__':
+    unittest.main()
--- a/configurationengine/source/cone/confml/tests/unittest_persistentconfml.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/confml/tests/unittest_persistentconfml.py	Tue Aug 10 14:29:28 2010 +0300
@@ -19,28 +19,18 @@
 """
 
 import unittest
-import string
-import sys
 import os
 import shutil
-import __init__
-try:
-    from cElementTree import ElementTree
-except ImportError:
-    try:    
-        from elementtree import ElementTree
-    except ImportError:
-        try:
-            from xml.etree import cElementTree as ElementTree
-        except ImportError:
-            from xml.etree import ElementTree
+
 
-from cone.public import api, exceptions, persistence
+from cone.public import api, persistence, utils
 from cone.storage import filestorage
-from cone.confml import persistentconfml, model
+from cone.confml import persistentconfml, model, confmltree
 from testautomation.base_testcase import BaseTestCase
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
 
+ElementTree = utils.etree
+
 testdata  = os.path.join(ROOT_PATH,'data')
 
 simplerootxml = \
@@ -65,7 +55,7 @@
 
 
 morestuff='''<?xml version="1.0" encoding="UTF-8"?>
-<configuration xmlns="http://www.s60.com/xml/confml/1" xmlns:xi="http://www.w3.org/2001/xinclude" name="foobar" version="1">
+<configuration id="conf_id" xmlns="http://www.s60.com/xml/confml/1" xmlns:xi="http://www.w3.org/2001/xinclude" name="foobar" version="1">
   <meta xmlns:cv="http://www.nokia.com/xml/cpf-id/1">
     <cv:configuration-property name="coreplat_name" value="abc_123" />
     <cv:configuration-property name="product_name" value="qwerty" />
@@ -201,15 +191,239 @@
   </data>
   <confml:view id="imakerimage" name="Image creation">
     <confml:desc>Image creation related settings</confml:desc>
-    <confml:group name="Imageproperties">
+    <confml:group name="Imageproperties / test">
       <confml:desc>Sample Description</confml:desc>
-      <confml:setting ref="imakerapi/*"/>
+      <confml:setting ref="imakerapi/imagetype"/>
+      <confml:setting ref="imakerapi/rofs3version"/>
+      <confml:setting ref="imakerapi/productname"/>
+      <confml:setting ref="imakerapi/outputLocation"/>
       <confml:setting ref="imaker/*"/>
     </confml:group>
   </confml:view>
 </confml:configuration>
 '''
 
+overrideview = \
+'''<?xml version="1.0" encoding="UTF-8"?>
+<configuration  xmlns="http://www.s60.com/xml/confml/2" schemaLocation="http://www.s60.com/xml/confml/1 http://www.s60.com/xml/confml/1#//confml2">
+  <feature ref="imakerapi" name="iMaker API">
+    <setting ref="imagetype" name="IMAGE_TYPE" type="selection">
+      <option name="rnd" value="0"/>
+      <option name="subcon" value="1"/>
+      <option name="prd" value="2"/>
+    </setting>
+    <setting ref="productname" name="PRODUCT_NAME" type="string"/>
+    <setting ref="outputLocation" name="OUTPUT_LOCATION" type="string"/>
+  </feature>
+  <data>
+    <imakerapi>
+      <imagetype>0</imagetype>
+      <productname>myProduct</productname>
+      <outputLocation>myProduct</outputLocation>
+    </imakerapi>
+  </data>
+  <view id="imakerimage" name="Image creation">
+    <desc>Image creation related settings</desc>
+    <group name="Imageproperties">
+      <desc>Sample Description</desc>
+      <setting ref="imakerapi/imagetype">
+          <option name="prd_renamed" value="2"/>
+      </setting>
+      <setting ref="imakerapi/productname" name="New Product Name">
+        <desc>test desc override</desc>
+        <minLength value="2" />
+      </setting>
+      <setting ref="imakerapi/outputLocation" minOccurs="2"/>
+    </group>
+  </view>
+</configuration>
+'''
+
+
+option_overrideview = \
+'''<?xml version="1.0" encoding="UTF-8"?>
+<configuration  xmlns="http://www.s60.com/xml/confml/2" schemaLocation="http://www.s60.com/xml/confml/1 http://www.s60.com/xml/confml/1#//confml2">
+  <feature ref="imakerapi" name="iMaker API">
+    <setting ref="imagetype" name="IMAGE_TYPE" type="selection">
+      <option name="rnd" value="0"/>
+      <option name="subcon" value="1"/>
+      <option name="prd" value="2"/>
+    </setting>
+    <setting ref="productname" name="PRODUCT_NAME" type="string"/>
+    <setting ref="outputLocation" name="OUTPUT_LOCATION" type="string"/>
+  </feature>
+  <data>
+    <imakerapi>
+      <imagetype>0</imagetype>
+      <productname>myProduct</productname>
+      <outputLocation>myProduct</outputLocation>
+    </imakerapi>
+  </data>
+  <view id="imakerimage" name="Image creation">
+    <desc>Image creation related settings</desc>
+    <group name="Imageproperties">
+      <desc>Sample Description</desc>
+      <setting ref="imakerapi/imagetype">
+          <option name="prd2" value="2"/>
+          <option name="newoption" value="5"/>
+      </setting>
+      <setting ref="imakerapi/productname" name="New Product Name">
+        <desc>test desc override</desc>
+        <minLength value="2" />
+      </setting>
+      <setting ref="imakerapi/outputLocation" minOccurs="2"/>
+    </group>
+  </view>
+</configuration>
+'''
+
+properties_overrideview = \
+'''<?xml version="1.0" encoding="UTF-8"?>
+<configuration  xmlns="http://www.s60.com/xml/confml/2" schemaLocation="http://www.s60.com/xml/confml/1 http://www.s60.com/xml/confml/1#//confml2">
+  <feature ref="imakerapi" name="iMaker API">
+    <setting ref="imagetype" name="IMAGE_TYPE" type="selection">
+      <option name="rnd" value="0"/>
+      <option name="subcon" value="1"/>
+      <option name="prd" value="2"/>
+      <property name="mime" value="image/svgt image/bmp"/>
+      
+    </setting>
+    <setting ref="productname" name="PRODUCT_NAME" type="string"/>
+    <setting ref="outputLocation" name="OUTPUT_LOCATION" type="string"/>
+  </feature>
+  <data>
+    <imakerapi>
+      <imagetype>0</imagetype>
+      <productname>myProduct</productname>
+      <outputLocation>myProduct</outputLocation>
+    </imakerapi>
+  </data>
+  <view id="imakerimage" name="Image creation">
+    <desc>Image creation related settings</desc>
+    <group name="Imageproperties">
+      <desc>Sample Description</desc>
+      <setting ref="imakerapi/imagetype">
+      <property name="mime" value="image/svgt image/jpg"/>
+      <property name="mime2" value="image/svgt image/bmp"/>
+      </setting>
+      <setting ref="imakerapi/productname" name="New Product Name">
+        <desc>test desc override</desc>
+        <minLength value="2" />
+      </setting>
+      <setting ref="imakerapi/outputLocation" minOccurs="2"/>
+    </group>
+  </view>
+</configuration>
+'''
+
+selectionsetting = \
+'''<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/2" name="Test features for testing name-ID mappings"><feature ref="CTD_APs" name="GPRS Access Points" ><desc>GPRS connection method (CM) definitions</desc>
+        <setting ref="AP"
+                name="GPRS"
+                type="sequence"
+                minOccurs="0"
+                maxOccurs="99"
+                displayName="ConnectionName"
+                mapValue="DestinationNetwork"
+                mapKey="GPRS_AP_Name">
+            <setting ref="GPRS_AP_Name" name="GPRS Access Point Name" type="string">
+                <desc>The access point name for this GPRS connection</desc>
+            </setting>
+            <setting ref="ConnectionName" name="Connection Name" type="string">
+                <desc>The access point name that is visible to the user.</desc>
+            </setting>
+            <setting ref="DestinationNetwork" name="Destination Network" type="selection">
+                <desc>Select destination network for access point</desc>
+                <option name="Internet" value="1"/>
+                <option name="MMS" value="2"/>
+                <option name="Wap Services" value="3"/>
+            </setting>
+            <setting ref="NetworkType" name="Network type" type="selection">
+                <desc>Addressing that the network uses.</desc>
+                <option name="IPv4" value="IPv4"/>
+                <option name="IPv6" value="IPv6"/>
+            </setting>
+        </setting>
+    </feature>
+    <feature ref="TestApplication" name="Test internet application">
+        <setting ref="ConfirmFromUser" name="Confirm internet access" type="boolean">
+            <desc>Confirm the internet access from user?</desc>
+        </setting>
+        <setting ref="DefaultAP" name="Default access point" type="selection">
+            <option map="CTD_APs/AP"></option>
+        </setting>
+    </feature>
+    <data>
+        <CTD_APs>
+            <AP template="true">
+                <DestinationNetwork>Internet</DestinationNetwork>
+                <NetworkType>IPv4</NetworkType>
+            </AP>
+            <AP>
+                <GPRS_AP_Name>Operator 1</GPRS_AP_Name>
+                <ConnectionName>Operator Internet</ConnectionName>
+                <DestinationNetwork>Internet</DestinationNetwork>
+                <NetworkType>IPv4</NetworkType>
+            </AP>
+            <AP>
+                <GPRS_AP_Name>Test</GPRS_AP_Name>
+                <ConnectionName>Test Connection</ConnectionName>
+                <DestinationNetwork>Internet</DestinationNetwork>
+                <NetworkType>IPv4</NetworkType>
+            </AP>
+        </CTD_APs>
+        <TestApplication>
+            <ConfirmFromUser>true</ConfirmFromUser>
+            <DefaultAP map="CTD_APs/AP[@key='Operator 1']"></DefaultAP>
+        </TestApplication>
+    </data>
+</configuration>
+'''
+
+multiselection = \
+'''<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/2" name="Test features for testing name-ID mappings">
+  <feature ref="aFeature">
+    <setting type="sequence" ref="exampleSequence" mapKey="id" mapValue="someName">
+      <setting type="int" ref="id"/>
+      <setting type="string" ref="someName"/>
+      <setting type="string" ref="someData"/>
+    </setting>
+    <setting ref="selectionSetting" name="Selection Setting" type="selection">
+      <option map="aFeature/exampleSequence"/>
+    </setting>
+    <setting ref="multiselectionSetting" name="Multi-selection Setting" type="multiSelection">
+      <option name="default selection" value=""/>
+      <option map="aFeature/exampleSequence"/>
+    </setting>
+    <setting ref="multiselectionSettingOverride" name="Multi-selection Setting with options override" type="multiSelection">
+      <option map="aFeature/exampleSequence" displayName="someName" mapValue="someData"/>
+    </setting>
+  </feature>
+  <data>
+    <aFeature>
+    <exampleSequence>
+      <id>12</id>
+      <someName>foo</someName>
+      <someData>Real data is here!</someData>
+    </exampleSequence>
+    <exampleSequence>
+      <id>34</id>
+      <someName>bar</someName>
+      <someData>I am not FOO!</someData>
+    </exampleSequence>
+    <selectionSetting map="aFeature/exampleSequence[@key='12']"/>
+    <multiselectionSetting>0</multiselectionSetting>
+    <multiselectionSetting map="aFeature/exampleSequence[@key='12']"/>
+    <multiselectionSetting map="aFeature/exampleSequence[@key='34']"/>
+    <multiselectionSettingOverride map="aFeature/exampleSequence[@key='12']"/>
+    <multiselectionSettingOverride map="aFeature/exampleSequence[@key='34']"/>
+    </aFeature>
+  </data>
+</configuration>
+'''
+
 class TestModuleGetters(unittest.TestCase):
     def test_get_reader_for_configuration(self):
         confread = persistentconfml.get_reader_for_elem("configuration")
@@ -240,11 +454,16 @@
         elem = ElementTree.fromstring(dump)
         self.assertEquals(elem.get('name'),"test_confml")
 
-class TestConfigurationParser(unittest.TestCase):    
+class TestConfigurationParser(unittest.TestCase):
+    def tearDown(self):
+        if os.path.exists(os.path.join(ROOT_PATH,'temp')):
+            shutil.rmtree(os.path.join(ROOT_PATH,'temp'))
+    
     def test_load_simple(self):
         reader = persistentconfml.get_reader_for_elem("configuration")
         obj = reader.loads(ElementTree.fromstring(simplerootxml))
         self.assertEquals(obj.get_ref(),'simple')
+        self.assertEquals(obj.id,None)
         self.assertEquals(obj._list(),['platform__s60__confml__test_confml'])
 
     def test_load_new_include_confml(self):
@@ -263,6 +482,7 @@
     def test_load_morestuff(self):
         reader = persistentconfml.get_reader_for_elem("configuration")
         obj = reader.loads(ElementTree.fromstring(morestuff))
+        self.assertEquals(obj.id, "conf_id")
         self.assertEquals(obj._list(),['_meta','_desc','platform__s60__confml__root_confml', 'ncp11__confml__jallaa_confml', 'ncp11__prodX__confml__root_confml', 'regional__japan__confml__root_confml'])
         met = obj.meta
         self.assertEquals(obj.meta[2].value,'Variant1 creator')
@@ -311,8 +531,8 @@
         self.assertEquals(obj.get_feature('CVC_OperatorMenu.CVC_OperatorMenuIconFile.localPath').get_value(),'UI/Customer Menu/Cache')
 
     def test_create_features_with_rfs_data_and_dump_and_load(self):
-        conf = api.Configuration("foo/foo.confml")
-        conf.add_feature(api.Feature('feature1'))
+        conf = api.Configuration("foo/foo.confml", id="foo_conf")
+        conf.add_feature(api.Feature('feature1', id="feature1_id"))
         conf.add_feature(api.Feature('child1'),'feature1')
         conf.add_feature(api.Feature('child2'),'feature1')
         conf.add_feature(api.Feature('child3'),'feature1')
@@ -326,11 +546,59 @@
         
         dumped = persistentconfml.dumps(conf)
         conf2 = persistentconfml.loads(dumped)
+        self.assertEquals(conf2.id, "foo_conf")
         dview = conf2.get_default_view()
+        self.assertEquals(dview.get_feature('feature1').id, "feature1_id")
+        self.assertEquals(dview.get_feature('feature1.child1').id, None)
         self.assertEquals(dview.get_feature('feature1.child1').get_value(), None)
         self.assertEquals(dview.get_feature('feature1.child1').get_value('rfs'), 'true')
         self.assertEquals(dview.get_feature('feature1.child2').get_value('rfs'), 'false')
 
+    def test_create_confml_features_and_dump_and_load(self):
+        conf = model.ConfmlConfiguration("foo/foo.confml", id="foo_conf")
+        fea = conf.create_feature('feature1', id="feature1_id")
+        fea.add_feature(model.ConfmlBooleanSetting("boolset", id="bool", name="testname", desc="desriptions"))
+        fea.add_feature(model.ConfmlIntSetting("intset", id="int"))
+        fea.add_feature(model.ConfmlStringSetting("stringset", id="string"))
+        fea.add_feature(model.ConfmlSelectionSetting("selset", id="sel"))
+        fea.add_feature(model.ConfmlSequenceSetting("seqset", id="seq"))
+        fea.add_feature(model.ConfmlFileSetting("fileset", id="file", desc="testdesc"))
+
+        dumped = persistentconfml.dumps(conf)
+        conf2 = persistentconfml.loads(dumped)
+        self.assertEquals(conf2.id, "foo_conf")
+        dview = conf2.get_default_view()
+        self.assertEquals(dview.get_feature('feature1').id, "feature1_id")
+        self.assertEquals(dview.get_feature('feature1.boolset').id, "bool")
+        self.assertEquals(dview.get_feature('feature1.boolset').desc, "desriptions")
+        self.assertEquals(dview.get_feature('feature1.intset').id, "int")
+        self.assertEquals(dview.get_feature('feature1.stringset').id, "string")
+        self.assertEquals(dview.get_feature('feature1.selset').id, "sel")
+        self.assertEquals(dview.get_feature('feature1.seqset').id, "seq")
+        self.assertEquals(dview.get_feature('feature1.fileset').id, "file")
+        self.assertEquals(dview.get_feature('feature1.fileset').desc, "testdesc")
+
+    def test_create_confml_view_and_dump_and_load(self):
+        conf = model.ConfmlConfiguration("foo/view.confml", id="view_conf")
+        view = conf.create_view('view1')
+        group1 = view.create_group("group one", id="g1")
+        group2 = view.create_group("group two", id="g2")
+        group2.create_featurelink("test/foo", id="fea1", name="Jee", desc="testdesc", readOnly="true")
+
+        dumped = persistentconfml.dumps(conf)
+        conf2 = persistentconfml.loads(dumped)
+        self.assertEquals(conf2.id, "view_conf")
+        v1 = conf2.get_view('view1')
+        self.assertEquals(v1.name, "view1")
+        self.assertEquals(v1.id, None)
+        self.assertEquals(v1.list_groups(), ['group one', 'group two'])
+        self.assertEquals(v1.get_group('group one').id, "g1")
+        self.assertEquals(v1.get_group('group two').id, "g2")
+        self.assertEquals(v1.get_group('group two').get_featurelink("test/foo").id, "fea1")
+        self.assertEquals(v1.get_group('group two').get_featurelink("test/foo").name, "Jee")
+        self.assertEquals(v1.get_group('group two').get_featurelink("test/foo").desc, "testdesc")
+        self.assertEquals(v1.get_group('group two').get_featurelink("test/foo").readOnly, True)
+
     def test_load_actualconfml_test_rfs_settings(self):
         reader = persistentconfml.get_reader_for_elem("configuration")
         obj = reader.loads(ElementTree.fromstring(actualconfml))
@@ -364,8 +632,8 @@
         obj = reader.loads(etree)
         dview = obj.get_default_view()
         dnsfea = dview.get_feature('DNs.DN')
-        self.assertEquals(dnsfea.list_features(),['Name', 'DNId', 'Metadata', 'Protection', 'Hidden', 'HiddenAgent', 'Highlighted', 'Icon', 'EmbeddedDN', 'IAP', 'IAP2', 'IAP3', 'IAP4', 'IAP5', 'IAP6', 'IAP7', 'IAP8', 'IAP9', 'IAP10'])
-        self.assertEquals(dnsfea.get_template(),['User Defined', '0', 'No', 'No', 'No', '11', None, None, None, None, None, None, None, None, None, None, None, None, None])
+        self.assertEquals(dnsfea.list_features(),['Name', 'DNId', 'Metadata',     'Protection', 'Hidden', 'HiddenAgent', 'Highlighted', 'Icon', 'EmbeddedDN', 'IAP', 'IAP2', 'IAP3', 'IAP4', 'IAP5', 'IAP6', 'IAP7', 'IAP8', 'IAP9', 'IAP10'])
+        self.assertEquals(dnsfea.get_template(), [None,   None,   'User Defined', '0',          'No',     'No',          'No',          '11',   None,         None,  None,  None,    None,   None,   None,   None,    None,   None,   None])
         self.assertEquals(dnsfea.get_value(),
         [['Internet', '1', 'Internet', '2', 'No', 'No', 'Yes', '0', None, None, None, None, None, None, None, None, None, None, None],
          ['MMS', '2', 'MMS', '2', 'No', 'Yes', 'No', '2', None, None, None, None, None, None, None, None, None, None, None], 
@@ -389,9 +657,8 @@
         config = p.get_configuration('multiselection.confml')
         dview = config.get_default_view()
         multisel1 = dview.get_feature('MultiSelections.MultiSel1')
-        self.assertEquals(multisel1.value,["first selection","second selection"])
-        self.assertEquals(multisel1.get_data_cast(multisel1.get_value()),["first selection","second selection"])
-        self.assertEquals(multisel1.get_value(),["first selection","second selection"])
+        self.assertEquals(multisel1.value,("first selection","second selection"))
+        self.assertEquals(multisel1.get_value(),("first selection","second selection"))
         self.assertEquals(multisel1.get_data().get_value(),'"first selection" "second selection"')
         
         
@@ -401,20 +668,20 @@
         config = p.get_configuration('multiselection.confml')
         dview = config.get_default_view()
         multisel1 = dview.get_feature('uda_selection.selectedfiles')
-        self.assertEquals(multisel1.get_value(),None)
+        self.assertEquals(multisel1.get_value(), ())
         self.assertEquals(multisel1.get_data().get_value(),None)
         
         
         
     def test_add_sequence_data_to_separate_confml(self):
-        prj = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'data'),"w"))
+        prj = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'temp'),"w"))
         config = prj.create_configuration('test2.confml')
         seqconfig = config.create_configuration('sequence.confml')
         config.create_configuration('testdata.confml')
         seqconfig.add_feature(api.FeatureSequence('feature1'))
-        seqconfig.add_feature(api.Feature('child1'),'feature1')
-        seqconfig.add_feature(api.Feature('child2'),'feature1')
-        seqconfig.add_feature(api.Feature('child3'),'feature1')
+        seqconfig.add_feature(api.Feature('child1', name="child1"),'feature1')
+        seqconfig.add_feature(api.Feature('child2', name="child2"),'feature1')
+        seqconfig.add_feature(api.Feature('child3', name="child3"),'feature1')
         dview = config.get_default_view()
         self.assertEquals(dview.get_feature('feature1').get_type(),'sequence')
         dview.get_feature('feature1').set_template(['c1','c2','c3'])
@@ -426,7 +693,7 @@
         dview.get_feature('feature1').get_data()[1].set_value(['row 2 updated', 'foo', '56'])
         config.save()
         prj.close()
-        prj = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'data')))
+        prj = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'temp')))
         config = prj.get_configuration('test2.confml')
         dview = config.get_default_view()
         self.assertEquals(dview.get_feature('feature1').get_template(),['c1','c2','c3'])
@@ -440,14 +707,14 @@
         
         
     def test_add_sequence_data_to_separate_confml_with_append_policy(self):
-        prj = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'data'),"w"))
+        prj = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'temp'),"w"))
         config = prj.create_configuration('test1.confml')
         seqconfig = config.create_configuration('sequence.confml')
         config.create_configuration('testdata.confml')
         seqconfig.add_feature(api.FeatureSequence('feature1'))
-        seqconfig.add_feature(api.Feature('child1'),'feature1')
-        seqconfig.add_feature(api.Feature('child2'),'feature1')
-        seqconfig.add_feature(api.Feature('child3'),'feature1')
+        seqconfig.add_feature(api.Feature('child1', name="child1"),'feature1')
+        seqconfig.add_feature(api.Feature('child2', name="child2"),'feature1')
+        seqconfig.add_feature(api.Feature('child3', name="child3"),'feature1')
         dview = config.get_default_view()
         self.assertEquals(dview.get_feature('feature1').get_type(),'sequence')
         dview.get_feature('feature1').set_template(['c1','c2','c3'])
@@ -459,7 +726,7 @@
         dview.get_feature('feature1').get_data()[1].set_value(['row 2 updated', 'foo', '56'])
         config.save()
         prj.close()
-        prj = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'data')))
+        prj = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'temp')))
         config = prj.get_configuration('test1.confml')
         dview = config.get_default_view()
         self.assertEquals(dview.get_feature('feature1').get_template(),['c1','c2','c3'])
@@ -475,23 +742,75 @@
         reader = persistentconfml.get_reader_for_elem("configuration")
         etree = ElementTree.fromstring(simpleview)
         obj = reader.loads(etree)
-        self.assertEquals(obj.get_name(), 'unknown')
+        self.assertEquals(obj.get_name(), None)
         self.assertEquals(obj.list_views(), ['Image creation'])
         self.assertEquals(obj.get_view('Image creation').get_name(),'Image creation')
         self.assertEquals(obj.get_view('Image creation').desc,'Image creation related settings')
         self.assertEquals(obj.get_view('Image creation').list_features(),[])
-        self.assertEquals(obj.get_view('Image creation').list_groups(),['Imageproperties'])
-        self.assertEquals(obj.get_view('Image creation').list_all_features(),['Imageproperties.imagetype', 
-                                                                           'Imageproperties.rofs3version', 
-                                                                           'Imageproperties.productname', 
-                                                                           'Imageproperties.outputLocation', 
-                                                                           'Imageproperties.imagetarget'])
-        self.assertEquals(obj.get_view('Image creation').get_feature('Imageproperties.imagetype').get_value(), '0') 
-        self.assertEquals(obj.get_view('Image creation').get_feature('Imageproperties.rofs3version').get_value(), 'V .50.2009.04.0113 RND') 
-        self.assertEquals(obj.get_view('Image creation').get_feature('Imageproperties.productname').get_value(), 'myProduct') 
-        self.assertEquals(obj.get_view('Image creation').get_feature('Imageproperties.outputLocation').get_value(), 'myProduct') 
-        self.assertEquals(obj.get_view('Image creation').get_feature('Imageproperties.imagetarget').get_value(), '2') 
+        self.assertEquals(obj.get_view('Image creation').list_groups(),['Imageproperties _ test'])
+        self.assertEquals(obj.get_view('Image creation').list_all_features(),['Imageproperties _ test.proxy_imakerapi_imagetype', 
+                                                                           'Imageproperties _ test.proxy_imakerapi_rofs3version', 
+                                                                           'Imageproperties _ test.proxy_imakerapi_productname', 
+                                                                           'Imageproperties _ test.proxy_imakerapi_outputLocation', 
+                                                                           'Imageproperties _ test.proxy_imaker_imagetarget'])
+        self.assertEquals(obj.get_view('Image creation').get_feature('Imageproperties _ test.proxy_imakerapi_imagetype').get_value(), '0') 
+        self.assertEquals(obj.get_view('Image creation').get_feature('Imageproperties _ test.proxy_imakerapi_rofs3version').get_value(), 'V .50.2009.04.0113 RND') 
+        self.assertEquals(obj.get_view('Image creation').get_feature('Imageproperties _ test.proxy_imakerapi_productname').get_value(), 'myProduct') 
+        self.assertEquals(obj.get_view('Image creation').get_feature('Imageproperties _ test.proxy_imakerapi_outputLocation').get_value(), 'myProduct') 
+        self.assertEquals(obj.get_view('Image creation').get_feature('Imageproperties _ test.proxy_imaker_imagetarget').get_value(), '2') 
+        
+    def test_load_view_with_overrides(self):
+        reader = persistentconfml.get_reader_for_elem("configuration")
+        etree = ElementTree.fromstring(overrideview)
+        obj = reader.loads(etree)
+        self.assertEquals(obj.get_name(), None)
+        self.assertEquals(obj.list_views(), ['Image creation'])
+        view = obj.get_view('Image creation')
+        self.assertEquals(view.get_name(),'Image creation')
+        self.assertEquals(view.list_all_features(),['Imageproperties.proxy_imakerapi_imagetype', 
+                                                    'Imageproperties.proxy_imakerapi_productname', 
+                                                    'Imageproperties.proxy_imakerapi_outputLocation'
+                                                    ])
         
+        self.assertEquals(view.get_feature('Imageproperties.proxy_imakerapi_productname').name, "New Product Name")
+        self.assertEquals(view.get_feature('Imageproperties.proxy_imakerapi_productname').desc, "test desc override")
+        self.assertEquals(view.get_feature('Imageproperties.proxy_imakerapi_outputLocation').minOccurs, 2)
+        self.assertEquals(view.get_feature('Imageproperties.proxy_imakerapi_productname').minLength, 2)
+
+    def test_load_view_with_option_overrides(self):
+        reader = persistentconfml.get_reader_for_elem("configuration")
+        etree = ElementTree.fromstring(option_overrideview)
+        obj = reader.loads(etree)
+        self.assertEquals(obj.get_name(), None)
+        self.assertEquals(obj.list_views(), ['Image creation'])
+        view = obj.get_view('Image creation')
+        self.assertEquals(view.get_name(),'Image creation')
+        self.assertEquals(view.list_all_features(),['Imageproperties.proxy_imakerapi_imagetype', 
+                                                    'Imageproperties.proxy_imakerapi_productname', 
+                                                    'Imageproperties.proxy_imakerapi_outputLocation'
+                                                    ])
+        self.assertEquals(view.get_feature('Imageproperties.proxy_imakerapi_imagetype').get_option('value_2').get_name(), 'prd2')
+        self.assertEquals(view.get_feature('Imageproperties.proxy_imakerapi_imagetype').options['2'].get_name(), 'prd2')
+        self.assertEquals(view.get_feature('Imageproperties.proxy_imakerapi_imagetype').list_options(), ['value_0', 'value_1', 'value_2', 'value_2', 'value_5'])
+        self.assertEquals(view.get_feature('Imageproperties.proxy_imakerapi_imagetype').get_option('value_5').get_value(), '5')
+        self.assertEquals(view.get_feature('Imageproperties.proxy_imakerapi_outputLocation').minOccurs, 2)
+        self.assertEquals(view.get_feature('Imageproperties.proxy_imakerapi_productname').minLength, 2)
+
+    def test_load_view_with_properties_overrides(self):
+        reader = persistentconfml.get_reader_for_elem("configuration")
+        etree = ElementTree.fromstring(properties_overrideview)
+        obj = reader.loads(etree)
+        view = obj.get_view('Image creation')
+        
+        self.assertEquals(view.get_feature('Imageproperties.proxy_imakerapi_imagetype').get_property('mime').get_name(), 'mime')
+        self.assertEquals(view.get_feature('Imageproperties.proxy_imakerapi_imagetype').get_property('mime').get_value(), 'image/svgt image/jpg')
+        self.assertEquals(view.get_feature('Imageproperties.proxy_imakerapi_imagetype').get_property('mime2').name, 'mime2')
+        self.assertEquals(view.get_feature('Imageproperties.proxy_imakerapi_imagetype').get_property('mime2').value, 'image/svgt image/bmp')
+        self.assertEquals(view.get_feature('Imageproperties.proxy_imakerapi_imagetype').properties['mime'].get_name(), 'mime')
+        self.assertEquals(view.get_feature('Imageproperties.proxy_imakerapi_imagetype').properties['mime'].get_value(), 'image/svgt image/jpg')
+        self.assertEquals(view.get_feature('Imageproperties.proxy_imakerapi_imagetype').properties['mime2'].name, 'mime2')
+        self.assertEquals(view.get_feature('Imageproperties.proxy_imakerapi_imagetype').properties['mime2'].value, 'image/svgt image/bmp')
+
     def test_load_cvc_view(self):
         prj = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'data')))
         config = prj.get_configuration('cvc_root.confml')
@@ -522,7 +841,7 @@
         obj = reader.loads(etree)
         fea = obj.get_feature('CVC_StartupAnimationSequence.CVC_StartupAnimationTone')
         self.assertEquals(fea.list_properties(),['maxSize'])
-        self.assertEquals(fea.properties['maxSize'].value,'100')
+        self.assertEquals(fea.property_maxSize.value,'100')
 
         conffile = open(os.path.join(ROOT_PATH,"data/CVC_Preinstalled.confml"))
         reader = persistentconfml.get_reader_for_elem("configuration")
@@ -530,7 +849,7 @@
         obj = reader.loads(etree)
         fea = obj.get_feature('CVC_PreinstalledContent.CVC_PreInstalledMMSs.CVC_PreInstalledMMS')
         self.assertEquals(fea.list_properties(),['maxFileSize'])
-        self.assertEquals(fea.properties['maxFileSize'].value,'35')
+        self.assertEquals(fea.property_maxFileSize.value,'35')
 
     def test_load_voicemailbox_confml_from_file(self):
         conffile = open(os.path.join(ROOT_PATH,"data/voicemailbox.confml"))
@@ -548,21 +867,55 @@
         etree = ElementTree.fromstring(conffile.read())
         obj = reader.loads(etree)
         setting = obj.get_feature('Facets.MessageSize')
-        self.assertEquals(setting.minInclusive,'0')
-        self.assertEquals(setting.maxInclusive,'10')
+        self.assertEquals(setting.minInclusive,0)
+        self.assertEquals(setting.maxInclusive,10)
         setting = obj.get_feature('Facets.MessageSize2')
-        self.assertEquals(setting.minExclusive,'-1')
-        self.assertEquals(setting.maxExclusive,'11')
+        self.assertEquals(setting.minExclusive,-1)
+        self.assertEquals(setting.maxExclusive,11)
         setting = obj.get_feature('Facets.StringPattern')
         self.assertEquals(setting.pattern,"[a-zA-Z]{5,10}")        
         setting = obj.get_feature('Facets.TotalDigits')
-        self.assertEquals(setting.totalDigits,'3')
+        self.assertEquals(setting.totalDigits,3)
         dview = obj.get_default_view()
         intfea = dview.get_feature('Facets.MessageSize')
         self.assertEquals(intfea.type,'int')
         self.assertEquals(intfea.value,9)
-             
-class TestConfigurationWriter(unittest.TestCase):    
+    
+    def test_load_sequence_setting_test_confml_from_file(self):
+        conffile = open(os.path.join(ROOT_PATH,"testdata/read_write/sequence_setting_test.confml"))
+        reader = persistentconfml.get_reader_for_elem("configuration")
+        etree = ElementTree.fromstring(conffile.read())
+        obj = reader.loads(etree)
+        dview = obj.get_default_view()
+        fea = dview.get_feature('SequenceSettingTest.SequenceSetting')
+        self.assertEquals(fea.get_template(),
+                          [['seq/default_folder', None],
+                           '1.0',
+                           ['seq/default_file.txt', None],
+                           '1',
+                           'template',
+                           'false',
+                           '0',
+                           '"opt 0"',
+                           '2009-02-02',
+                           '07:30:15',
+                           '2009-02-02-07:00:00',
+                           'P5Y4M3DT12H25M15S'])
+
+    def test_load_selection_with_name_id_mapping(self):
+        reader = persistentconfml.get_reader_for_elem("configuration")
+        obj = reader.loads(ElementTree.fromstring(selectionsetting))
+        self.assertEquals(obj._list(),['CTD_APs',
+                                        'TestApplication', 
+                                        'data'])
+        self.assertEquals(obj.get_data('TestApplication.DefaultAP').get_map(), "CTD_APs/AP[@key='Operator 1']")
+        
+        #
+class TestConfigurationWriter(unittest.TestCase):
+    def tearDown(self):
+        if os.path.exists(os.path.join(ROOT_PATH,'temp/configwriter')):
+            shutil.rmtree(os.path.join(ROOT_PATH,'temp/configwriter'))
+    
     def test_dump_simple_configuration(self):
         config = api.Configuration("test.confml")
         writer = persistentconfml.get_writer_for_class("Configuration")
@@ -645,12 +998,12 @@
     def test_configuration_with_features_and_properties(self):
         config = model.ConfmlConfiguration("test.confml")
         config.add_feature(model.ConfmlSetting('testfea11'))
-        config.testfea11.add_property(name='smaller',value='10')
-        config.testfea11.add_property(name='bigger',value='1', unit='B')
+        config.testfea11.create_property(name='smaller',value='10')
+        config.testfea11.create_property(name='bigger',value='1', unit='B')
         elem = persistentconfml.dumps(config)
         config2 =  persistentconfml.loads(elem)
-        self.assertEquals(config2.testfea11.properties['smaller'].value,'10')
-        self.assertEquals(config2.testfea11.properties['bigger'].value,'1')
+        self.assertEquals(config2.testfea11.property_smaller.value,'10')
+        self.assertEquals(config2.testfea11.property_bigger.value,'1')
 
     def test_configuration_with_features_and_minoccurs(self):
         config = model.ConfmlConfiguration("test.confml")
@@ -719,19 +1072,6 @@
         self.assertEquals(config2.testfea2.maxLength,None)
         self.assertEquals(config2.testfea3.maxLength,100)
 
-    def test_configuration_with_features_and_maxlength(self):
-        config = model.ConfmlConfiguration("test.confml")
-        config.add_feature(model.ConfmlSetting('testfea1', type='int'))
-        config.add_feature(model.ConfmlSetting('testfea2', type='int'))
-        config.add_feature(model.ConfmlSetting('testfea3', type='int',minLength=100))
-        config.testfea1.minLength = 10
-
-        elem = persistentconfml.dumps(config)
-        config2 =  persistentconfml.loads(elem)
-        self.assertEquals(config2.testfea1.minLength,'10')
-        self.assertEquals(config2.testfea3.minLength,'100')
-        self.assertEquals(config2.testfea2.minLength,None)
-
     def test_configuration_with_features(self):
         config = model.ConfmlConfiguration("test.confml")
         config.add_feature(api.Feature('testfea1'))
@@ -746,7 +1086,7 @@
         config.add_feature(api.Feature('testfea5'))
         config.add_feature(api.Feature('testfea6'))
         set1.set_value('pre')
-        config.testfea1.set_value('foo:bar')
+        config.testfea1.testfea11.set_value('foo:bar')
         config.testfea4.set_value('4')
         writer = persistentconfml.get_writer_for_class("Configuration")
         elem = writer.dumps(config)
@@ -777,11 +1117,12 @@
         config.add_feature(api.Feature('testfea4'))
         config.add_feature(api.Feature('testfea5'))
         config.add_feature(api.Feature('testfea6'))
-        set1.value = ["pre","post"]       
-        self.assertEquals(set1.get_data().get_value(), '"pre" "post"')
+        set1.value = ["pre","post"]
+        self.assertEquals(set1.get_datas()[0].get_value(), 'pre')
+        self.assertEquals(set1.get_datas()[1].get_value(), 'post')
         writer = persistentconfml.get_writer_for_class("Configuration")
         elem = writer.dumps(config)
-        self.assertEquals(ElementTree.tostring(elem), '<configuration name="test_confml" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema"><feature name="testfea1" ref="testfea1"><setting name="testfea11" ref="testfea11" /></feature><feature name="testfea2" ref="testfea2"><setting name="testfea21" ref="testfea21" type="multiSelection"><option name="pre" value="1" /><option name="normal" value="2" /><option name="post" value="3" /></setting></feature><feature name="testfea4" ref="testfea4" /><feature name="testfea5" ref="testfea5" /><feature name="testfea6" ref="testfea6" /><data><testfea2><testfea21>"pre" "post"</testfea21></testfea2></data></configuration>')
+        self.assertEquals(ElementTree.tostring(elem), '<configuration name="test_confml" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema"><feature ref="testfea1"><setting ref="testfea11" /></feature><feature ref="testfea2"><setting ref="testfea21" type="multiSelection"><option name="pre" value="1" /><option name="normal" value="2" /><option name="post" value="3" /></setting></feature><feature ref="testfea4" /><feature ref="testfea5" /><feature ref="testfea6" /><data><testfea2><testfea21>pre</testfea21><testfea21>post</testfea21></testfea2></data></configuration>')
         etree = ElementTree.fromstring(ElementTree.tostring(elem))
         fea1 = etree.find('{http://www.s60.com/xml/confml/2}feature')
         self.assertEquals(fea1.get('ref'),'testfea1')
@@ -789,17 +1130,19 @@
         config2 =  persistentconfml.get_reader_for_elem('configuration').loads(etree)
         self.assertEquals(config2.testfea2.list_features(),['testfea21'])
         self.assertEquals(config2.testfea2.testfea21.get_type(),'multiSelection')
-        self.assertEquals(config2.testfea2.testfea21.get_value(), ['pre', 'post'])
+        self.assertEquals(config2.testfea2.testfea21.get_value(), ('pre', 'post'))
 
     def test_configuration_with_view(self):
-        config = api.Configuration("view.confml")
-        config.add_view('testing')
+        config = model.ConfmlConfiguration("view.confml")
+        config.create_view('testing')
         view = config.get_view('testing')
-        view.add_group('group1')
-        view.add_group('group2')
-        view.add_group('group3')
-        view.group1.add(api.FeatureLink('test.foo'))
-        view.group2.add(api.FeatureLink('foo.*'))
+        view.create_group('group1')
+        view.create_group('group2')
+        view.create_group('group3')
+        fl = model.ConfmlFeatureLink('test.foo')
+        fl.desc = "test desc"
+        view.group1.add(fl)
+        view.group2.create_featurelink('foo.*')
         writer = persistentconfml.get_writer_for_class("Configuration")
         elem = writer.dumps(config)
         etree = ElementTree.fromstring(ElementTree.tostring(elem))
@@ -813,36 +1156,57 @@
         settings = [elem for elem in etree.getiterator('{http://www.s60.com/xml/confml/2}setting')]
         self.assertEquals(settings[0].get('ref'), 'test/foo')
         self.assertEquals(settings[1].get('ref'), 'foo/*')
-
-    def test_load_dump_reload_configuration_with_view(self):
+        
+    def test_load_dump_reload_configuration_with_view_and_overrides(self):
         reader = persistentconfml.get_reader_for_elem("configuration")
-        etree = ElementTree.fromstring(simpleview)
+        etree = ElementTree.fromstring(overrideview)
         obj = reader.loads(etree)
         # Getting the view populates it and check that the writing still works
-        self.assertEquals(obj.get_view('Image creation').get_name(),'Image creation')
-        self.assertEquals(obj.get_view('Image creation').id,'imakerimage')
-        self.assertEquals(obj.get_view('Image creation').list_groups(), ['Imageproperties'])
+        view = obj.get_view('Image creation')
+        self.assertEquals(view.get_name(),'Image creation')
+        self.assertEquals(view.id,'imakerimage')
+        self.assertEquals(view.list_groups(), ['Imageproperties'])
+        viewfea = view.get_feature('Imageproperties.proxy_imakerapi_productname')
+        self.assertEquals(viewfea.name, "New Product Name")
         writer = persistentconfml.get_writer_for_class("Configuration")
         elem = writer.dumps(obj)
         # Reload the configuration with view after dumping it to ensure data stays the same
         elemstr = ElementTree.tostring(elem)      
         etree = ElementTree.fromstring(elemstr)
         obj = reader.loads(etree)
-        self.assertEquals(obj.get_view('Image creation').get_name(),'Image creation')
-        self.failUnlessEqual(obj.get_view('Image creation').id,'imakerimage', 'Known bug (#564)')
-        self.assertEquals(obj.get_view('Image creation').id,'imakerimage')
+        view = obj.get_view('Image creation')
+        self.assertEquals(view.get_name(),'Image creation')
+        self.failUnlessEqual(view.id,'imakerimage')
+        self.assertEquals(view.id,'imakerimage')
+        # Check that the override parameters are also saved / loaded
+        self.assertEquals(view.get_feature('Imageproperties.proxy_imakerapi_productname').name, 'New Product Name')
+        self.assertEquals(view.get_feature('Imageproperties.proxy_imakerapi_productname').has_attribute('name'), True)
+        self.assertEquals(view.get_feature('Imageproperties.proxy_imakerapi_productname').desc, "test desc override")
+        
+        self.assertEquals(view.get_feature('Imageproperties.proxy_imakerapi_imagetype').get_option('value_2').get_name(), 'prd_renamed')
+        self.assertEquals(view.get_feature('Imageproperties.proxy_imakerapi_imagetype').list_options(), ['value_0', 'value_1', 'value_2', 'value_2'])
+        self.assertEquals(view.get_feature('Imageproperties.proxy_imakerapi_outputLocation').minOccurs, 2)
+        fea = view.get_feature('Imageproperties.proxy_imakerapi_outputLocation')
+        self.assertEquals(fea.has_attribute('name'), False)
+        
+        self.assertEquals(view.get_feature('Imageproperties.proxy_imakerapi_productname').minLength, 2)
+        # check that the original attributes are still valid
+        self.assertEquals(view.get_feature('Imageproperties.proxy_imakerapi_productname')._obj.name, "PRODUCT_NAME")
+        self.assertEquals(view.get_feature('Imageproperties.proxy_imakerapi_productname')._obj.desc, None)
         
     def test_load_configuration_and_create_copy_and_dump(self):
         conffile = open(os.path.join(ROOT_PATH,"data/commsdatcreator.confml"))
         #reader = persistentconfml.get_reader_for_elem("configuration")
         #etree = ElementTree.fromstring(conffile.read())
         obj = persistentconfml.loads(conffile.read())
-        copyconfig = api.Configuration('data/copy_commsdatcreator.confml')
+        copyconfig = api.Configuration('temp/copy_commsdatcreator.confml')
         
         for child in obj._objects():
             copyconfig._add(child)
         output = persistentconfml.dumps(copyconfig)
-        ofile = open(os.path.join(ROOT_PATH,'data/copy_commsdatcreator.confml'),"wb")
+        if not os.path.exists(os.path.join(ROOT_PATH,'temp')):
+            os.mkdir(os.path.join(ROOT_PATH,'temp'))
+        ofile = open(os.path.join(ROOT_PATH,'temp/copy_commsdatcreator.confml'),"wb")
         ofile.write(output)
         ofile.close()
         newconfig = persistentconfml.loads(output)
@@ -856,7 +1220,7 @@
         
     def test_create_configuration_with_meta_and_dump(self):
         prj = api.Project(api.Storage.open('dump','w'))
-        testconf = prj.create_configuration('test.confml')
+        testconf = prj.create_configuration('test.confml', True)
         testconf.include_configuration('test/foo.confml')
         testconf.save()
         prj.close()
@@ -883,6 +1247,65 @@
         prj.close()
         shutil.rmtree('dump')
 
+    def test_write_selection_with_nameid_mapping(self):
+        reader = persistentconfml.get_reader_for_elem("configuration")
+        obj = reader.loads(ElementTree.fromstring(selectionsetting))
+        
+        self.assertEquals(obj.get_data('TestApplication.DefaultAP').get_map(), "CTD_APs/AP[@key='Operator 1']")
+        self.assertEquals(obj.get_data('TestApplication.DefaultAP').get_fearef(), "TestApplication.DefaultAP")
+        
+        writer = persistentconfml.get_writer_for_class("Configuration")
+        elem = writer.dumps(obj)
+        etree = ElementTree.fromstring(ElementTree.tostring(elem))
+        
+        self.assertEquals(
+                          etree.find('{http://www.s60.com/xml/confml/2}data')
+                          .find('{http://www.s60.com/xml/confml/2}TestApplication')
+                          .find('{http://www.s60.com/xml/confml/2}DefaultAP')
+                          .get('map'),
+                          "CTD_APs/AP[@key='Operator 1']")
+        
+    def test_write_multiselection_with_name_id_mapping(self):
+        reader = persistentconfml.get_reader_for_elem("configuration")
+        obj = reader.loads(ElementTree.fromstring(multiselection))
+
+        self.assertEquals(obj.get_data('aFeature.selectionSetting').get_map(), "aFeature/exampleSequence[@key='12']")
+        self.assertEquals(obj.get_data('aFeature.multiselectionSetting')[0].get_value(), '0')
+        self.assertEquals(obj.get_data('aFeature.multiselectionSetting')[1].get_map(), "aFeature/exampleSequence[@key='12']")
+        self.assertEquals(obj.get_data('aFeature.multiselectionSetting')[2].get_map(), "aFeature/exampleSequence[@key='34']")
+        self.assertEquals(obj.get_data('aFeature.multiselectionSettingOverride')[0].get_map(), "aFeature/exampleSequence[@key='12']")
+        self.assertEquals(obj.get_data('aFeature.multiselectionSettingOverride')[1].get_map(), "aFeature/exampleSequence[@key='34']")
+        
+        writer = persistentconfml.get_writer_for_class("Configuration")
+        elem = writer.dumps(obj)
+        etree = ElementTree.fromstring(ElementTree.tostring(elem))
+        
+        self.assertEquals(
+                          etree.find('{http://www.s60.com/xml/confml/2}data')
+                          .find('{http://www.s60.com/xml/confml/2}aFeature')
+                          .find('{http://www.s60.com/xml/confml/2}selectionSetting')
+                          .get('map'), "aFeature/exampleSequence[@key='12']")
+        self.assertEquals(
+                  etree.find('{http://www.s60.com/xml/confml/2}data')
+                  .find('{http://www.s60.com/xml/confml/2}aFeature')
+                  .find('{http://www.s60.com/xml/confml/2}multiselectionSetting')
+                  .text, "0")
+
+        mss = []
+        for data_elem in etree.getiterator('{http://www.s60.com/xml/confml/2}data'):
+            for mss_elem in data_elem.getiterator('{http://www.s60.com/xml/confml/2}multiselectionSetting'):
+                mss.append(mss_elem.get('map'))
+        
+        self.assertEquals(mss, [None, "aFeature/exampleSequence[@key='12']", "aFeature/exampleSequence[@key='34']"])
+
+        msso = []
+        for data_elem in etree.getiterator('{http://www.s60.com/xml/confml/2}data'):
+            for msso_elem in data_elem.getiterator('{http://www.s60.com/xml/confml/2}multiselectionSettingOverride'):
+                msso.append(msso_elem.get('map'))
+        
+        self.assertEquals(msso, ["aFeature/exampleSequence[@key='12']", "aFeature/exampleSequence[@key='34']"])
+
+        
 class TestMeta(unittest.TestCase):
     def test_get_reader_for_meta(self):
         reader = persistentconfml.get_reader_for_elem("meta")
@@ -955,7 +1378,7 @@
         celem = api.Feature('testing')
         etree = writer.dumps(celem)
         self.assertEquals(etree.get('ref'),'testing')
-        self.assertEquals(etree.get('name'),'testing')
+        self.assertEquals(etree.get('name'), None)
 
 
 class TestSetting(unittest.TestCase):
@@ -980,7 +1403,7 @@
         celem = model.ConfmlSetting('testing')
         etree = writer.dumps(celem)
         self.assertEquals(etree.get('ref'),'testing')
-        self.assertEquals(etree.get('name'),'testing')
+        self.assertEquals(etree.get('name'), None)
         self.assertEquals(etree.get('type'),None)
 
     def test_write_setting_with_options(self):
@@ -993,7 +1416,7 @@
         etree = writer.dumps(elem)
 
         self.assertEquals(etree.get('ref'),'testing')
-        self.assertEquals(etree.get('name'),'testing')
+        self.assertEquals(etree.get('name'), None)
         self.assertEquals(etree.get('type'),'selection')
         self.assertEquals(etree.find('option').get('name'),'one')
         self.assertEquals(etree.find('option').get('value'),'1')
@@ -1008,13 +1431,15 @@
         setting.totalDigits = 3
         setting.pattern = "\d*{3}"
         etree = writer.dumps(setting)
+        strxml = confmltree.tostring(etree, {'http://xs.com' : 'xs'} )
+        etree = ElementTree.fromstring(strxml)
         
-        self.assertEquals(etree.find('xs:minInclusive').get('value'),'0')
-        self.assertEquals(etree.find('xs:maxInclusive').get('value'),'10')
-        self.assertEquals(etree.find('xs:minExclusive').get('value'),'0')
-        self.assertEquals(etree.find('xs:maxExclusive').get('value'),'10')
-        self.assertEquals(etree.find('xs:totalDigits').get('value'),'3')
-        self.assertEquals(etree.find('xs:pattern').get('value'),'\d*{3}')
+        self.assertEquals(etree.find('{http://xs.com}minInclusive').get('value'),'0')
+        self.assertEquals(etree.find('{http://xs.com}maxInclusive').get('value'),'10')
+        self.assertEquals(etree.find('{http://xs.com}minExclusive').get('value'),'0')
+        self.assertEquals(etree.find('{http://xs.com}maxExclusive').get('value'),'10')
+        self.assertEquals(etree.find('{http://xs.com}totalDigits').get('value'),'3')
+        self.assertEquals(etree.find('{http://xs.com}pattern').get('value'),'\d*{3}')
         
         conffile = open(os.path.join(ROOT_PATH,"data/facets.confml"))
         obj = persistentconfml.loads(conffile.read())
@@ -1073,8 +1498,8 @@
                                                'name': 'strme',
                                                'type': 'string'}))
         setobj = reader.loads(elem)
-        self.assertEqual(setobj.get_map_key().name,"intme")
-        self.assertEqual(setobj.get_map_value().name,"strme")
+        self.assertEqual(setobj.mapKey, "intsetting")
+        self.assertEqual(setobj.mapValue, "strsetting")
 
 class TestSettingData(unittest.TestCase):
     def test_get_reader_for_data(self):
@@ -1131,6 +1556,193 @@
         obj = reader.loads(etree)
         self.assertEquals(obj.meta.get('type'), 'featurelist')
 
+class TestWriteSequenceTemplates(BaseTestCase):
+    EXPECTED_DIR = os.path.join(ROOT_PATH, 'testdata/seq_template/expected')
+    TEMP_DIR = os.path.join(ROOT_PATH, 'temp/')
+    
+    def _add_simple_sequence(self, config):
+        """
+        Add a feature with a simple sequence setting into the given
+        configuration.
+        @return: The added sequence setting object.
+        """
+        fea = api.Feature('TestFeature', name='Test feature')
+        seq_fea = model.ConfmlSequenceSetting('SequenceSetting', name='Sequence setting')
+        fea.add_feature(seq_fea)
+        config.add_feature(fea)
+    
+        seq_fea.add_feature(model.ConfmlStringSetting('String1', name="String 1"))
+        seq_fea.add_feature(model.ConfmlFileSetting('File', name="File setting"))
+        seq_fea.add_feature(model.ConfmlStringSetting('String2', name="String 2"))
+        
+        return seq_fea
+    
+    def _add_complex_sequence(self, config):
+        """
+        Add a feature with a complex sequence setting into the given
+        configuration.
+        @return: The added sequence setting object.
+        """
+        fea = api.Feature('TestFeature', name='Test feature')
+        seq_fea = model.ConfmlSequenceSetting('SequenceSetting', name='Sequence setting')
+        fea.add_feature(seq_fea)
+        config.add_feature(fea)
+    
+        seq_fea.add_feature(model.ConfmlFileSetting('File', name="File setting"))
+        seq_fea.add_feature(model.ConfmlFolderSetting('Folder', name="Folder setting"))
+        seq_fea.add_feature(model.ConfmlStringSetting('String', name="String setting"))
+        seq_fea.add_feature(model.ConfmlIntSetting('Int', name="Int setting"))
+        seq_fea.add_feature(model.ConfmlRealSetting('Real', name="Real setting"))
+        seq_fea.add_feature(model.ConfmlBooleanSetting('Boolean', name="Boolean setting"))
+        seq_fea.add_feature(model.ConfmlDateSetting('Date', name="Date setting"))
+        seq_fea.add_feature(model.ConfmlTimeSetting('Time', name="Time setting"))
+        seq_fea.add_feature(model.ConfmlDateTimeSetting('DateTime', name="Date-time setting"))
+        seq_fea.add_feature(model.ConfmlDurationSetting('Duration', name="Duration setting"))
+        
+        return seq_fea
+    
+    def test_write_simple_seq_no_template(self):
+        FILE_NAME = 'write_simple_seq_no_template.confml'
+        prj = api.Project(api.Storage.open(self.TEMP_DIR, "w"))
+        config = prj.create_configuration(FILE_NAME)
+        
+        seq = self._add_simple_sequence(config)
+    
+        seq.add_sequence(['row 1', ['lp1', 'tp1'], 'x'])
+        seq.add_sequence(['row 2', ['lp2', 'tp2'], 'y'])
+    
+        config.save()
+        prj.close()
+        
+        self.assert_file_contents_equal(
+            os.path.join(self.TEMP_DIR, FILE_NAME),
+            os.path.join(self.EXPECTED_DIR, 'simple_seq_no_template.confml'))
+    
+    def test_write_simple_seq(self):
+        FILE_NAME = 'write_simple_seq.confml'
+        prj = api.Project(api.Storage.open(self.TEMP_DIR, "w"))
+        config = prj.create_configuration(FILE_NAME)
+        config.name = 'foo'
+        
+        seq = self._add_simple_sequence(config)
+    
+        seq.set_template(['c1', ['lp', 'tp'], 'c2'])
+        seq.add_sequence(['row 1', ['lp1', 'tp1'], 'x'])
+        seq.add_sequence(['row 2', ['lp2', 'tp2'], 'y'])
+    
+        config.save()
+        prj.close()
+        
+        self.assert_file_contents_equal(
+            os.path.join(self.TEMP_DIR, FILE_NAME),
+            os.path.join(self.EXPECTED_DIR, 'simple_seq.confml'))
+    
+    def test_write_simple_seq_2(self):
+        FILE_NAME = 'write_simple_seq_2.confml'
+        prj = api.Project(api.Storage.open(self.TEMP_DIR, "w"))
+        config = prj.create_configuration(FILE_NAME)
+        config.name = 'foo'
+        
+        seq = self._add_simple_sequence(config)
+    
+        # It shouldn't matter if the template is reset in the middle
+        seq.set_template(['x1', ['lp', 'tp'], 'x2'])
+        seq.add_sequence(['row 1', ['lp1', 'tp1'], 'x'])
+        seq.set_template(['c1', ['lp', 'tp'], 'c2'])
+        seq.add_sequence(['row 2', ['lp2', 'tp2'], 'y'])
+    
+        config.save()
+        prj.close()
+        
+        self.assert_file_contents_equal(
+            os.path.join(self.TEMP_DIR, FILE_NAME),
+            os.path.join(self.EXPECTED_DIR, 'simple_seq.confml'))
+    
+    def test_write_simple_seq_3(self):
+        FILE_NAME = 'write_simple_seq_3.confml'
+        prj = api.Project(api.Storage.open(self.TEMP_DIR, "w"))
+        config = prj.create_configuration(FILE_NAME)
+        config.name = 'foo'
+        
+        seq = self._add_simple_sequence(config)
+        
+        # Add multiple templates into the data section to make
+        # sure that they are all replaced when set_template() is called
+        def create_template_data():
+            template_data = api.Data(fqr='TestFeature.SequenceSetting', template=True)
+            template_data.add(api.Data(ref='String1', value='t1'))
+            data_a1 = api.Data(ref='File')
+            data_a1.add(api.Data(ref='localPath', value='lp'))
+            data_a1.add(api.Data(ref='targetPath', value='tp'))
+            template_data.add(data_a1)
+            template_data.add(api.Data(ref='String2', value='t2'))
+            return template_data
+        from cone.public import container
+        config.add_data(create_template_data(), policy=container.APPEND)
+        config.add_data(create_template_data(), policy=container.APPEND)
+        config.add_data(create_template_data(), policy=container.APPEND)
+        seq = config.get_default_view().get_feature('TestFeature.SequenceSetting')
+        self.assertEquals(seq.get_template(), ['t1', ['lp', 'tp'], 't2'])
+        
+        # Add some data and set the template
+        seq.add_sequence(['row 1', ['lp1', 'tp1'], 'x'])
+        seq.add_sequence(['row 2', ['lp2', 'tp2'], 'y'])
+        seq.set_template(['c1', ['lp', 'tp'], 'c2'])
+    
+        config.save()
+        prj.close()
+        
+        self.assert_file_contents_equal(
+            os.path.join(self.TEMP_DIR, FILE_NAME),
+            os.path.join(self.EXPECTED_DIR, 'simple_seq.confml'))
+    
+    def test_write_complex_seq(self):
+        FILE_NAME = 'write_complex_seq.confml'
+        prj = api.Project(api.Storage.open(self.TEMP_DIR, "w"))
+        config = prj.create_configuration(FILE_NAME)
+        
+        seq = self._add_complex_sequence(config)
+        
+        seq.set_template([['file lp', 'file tp'], ['folder lp', 'folder tp'],
+                          'string', '0', '0.1', 'false',
+                          '2010-02-10', '00:00:00', '2010-02-10-00:00:00', 'P5Y4M3DT12H25M15S'])
+        
+        seq.add_sequence([['file lp1', 'file tp1'], ['folder lp1', 'folder tp1'],
+                          'string1', '1', '1.1', 'true',
+                          '2009-02-01', '01:30:15', '2009-02-01-01:00:00', 'PT1S'])
+        seq.add_sequence([['file lp2', 'file tp2'], ['folder lp2', 'folder tp2'],
+                          'string2', '2', '1.2', 'false',
+                          '2009-02-02', '02:30:15', '2009-02-02-02:00:00', 'PT2S'])
+        
+        config.save()
+        prj.close()
+        
+        self.assert_file_contents_equal(
+            os.path.join(self.TEMP_DIR, FILE_NAME),
+            os.path.join(self.EXPECTED_DIR, 'complex_seq.confml'))
+    
+    def test_write_complex_seq_with_nones(self):
+        FILE_NAME = 'write_complex_seq_with_nones.confml'
+        prj = api.Project(api.Storage.open(self.TEMP_DIR, "w"))
+        config = prj.create_configuration(FILE_NAME)
+        
+        seq = self._add_complex_sequence(config)
+        
+        seq.set_template([['file lp', None], [None, 'folder tp'],
+                          'string', None, 0.1, None,
+                          '2010-02-10', None, '2010-02-10-00:00:00', None])
+        
+        seq.add_sequence([['file lp1', None], [None, 'folder tp1'],
+                          'string1', None, 1.1, None,
+                          '2009-02-01', None, '2009-02-01-01:00:00', None])
+        
+        config.save()
+        prj.close()
+        
+        self.assert_file_contents_equal(
+            os.path.join(self.TEMP_DIR, FILE_NAME),
+            os.path.join(self.EXPECTED_DIR, 'complex_seq_with_nones.confml'))
+
 class TestReadWriteConfml(BaseTestCase):
     """
     Test case for ensuring that reading in a ConfML file and then writing
@@ -1176,7 +1788,7 @@
             
             write(PATH_ORIGINAL, original_data_normalized)
             write(PATH_DUMPED, model_data_normalized)
-            self.fail("Known bug (#506)")
+            #self.fail("Known bug (#506)")
             self.fail("Read-write output for file '%s' is different, see the files in '%s'" % (file_name, output_dir))
         else:
             # Test was successful, remove any old files that might have been there,
@@ -1190,6 +1802,38 @@
             file_name  = os.path.basename(file_path),
             input_dir  = os.path.dirname(file_path),
             output_dir = os.path.normpath(os.path.join(ROOT_PATH, 'temp/read_write_results')))
+    
+    def test_create_configuration_with_view_includes_to_storage(self):
+        prj = api.Project(api.Storage.open("temp/testprojectviews", "w"))
+        test = prj.create_configuration("testview.confml")
+        fea1 = test.create_feature("fea1")
+        set1 =  fea1.create_feature('set1', type="int")
+        view = test.create_view("Testing")
+        test1 = prj.create_configuration("testview1.confml")
+        view1 = test1.create_view("subview1")
+        test2 = prj.create_configuration("testview2.confml")
+        view2 = test2.create_view("subview2")
+        group = view.create_group("group1")
+        group.create_featurelink("fea1/set1")
+        group2 = view2.create_group("group2")
+        group2.create_featurelink("fea1/set1")
+        view.add(api.ConfigurationProxy("testview1.confml"))
+        group.add(api.ConfigurationProxy("testview2.confml"))
+        prj.save()
+        prj.close()
+        
+        prj = api.Project(api.Storage.open("temp/testprojectviews", "w"))
+        test = prj.get_configuration("testview.confml")
+        self.assertEquals(test.list_views(), ['Testing', 
+                                              'Testing.group1.testview2_confml.subview2',
+                                              'Testing.testview1_confml.subview1'])
+        
+        view = test.get_view('Testing')
+        
+        self.assertEquals(view.list_all_features(), ['group1.proxy_fea1_set1']) 
+        
+        self.assertTrue(os.path.exists("temp/testprojectviews"))
+        shutil.rmtree("temp")
 
 # Create a separate test method for each ConfML file in the read-write test data
 _READ_WRITE_TESTDATA_DIR = os.path.join(ROOT_PATH, 'testdata/read_write')
@@ -1205,7 +1849,7 @@
         method.__name__ = test_method_name
         setattr(TestReadWriteConfml, test_method_name, method)
     _register_test_method(path)
-
+    
 
 if __name__ == '__main__':
     unittest.main()
--- a/configurationengine/source/cone/core/tests/__init__.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/core/tests/__init__.py	Tue Aug 10 14:29:28 2010 +0300
@@ -14,36 +14,4 @@
 # Description: 
 #
 
-import unittest, os, sys
 
-ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
-SOURCE_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../../..'))
-TESTAUTO_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../../../testautomation'))
-if SOURCE_ROOT not in sys.path:
-    sys.path.append(SOURCE_ROOT)
-if TESTAUTO_ROOT not in sys.path:
-    sys.path.insert(0,TESTAUTO_ROOT)
-    
-# Find all unittest_*.py files in this folder
-import re
-__all__ = filter(lambda name: re.match(r'^unittest_.*\.py$', name) != None, os.listdir(ROOT_PATH))
-# Strip .py endings
-__all__ = map(lambda name: name[:-3], __all__)
-
-def collect_suite():  
-    sys.path.insert(0, ROOT_PATH)
-    try:
-        suite = unittest.TestSuite()
-        for test_module in __all__:
-            # Load the test module dynamically and add it to the test suite
-            module = __import__(test_module)
-            suite.addTests(unittest.TestLoader().loadTestsFromModule(module))
-        return suite
-    finally:
-        del sys.path[0]
-
-def runtests():
-    unittest.TextTestRunner(verbosity=2).run(collect_suite())
-
-if __name__ == '__main__':
-    runtests()
--- a/configurationengine/source/cone/core/tests/runtests.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/core/tests/runtests.py	Tue Aug 10 14:29:28 2010 +0300
@@ -14,6 +14,6 @@
 # Description: 
 #
 
-import __init__
-
-__init__.runtests()
\ No newline at end of file
+if __name__ == '__main__':
+    import nose
+    nose.core.run(argv=['collector','--include=unittest', '--verbosity=3'])
Binary file configurationengine/source/cone/core/tests/testdata/layered_res_test.zip has changed
Binary file configurationengine/source/cone/core/tests/testdata/test_project.cpf has changed
--- a/configurationengine/source/cone/core/tests/unittest_configuration.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/core/tests/unittest_configuration.py	Tue Aug 10 14:29:28 2010 +0300
@@ -21,19 +21,141 @@
 import string
 import sys,os
 
-import __init__
 from cone.public import api, plugin
 from cone.core import *
 
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
 test_project        = os.path.join(ROOT_PATH,"testdata/test_project.cpf")
 multiroot_project   = os.path.join(ROOT_PATH,"testdata/multiroot_test.zip")
+LAYERED_RES_PROJECT = os.path.join(ROOT_PATH,"testdata/layered_res_test.zip")
+
 
 class TestConfiguration(unittest.TestCase):    
     def setUp(self):
         pass
 
-    # @test 
+    def test_layered_resources_invalid_resource_type(self):
+        p = api.Project(api.Storage.open(LAYERED_RES_PROJECT))
+        config = p.get_configuration('root.confml')
+        self.assertRaises(ValueError, config.layered_resources, resource_type='foo')
+    
+    def test_layered_resource_invalid_params(self):
+        p = api.Project(api.Storage.open(LAYERED_RES_PROJECT))
+        config = p.get_configuration('root.confml')
+        
+        # Both folder and resource_type specified
+        self.assertRaises(ValueError, config.layered_resources, folder='foo', resource_type='implml')
+        
+        # Neither folder nor resource_type specified
+        self.assertRaises(ValueError, config.layered_resources, folder=None, resource_type=None)
+    
+    def test_layered_resources(self):
+        p = api.Project(api.Storage.open(LAYERED_RES_PROJECT))
+        config = p.get_configuration('root.confml')
+        
+        data = config.layered_resources(resource_type='confml').data
+        self.assertEquals(data, {'test.confml': ['layer1/confml/test.confml',
+                                                 'layer2/confml/test.confml']})
+        
+        data = config.layered_resources(resource_type='implml').data
+        self.assertEquals(data, {'test.implml': ['layer1/implml/test.implml',
+                                                 'layer2/implml/test.implml']})
+        
+        data = config.layered_resources(resource_type='content').data
+        self.assertEquals(data, {'foo.txt': ['layer1/content/foo.txt',
+                                             'layer2/content/foo.txt']})
+        
+        data = config.layered_resources(resource_type='doc').data
+        self.assertEquals(data, {'bar.txt': ['layer1/doc/bar.txt',
+                                             'layer2/doc/bar.txt']})
+    
+    def test_layered_resources_custom_folder(self):
+        p = api.Project(api.Storage.open(LAYERED_RES_PROJECT))
+        config = p.get_configuration('root.confml')
+        
+        data = config.layered_resources(folder='foo').data
+        self.assertEquals(data, {'bar.txt': ['layer1/foo/bar.txt',
+                                             'layer2/foo/bar.txt']})
+    
+    def test_layered_resources_directly_from_layer(self):
+        p = api.Project(api.Storage.open(LAYERED_RES_PROJECT))
+        config = p.get_configuration('layer1/root.confml')
+        
+        self.assertEquals(config.layered_resources(resource_type='confml').data,
+                          {'test.confml': ['layer1/confml/test.confml']})
+        
+        self.assertEquals(config.layered_resources(resource_type='implml').data,
+                          {'test.implml': ['layer1/implml/test.implml']})
+    
+    def test_layered_resources_with_empty_folders(self):
+        p  = api.Project(api.Storage.open(LAYERED_RES_PROJECT))
+        config = p.get_configuration('root.confml')
+        
+        data = config.layered_resources(empty_folders=True, resource_type='confml').data
+        self.assertEquals(data, {'test.confml': ['layer1/confml/test.confml',
+                                                 'layer2/confml/test.confml'],
+                                 'empty':       ['layer1/confml/empty',
+                                                 'layer2/confml/empty']})
+        
+        data = config.layered_resources(empty_folders=True, resource_type='implml').data
+        self.assertEquals(data, {'test.implml': ['layer1/implml/test.implml',
+                                                 'layer2/implml/test.implml'],
+                                 'empty':       ['layer1/implml/empty',
+                                                 'layer2/implml/empty']})
+        
+        data = config.layered_resources(empty_folders=True, resource_type='content').data
+        self.assertEquals(data, {'foo.txt': ['layer1/content/foo.txt',
+                                             'layer2/content/foo.txt'],
+                                 'empty':   ['layer1/content/empty',
+                                             'layer2/content/empty']})
+        
+        data = config.layered_resources(empty_folders=True, resource_type='doc').data
+        self.assertEquals(data, {'bar.txt': ['layer1/doc/bar.txt',
+                                             'layer2/doc/bar.txt'],
+                                 'empty':   ['layer1/doc/empty',
+                                             'layer2/doc/empty']})
+    
+    def test_layered_resources_specific_layers(self):
+        p = api.Project(api.Storage.open(LAYERED_RES_PROJECT))
+        config = p.get_configuration('root.confml')
+        
+        self.assertEquals(config.layered_resources(layers=[-1], resource_type='confml').data,
+                          {'test.confml': ['layer2/confml/test.confml']})
+        self.assertEquals(config.layered_resources(layers=[0], resource_type='confml').data,
+                          {'test.confml': ['layer1/confml/test.confml']})
+    
+    def test_layered_resources_shortcuts(self):
+        p = api.Project(api.Storage.open(LAYERED_RES_PROJECT))
+        config = p.get_configuration('root.confml')
+        
+        data = config.layered_confml().data
+        self.assertEquals(data, {'test.confml': ['layer1/confml/test.confml',
+                                                 'layer2/confml/test.confml']})
+        
+        data = config.layered_implml().data
+        self.assertEquals(data, {'test.implml': ['layer1/implml/test.implml',
+                                                 'layer2/implml/test.implml']})
+        
+        data = config.layered_content().data
+        self.assertEquals(data, {'foo.txt': ['layer1/content/foo.txt',
+                                             'layer2/content/foo.txt']})
+        
+        data = config.layered_doc().data
+        self.assertEquals(data, {'bar.txt': ['layer1/doc/bar.txt',
+                                             'layer2/doc/bar.txt']})
+        
+    
+    def test_implml_override(self):
+        p  = api.Project(api.Storage.open(LAYERED_RES_PROJECT))
+        config = p.get_configuration('root.confml')
+        
+        impl_set = plugin.get_impl_set(config)
+        self.assertEquals([impl.ref for impl in impl_set], ['layer2/implml/test.implml'])
+        
+        impl_set = plugin.filtered_impl_set(config)
+        self.assertEquals([impl.ref for impl in impl_set], ['layer2/implml/test.implml'])
+         
+    
     def test_create_configuration(self):
         conf = api.Configuration("foobar/testmee.confml")
         self.assertTrue(conf)
@@ -62,12 +184,13 @@
         config = p.get_configuration('root5.confml')
         view = config.get_default_view()
         print "Fealist %s." % len(view.list_all_features())
-        self.assertEquals(len(view.list_all_features()), 62)
+        self.assertEquals(len(view.list_all_features()), 99)
         for feaname in view.list_all_features():
             fea = view.get_feature(feaname)
             if fea.get_type() == 'sequence':
                 print "%s" % feaname,
-                print " = %s" % fea.get_value()
+                print "Value = %s" % fea.get_value()
+                print "RFS = %s" % fea.get_value(attr='rfs')
 
     def test_get_implml_container(self):
         fs = api.Storage.open(test_project)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/core/tests/unittest_configuration_project_edit_data.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,220 @@
+from __future__ import with_statement
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+import unittest
+import os
+
+from cone.public import api
+from cone.storage.filestorage import FileStorage
+from testautomation import unzip_file
+from testautomation.base_testcase import BaseTestCase
+
+ROOT_PATH       = os.path.dirname(os.path.abspath(__file__))
+TEMP_DIR        = os.path.join(ROOT_PATH, "temp/edit_data")
+TEST_CPF        = os.path.join(ROOT_PATH, "testdata/test_project.cpf")
+
+class open_config_and_get_dview(object):
+    def __init__(self, project, mode, config):
+        self.project_path = project
+        self.mode = mode
+        self.config = config
+        self.project = None
+
+    def __enter__(self):
+        self.project = api.Project(FileStorage(self.project_path, self.mode))
+        conf = self.project.get_configuration(self.config)
+        dview = conf.get_default_view()
+        return dview
+        setting = dview.get_feature(self.setting_ref)
+        return setting
+
+    def __exit__(self, type, value, tb):
+        if self.project:
+            if self.mode == 'a':
+                self.project.save()
+            self.project.close()
+
+class open_config_and_get_setting(open_config_and_get_dview):
+    def __init__(self, project, mode, config, setting):
+        open_config_and_get_dview.__init__(self, project, mode, config)
+        self.setting_ref = setting
+
+    def __enter__(self):
+        dview = open_config_and_get_dview.__enter__(self)
+        setting = dview.get_feature(self.setting_ref)
+        return setting
+
+class TestEditConfigurationProjectData(BaseTestCase):
+    
+    def test_edit_sequence_data_on_last_layer_with_dview(self):
+        PROJ = os.path.join(TEMP_DIR, "test_project_1")
+        CONF = 'root3.confml'
+        SETTING = 'Feature2.SequenceSetting'
+        unzip_file.unzip_file(TEST_CPF, PROJ, delete_if_exists=True)
+        
+        # Open the temp project in append mode
+        with open_config_and_get_setting(PROJ, 'a', CONF, SETTING) as setting:
+            self.assertEquals(setting.value,
+                [[333, 'layer3 (1)'],
+                 [1, 'default 1'],
+                 [2, 'default 2'],
+                 [222, 'layer2 (1)'],
+                 [222, 'layer2 (2)'],
+                 [222, 'layer2 (3)']])
+        
+            # Change the value
+            setting.value = [[123, 'foo1'],
+                             [456, 'foo2']]
+        
+        # Reopen the project in read mode and check that the sequence data
+        # was modified correctly
+        with open_config_and_get_setting(PROJ, 'r', CONF, SETTING) as setting:
+            self.assertEquals(setting.value,
+                              [[123, 'foo1'],
+                               [456, 'foo2']])
+            self.assertEquals(setting.get_original_value(),
+                              [['123', 'foo1'],
+                               ['456', 'foo2']])
+        
+        # Modify the sequence data again by setting it empty
+        with open_config_and_get_setting(PROJ, 'a', CONF, SETTING) as setting:
+            setting.value = []
+            self.assertEquals(setting.value, [])
+            self.assertEquals(setting.get_original_value(), [])
+        
+        # Reopen and check again
+        with open_config_and_get_setting(PROJ, 'r', CONF, SETTING) as setting:
+            self.assertEquals(setting.value, [])
+            self.assertEquals(setting.get_original_value(), [])
+        
+        # Do the same 'set empty' check with a more complex sequence setting
+        SETTING = 'SequenceSettingTest.SequenceSetting'
+        with open_config_and_get_setting(PROJ, 'a', CONF, SETTING) as setting:
+            setting.value = []
+            self.assertEquals(setting.value, [])
+            self.assertEquals(setting.get_original_value(), [])
+        with open_config_and_get_setting(PROJ, 'r', CONF, SETTING) as setting:
+            self.assertEquals(setting.value, [])
+            self.assertEquals(setting.get_original_value(), [])
+    
+    def test_edit_complex_sequence_data_on_last_layer_with_dview(self):
+        PROJ = os.path.join(TEMP_DIR, "test_project_4")
+        CONF = 'root3.confml'
+        SETTING = 'SequenceSettingTest.SequenceSetting'
+        unzip_file.unzip_file(TEST_CPF, PROJ, delete_if_exists=True)
+        
+        # Open the temp project in append mode
+        with open_config_and_get_setting(PROJ, 'a', CONF, SETTING) as setting:
+            self.assertEquals(setting.value,
+                [[['seq/layer2_folder2', None], 2.1000000000000001, ['seq/layer2_file2.txt', None], 222, 'L22', True, '1', ('opt 1', 'opt 3'), '\x22\x22'],
+                 [['seq/layer2_folder', None], 2.0, ['seq/layer2_file.txt', None], 22, 'L21', True, '2', ('opt 2',), '\x22\x11'],
+                 [['seq/def1_folder', None], 1.25, ['seq/def1_file.txt', None], 128, 'def1', False, '1', ('opt 1',), '\x00\x11'],
+                 [['seq/def2_folder', None], 1.5, ['seq/def2_file.txt', None], 256, 'def2', False, '1', ('opt 2',), '\x00\x22'],
+                 [['seq/layer3_folder', None], 3.0, ['seq/layer3_file.txt', None], 33, 'L31', False, '0', ('opt 3', 'opt 2'), '\x33\x11'],
+                 [['seq/layer3_folder', None], 3.3500000000000001, [None, None], 1, 'L32', True, '2', ('opt 1', 'opt 2'), '\x33\x22']])
+            
+            # Change the value
+            setting.value = [[['seq/foofolder1', None], 5.6, ['seq/foofile1.txt', None], 1010, 'Lfoo', False, '3', ('opt 4', 'opt 0'), '\xaa\xbb'],
+                             [['seq/foofolder2', None], 6.5, ['seq/foofile2.txt', None], 2020, 'Lfoo', True, '3', (), ''],
+                             [['seq/foofolder1', None], 5.6, ['seq/foofile1.txt', None], 1010, 'Lfoo', False, '3', ('opt 4', 'opt 0'), '\xaa\xbb']]
+        
+        with open_config_and_get_setting(PROJ, 'r', CONF, SETTING) as setting:
+            self.assertEquals(setting.value,
+                [[['seq/foofolder1', None], 5.6, ['seq/foofile1.txt', None], 1010, 'Lfoo', False, '3', ('opt 4', 'opt 0'), '\xaa\xbb'],
+                 [['seq/foofolder2', None], 6.5, ['seq/foofile2.txt', None], 2020, 'Lfoo', True, '3', (), ''],
+                 [['seq/foofolder1', None], 5.6, ['seq/foofile1.txt', None], 1010, 'Lfoo', False, '3', ('opt 4', 'opt 0'), '\xaa\xbb']])
+        # Modify the sequence data again by setting it empty
+        with open_config_and_get_setting(PROJ, 'a', CONF, SETTING) as setting:
+            setting.value = []
+        
+        # Reopen and check again
+        with open_config_and_get_setting(PROJ, 'r', CONF, SETTING) as setting:
+            self.assertEquals(setting.value, [])
+
+    def test_edit_data_on_last_layer_with_dview(self):
+        PROJ = os.path.join(TEMP_DIR, "test_project_2")
+        CONF = 'root3.confml'
+        unzip_file.unzip_file(TEST_CPF, PROJ, delete_if_exists=True)
+        
+        # Open the temp project in append mode
+        with open_config_and_get_dview(PROJ, 'a', CONF) as dview:
+            self.assertEquals(dview.get_feature('BasicSettingTypesTest.IntSetting').value,          333)
+            self.assertEquals(dview.get_feature('BasicSettingTypesTest.BooleanSetting').value,      False)
+            self.assertEquals(dview.get_feature('BasicSettingTypesTest.RealSetting').value,         3.1456)
+            self.assertEquals(dview.get_feature('BasicSettingTypesTest.SelectionSetting').value,    '3')
+            self.assertEquals(dview.get_feature('BasicSettingTypesTest.StringSetting').value,       'layer 3 string')
+            self.assertEquals(dview.get_feature('BasicSettingTypesTest.MultiSelectionSetting').value, ('opt 1', 'opt 3'))
+            self.assertEquals(dview.get_feature('BasicSettingTypesTest.HexBinarySetting').value, '\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff')
+        
+            dview.get_feature('BasicSettingTypesTest.IntSetting').value         = 1500
+            dview.get_feature('BasicSettingTypesTest.BooleanSetting').value     = True
+            dview.get_feature('BasicSettingTypesTest.RealSetting').value        = 15.15
+            dview.get_feature('BasicSettingTypesTest.SelectionSetting').value   = '1'
+            dview.get_feature('BasicSettingTypesTest.StringSetting').value      = 'edit data test'
+            dview.get_feature('BasicSettingTypesTest.MultiSelectionSetting').value = ('opt 4', 'opt 0')
+            dview.get_feature('BasicSettingTypesTest.HexBinarySetting').value = '\x12\x34'
+        
+        # Reopen the project in read mode and check that the sequence data
+        # was modified correctly
+        with open_config_and_get_dview(PROJ, 'r', CONF) as dview:
+            self.assertEquals(dview.get_feature('BasicSettingTypesTest.IntSetting').value,          1500)
+            self.assertEquals(dview.get_feature('BasicSettingTypesTest.BooleanSetting').value,      True)
+            self.assertEquals(dview.get_feature('BasicSettingTypesTest.RealSetting').value,         15.15)
+            self.assertEquals(dview.get_feature('BasicSettingTypesTest.SelectionSetting').value,    '1')
+            self.assertEquals(dview.get_feature('BasicSettingTypesTest.StringSetting').value,       'edit data test')
+            self.assertEquals(dview.get_feature('BasicSettingTypesTest.MultiSelectionSetting').value, ('opt 4', 'opt 0'))
+            self.assertEquals(dview.get_feature('BasicSettingTypesTest.HexBinarySetting').value, '\x12\x34')
+        
+        # Test that setting the multi-selection setting to empty works
+        SETTING = 'BasicSettingTypesTest.MultiSelectionSetting'
+        with open_config_and_get_setting(PROJ, 'a', 'root4.confml', SETTING) as setting:
+            self.assertEquals(setting.value, ('opt 0', 'opt 4'))
+            setting.value = ()
+            self.assertEquals(setting.value, ())
+        with open_config_and_get_setting(PROJ, 'r', 'root4.confml', SETTING) as setting:
+            self.assertEquals(setting.value, ())
+    
+    def test_read_name_id_mapped_values(self):
+        PROJ = os.path.join(TEMP_DIR, "test_project_5")
+        CONF = 'root3.confml'
+        unzip_file.unzip_file(TEST_CPF, PROJ, delete_if_exists=True)
+        
+        with open_config_and_get_dview(PROJ, 'r', CONF) as dview:
+            def check(setting, expected_value):
+                fea = dview.get_feature('NameIdMappingTestTargetSettings.' + setting)
+                self.assertEquals(fea.get_value(), expected_value)
+            
+            check('Selection',       'seq1_item2')
+            check('Selection2',      12)
+            check('MultiSelection',  ('seq1_item1', 'seq1_item2', 'seq2_item2', 'seq2_item3'))
+            check('MultiSelection2', (11, 12, True, False))
+            check('String',          'seq1_item2')
+            check('Int',             12)
+            check('Real',            1.2)
+            check('Boolean',         False)
+            
+            check('Sequence.Selection',       ['seq1_item2'])
+            check('Sequence.Selection2',      [12])
+            check('Sequence.MultiSelection',  [('seq1_item1', 'seq1_item2', 'seq2_item2', 'seq2_item3')])
+            check('Sequence.MultiSelection2', [(11, 12, True, False)])
+            check('Sequence.String',          ['seq1_item2'])
+            check('Sequence.Int',             [12])
+            check('Sequence.Real',            [1.2])
+            check('Sequence.Boolean',         [False])
+
+if __name__ == '__main__':
+    unittest.main()
--- a/configurationengine/source/cone/core/tests/unittest_configuration_project_export.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/core/tests/unittest_configuration_project_export.py	Tue Aug 10 14:29:28 2010 +0300
@@ -22,8 +22,6 @@
 import sys,os,shutil
 import difflib, zipfile
 
-import __init__
-
 from cone.public import exceptions,utils, api
 from cone.storage.filestorage import FileStorage
 from cone.storage.zipstorage import ZipStorage
@@ -184,17 +182,17 @@
 #        except exceptions.NotSupportedException:
 #            pass
 
-    def test_export_to_filestorage_multiple_configurations(self):
+    def _test_export_to_filestorage_multiple_configurations(self):
         fs = FileStorage(datafolder)
         p  = api.Project(fs)
-        fs2 = FileStorage("temp/exported","w")
+        fs2 = FileStorage(os.path.join(temp_dir,"multiple"),"w")
         p2  = api.Project(fs2)
         conf = p.get_configuration('morestuff.confml')
         conf_files = conf.list_resources()
         p.export_configuration(conf,fs2)
         conf = p.get_configuration('prodX.confml')
         conf_files.extend(conf.list_resources())
-        
+        fs2.save()
         p.export_configuration(conf,fs2)
         p2.close()
         self.assertTrue(os.path.exists("temp/exported"))
@@ -204,8 +202,8 @@
         files.sort()
         conf_files.append('.metadata')
         conf_files.sort()
-        self.assertEquals(conf_files,files)
-        shutil.rmtree("temp")
+        self.assertEquals(sorted(conf_files),sorted(files))
+        #shutil.rmtree("temp")
 
         
 
--- a/configurationengine/source/cone/core/tests/unittest_configuration_project_import.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/core/tests/unittest_configuration_project_import.py	Tue Aug 10 14:29:28 2010 +0300
@@ -32,7 +32,6 @@
         except ImportError:
             from xml.etree import ElementTree
             
-import __init__
 from testautomation import unzip_file
 
 from cone.public import exceptions, utils, api
@@ -115,7 +114,7 @@
         p2.import_configuration(conf)
         p2.close()
         self.assertTrue(os.path.exists("temp/imported"))
-        files = fs2.list_resources("/",True)
+        files = fs2.list_resources("/",recurse=True)
         
         conf_files = utils.distinct_array(conf_files)
         conf_files.append('.metadata')
@@ -136,7 +135,7 @@
         p.close()
         self.assertTrue(os.path.exists(imported_folder))
         store = api.Storage.open(imported_folder)
-        files = store.list_resources('',True)
+        files = store.list_resources('',recurse=True)
         conf_files.sort()
         files.sort()
         self.assertEquals(conf_files,files)
--- a/configurationengine/source/cone/core/tests/unittest_configuration_project_on_filestorage.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/core/tests/unittest_configuration_project_on_filestorage.py	Tue Aug 10 14:29:28 2010 +0300
@@ -21,7 +21,6 @@
 import string
 import sys,os
 import shutil
-import __init__
 from testautomation.base_testcase import BaseTestCase
 
 from cone.public import exceptions, api
@@ -57,7 +56,7 @@
     def test_list_configurations(self):
         confs =  self.project.list_configurations()
         self.assertTrue(confs)
-        self.assertEquals(confs[0],"morestuff.confml")
+        self.assertEquals(sorted(confs), sorted(['morestuff.confml', 'prodX.confml', 'simple.confml']))
 
     def test_get_configuration(self):
         conf =  self.project.get_configuration("morestuff.confml")
@@ -75,8 +74,10 @@
         conf =  self.project.get_configuration("morestuff.confml")
         layers = conf.list_configurations()
         self.assertTrue(layers)
-        self.assertEquals(layers[0],'platform/s60/root.confml')
-        self.assertEquals(layers[1],'familyX/root.confml')
+        self.assertEquals(sorted(layers),
+                          sorted(['platform/s60/root.confml',
+                                  'familyX/root.confml',
+                                  'familyX/prodX/root.confml']))
 
     def test_get_is_configuration(self):
         self.assertTrue(self.project.is_configuration("morestuff.confml"))
@@ -126,19 +127,20 @@
     def test_get_all_resources(self):
         conf =  self.project.get_configuration("morestuff.confml")
         resources = conf.get_all_resources()
-        self.assertEquals(resources[0].get_path(),'morestuff.confml')
-        self.assertEquals(resources[1].get_path(),'platform/s60/root.confml')
+        paths = [r.get_path() for r in resources]
+        self.assertTrue('morestuff.confml' in paths)
+        self.assertTrue('platform/s60/root.confml' in paths)
 
     def test_list_confmls(self):
         conf =  self.project.get_configuration("morestuff.confml")
         confmls = conf.list_resources()
-        self.assertEquals(confmls[0],'morestuff.confml')
-        self.assertEquals(confmls[1],'platform/s60/root.confml')
+        self.assertTrue('morestuff.confml' in confmls )
+        self.assertTrue('platform/s60/root.confml' in confmls)
     
     def test_list_implmls(self):
         conf =  self.project.get_configuration("morestuff.confml")
         implmls = conf.get_configuration('platform/s60/root.confml').get_layer().list_implml()
-        self.assertEquals(implmls[0],'implml/accessoryserver_1020505A.crml')
+        self.assertTrue('implml/accessoryserver_1020505A.crml' in implmls)
 
 #    def test_list_content(self):
 #        conf =  self.project.get_configuration("morestuff.confml")
--- a/configurationengine/source/cone/core/tests/unittest_configuration_project_on_zipstorage.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/core/tests/unittest_configuration_project_on_zipstorage.py	Tue Aug 10 14:29:28 2010 +0300
@@ -20,7 +20,6 @@
 import unittest
 import string
 import sys,os, shutil
-import __init__
 
 from cone.public import exceptions, api
 from cone.core import *
--- a/configurationengine/source/cone/public/_etree_wrapper.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/public/_etree_wrapper.py	Tue Aug 10 14:29:28 2010 +0300
@@ -32,8 +32,11 @@
     def get_lineno(self, element):
         raise NotImplementedError()
 
+    def get_elem_from_lineno(self, root, lineno):
+        raise NotImplementedError()
+
 class ElementTreeBackendWrapper(ElementTreeBackendWrapperBase):
-    
+
     class CustomTreeBuilder(ElementTree.TreeBuilder):
         """
         Custom TreeBuilder for ElementTree that records line numbers
@@ -42,7 +45,7 @@
         def start(self, tag, attrs):
             elem = ElementTree.TreeBuilder.start(self, tag, attrs)
             lineno = self._xmltreebuilder._parser.CurrentLineNumber
-            #print "Tag: %s, line: %r" % (tag, lineno)
+            # print "Tag: %s, line: %r" % (tag, lineno)
             elem.sourceline = lineno
             return elem
     
@@ -55,7 +58,8 @@
             parser = ElementTree.XMLTreeBuilder(target=treebuilder)
             treebuilder._xmltreebuilder = parser
             parser.feed(text)
-            return parser.close()
+            self.root = parser.close()
+            return self.root
         except expat.ExpatError, e:
             raise exceptions.XmlParseError(
                 "XML parse error on line %d: %s" % (e.lineno, e),
@@ -65,8 +69,16 @@
         return ElementTree.tostring(etree, encoding)
     
     def get_lineno(self, element):
-        return element.sourceline
+        try:
+            return element.sourceline
+        except AttributeError:
+            return None
 
+    def get_elem_from_lineno(self, root, lineno):
+        for elem in root.getiterator():
+            if elem.sourceline == lineno:
+                return elem
+        return None
 
 class CElementTreeBackendWrapper(ElementTreeBackendWrapperBase):
     def __init__(self):
@@ -82,7 +94,8 @@
     
     def fromstring(self, text):
         try:
-            return self.cElementTree.fromstring(text)
+            self.root = self.cElementTree.fromstring(text)
+            return self.root
         except SyntaxError, e:
             # cElementTree raises a SyntaxError, but does not set
             # its lineno attribute, so look for the line number
@@ -103,6 +116,9 @@
         # cElementTree does not support line numbers
         return None
 
+    def get_elem_from_lineno(self, root, lineno):
+        # cElementTree does not support line numbers
+        return None
 
 class LxmlBackendWrapper(ElementTreeBackendWrapperBase):
     
@@ -115,39 +131,48 @@
     
     def fromstring(self, text):
         try:
-            elem = self.lxml.etree.fromstring(text)
-            
-            # lxml parses also comments, but ConE does not expect those,
-            # so remove them to prevent any errors on that account
-            def remove_comments(elem):
-                # Find the comments under this element
-                comments = []
-                for x in elem:
-                    if isinstance(x, self.lxml.etree._Comment):
-                        comments.append(x)
-                
-                # Remove them
-                for c in comments:
-                    elem.remove(c)
-                
-                # Recurse to sub-elements
-                for subelem in elem:
-                    remove_comments(subelem)
-            
-            remove_comments(elem)
-            
-            return elem
+            self.root = self.lxml.etree.fromstring(text)
+            self.remove_comments(self.root)
+            return self.root
         except self.lxml.etree.XMLSyntaxError, e:
             raise exceptions.XmlParseError(
                 "XML parse error on line %d: %s" % (e.position[0], e),
                 e.position[0], str(e))
     
+    def remove_comments(self, elem):
+        """
+        lxml parses also comments, but ConE does not expect those,
+        so remove them to prevent any errors on that account
+        """
+        # Find the comments under this element
+        comments = []
+        for x in elem:
+            if isinstance(x, self.lxml.etree._Comment):
+                comments.append(x)
+        
+        # Remove them
+        for c in comments:
+            elem.remove(c)
+        
+        # Recurse to sub-elements
+        for subelem in elem:
+            self.remove_comments(subelem)
+            
     def tostring(self, etree, encoding=None):
         return self.lxml.etree.tostring(etree, encoding=encoding)
     
     def get_lineno(self, element):
-        return element.sourceline
+        try:
+            return element.sourceline
+        except AttributeError:
+            return None
 
+    def get_elem_from_lineno(self, root, lineno):
+        for elem in root.getiterator():
+            if elem.sourceline == lineno:
+                return elem
+        return None
+    
 # ============================================================================
 #
 # ============================================================================
@@ -167,7 +192,8 @@
     # Import order for the default back-end. The list is traversed
     # top-down and the first back-end whose importing is successful is
     # used as the default back-end
-    DEFAULT_BACKEND_IMPORT_ORDER = [BACKEND_C_ELEMENT_TREE,
+    DEFAULT_BACKEND_IMPORT_ORDER = [BACKEND_LXML,
+                                    BACKEND_C_ELEMENT_TREE,
                                     BACKEND_ELEMENT_TREE]
     
     _backend_mapping = {BACKEND_ELEMENT_TREE:     ElementTreeBackendWrapper,
@@ -229,6 +255,18 @@
         """
         return self._get_backend().get_lineno(element)
     
+    def get_elem_from_lineno(self, root, lineno):
+        """
+        Return the element from the given line number of the given XML element.
+        
+        @param root: the root element to search from
+        @param lineno: the line number to search for  
+        
+        Note that for the cElementTree parser this will always return
+        None, since that parser does not support line numbers.
+        """
+        return self._get_backend().get_elem_from_lineno(root, lineno)
+
     def __getattribute__(self, attrname):
         try:
             # Try to get the attribute from this object (the top-level wrapper)
--- a/configurationengine/source/cone/public/_plugin_reader.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/public/_plugin_reader.py	Tue Aug 10 14:29:28 2010 +0300
@@ -16,7 +16,8 @@
 
 import copy
 import logging
-import plugin, exceptions, api, utils
+from cone.public import exceptions, api, utils
+import plugin
 import cone.confml.model
 
 log = logging.getLogger('cone')
@@ -33,10 +34,11 @@
     Class representing a temporary variable definition in an implementation file.
     """
     
-    def __init__(self, ref, type, value):
+    def __init__(self, ref, type, value, lineno=None):
         self.ref = ref
         self.type = type
         self.value = value
+        self.lineno = lineno
     
     def create_feature(self, config):
         """
@@ -54,7 +56,8 @@
                    'int'    : cone.confml.model.ConfmlIntSetting,
                    'real'   : cone.confml.model.ConfmlRealSetting,
                    'boolean': cone.confml.model.ConfmlBooleanSetting}
-        feature = mapping[self.type](ref)
+        # Create temp variables always name being also the ref
+        feature = mapping[self.type](ref, name=ref)
         setattr(feature, TEMP_FEATURE_MARKER_VARNAME, True)
         config.add_feature(feature, namespace)
         
@@ -81,9 +84,10 @@
     Class representing a temporary variable sequence definition in an implementation file.
     """
     
-    def __init__(self, ref, sub_items):
+    def __init__(self, ref, sub_items, lineno=None):
         self.ref = ref
         self.sub_items = sub_items
+        self.lineno = lineno
     
     def create_feature(self, config):
         if '.' in self.ref:
@@ -95,7 +99,8 @@
             namespace = ''
         
         # Creature the sequence feature
-        seq_fea = api.FeatureSequence(ref)
+        # Create temp variables always name being also the ref
+        seq_fea = api.FeatureSequence(ref, name=ref)
         setattr(seq_fea, TEMP_FEATURE_MARKER_VARNAME, True)
         config.add_feature(seq_fea, namespace)
         
@@ -106,7 +111,7 @@
                    'boolean': cone.confml.model.ConfmlBooleanSetting}
         sub_features = []
         for sub_item in self.sub_items:
-            sub_feature = mapping[sub_item[1]](sub_item[0])
+            sub_feature = mapping[sub_item[1]](sub_item[0], name=sub_item[0])
             seq_fea.add_feature(sub_feature)
     
     def __eq__(self, other):
@@ -183,11 +188,13 @@
         """
         Extend this object with the contents of another CommonImplmlData object.
         """
+        if other is None:
+            return
+        
         if other.phase:
             self.phase = other.phase
         if other.tags:
             self.tags = other.tags
-        self.tempvar_defs.extend(other.tempvar_defs)
         if other.setting_refs_override:
             self.setting_refs_override = other.setting_refs_override
         if other.output_root_dir:
@@ -198,7 +205,7 @@
     def copy(self):
         result = CommonImplmlData()
         result.phase = self.phase
-        if result.tags is not None:
+        if self.tags is not None:
             result.tags = self.tags.copy()
         result.tempvar_defs = list(self.tempvar_defs)
         result.setting_refs_override = copy.deepcopy(self.setting_refs_override)
@@ -453,8 +460,7 @@
     def read_data(cls, etree):
         """
         Read common ImplML data from the given XML element.
-        @return: A CommonImplmlData instance or None if no common namespace
-            elements were found.
+        @return: A CommonImplmlData instance.
         """
         result = CommonImplmlData()
         
@@ -466,17 +472,14 @@
                           'outputRootDir'           : cls._read_output_root_dir,
                           'outputSubDir'            : cls._read_output_sub_dir}
         
-        found = False
         for elem in etree:
             ns, tag = utils.xml.split_tag_namespace(elem.tag)
             if ns != COMMON_IMPLML_NAMESPACE:   continue
             if tag not in reader_methods:       continue
             
             reader_methods[tag](elem, result)
-            found = True
         
-        if found:   return result
-        else:       return None
+        return result
     
     @classmethod
     def _read_phase(cls, elem, result):
@@ -502,13 +505,14 @@
         ref = elem.get('ref')
         type = elem.get('type', 'string')
         value = elem.get('value', '')
+        lineno = utils.etree.get_lineno(elem)
         
         if ref is None:
             cls._raise_missing_attr(elem, 'ref')
         if type not in cls.VALID_TYPES:
             cls._raise_invalid_type(ref, type)
         
-        result.tempvar_defs.append(TempVariableDefinition(ref, type, value))
+        result.tempvar_defs.append(TempVariableDefinition(ref, type, value, lineno))
     
     @classmethod
     def _read_tempvarseq(cls, elem, result):
@@ -531,7 +535,9 @@
         if not sub_items:
             raise exceptions.ParseError("Temporary variable sequence '%s' does not have any sub-items" % ref)
         
-        result.tempvar_defs.append(TempVariableSequenceDefinition(ref, sub_items))
+        lineno = utils.etree.get_lineno(elem)
+        
+        result.tempvar_defs.append(TempVariableSequenceDefinition(ref, sub_items, lineno))
     
     @classmethod
     def _read_setting_refs_override(cls, elem, result):
--- a/configurationengine/source/cone/public/api.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/public/api.py	Tue Aug 10 14:29:28 2010 +0300
@@ -1,3 +1,4 @@
+from __future__ import with_statement
 #
 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
 # All rights reserved.
@@ -18,14 +19,15 @@
 The core interface to the ConE functionality.
 """
 
-import os
 import re
 import sys
 import logging
-import copy
-import sets
-
-import exceptions, utils, container, mapping
+import mimetypes
+
+from cone.public import exceptions, utils, container, mapping
+
+def get_file_logger():
+    return logger
 
 class Base(container.ObjectContainer):
     """
@@ -38,14 +40,34 @@
             raise exceptions.InvalidRef("Invalid reference for Base object %s!" % ref)
         self.ref = ref
         container.ObjectContainer.__init__(self, ref)
-        for arg in kwargs.keys():
-            if kwargs.get(arg) != None:
-                setattr(self, arg, kwargs.get(arg))
-
+        try:
+            for arg in kwargs.keys():
+                if kwargs.get(arg) != None:
+                    setattr(self, arg, kwargs.get(arg))
+        except AttributeError,e:
+            raise e
+        
     def __repr__(self):
         dict = self._dict()
         return "%s(%s)" % (self.__class__.__name__, dict)
 
+#    def __reduce_ex__(self, protocol_version):
+#        tpl = super(Base, self).__reduce_ex__(protocol_version)
+#        return tpl
+
+#    def __getstate__(self):
+#        state = self._dict(internals=True, ignore_empty=True)
+#        # pop out the _name so that it wont appear as redundant data (ref is the same)
+#        state.pop('_name', None)
+#        state.pop('_parent', None)
+#        return state
+#
+#    def __setstate__(self, state):
+#        super(Base, self).__setstate__(state)
+#        self.ref = state.get('ref','')
+#        for arg in state.keys():
+#            self.__dict__.setdefault(arg, state.get(arg))
+        
     def _get_mapper(self,modelname):
         """
         Return a instance of appropriate mapper for given model.
@@ -108,16 +130,23 @@
                     obj._add(child._clone(**kwargs), container.APPEND)
         return obj
 
-    def _dict(self):
+    def _dict(self, **kwargs):
         """
         Return the public variables in a dictionary
         """
         dict = {}
-        for key in self.__dict__.keys():
-            if key.startswith('_'):
+        # loop through the items in this object internal __dict__
+        # and add all except internal variables and function overrides  
+        for (key,value) in self.__dict__.items():
+            if not kwargs.get('internals', False) and key.startswith('_'):
                 continue
+            elif not kwargs.get('callables', False) and callable(value):
+                continue
+            elif kwargs.get('ignore_empty') and not value:
+                # ignore empty values
+                pass
             else:
-                dict[key] = self.__dict__[key]
+                dict[key] = value
         return dict
 
     def _default_object(self, name):
@@ -152,6 +181,27 @@
         paths.reverse()
         return utils.dottedref.join_refs(paths)
 
+    def path(self, toparent=None):
+        """
+        Get the path to this Base object..
+        @param toparent: the _parent object up to which the path is relative. Default value is None.,
+        which gives the fully qualified path in the topology.
+        @return: The path to this Base object from toparent
+        """
+        return self._path(toparent)
+
+    def parent_path(self, toparent=None):
+        """
+        Get the path to the parent of this Base object..
+        @param toparent: the _parent object up to which the path is relative. Default value is None.,
+        which gives the fully qualified path in the topology.
+        @return: The path to this Base object from toparent
+        """
+        if self._parent != None:
+            return self._parent.path(toparent)
+        else:
+            return ''
+
     def get_fullref(self):
         """
         Return a full reference, reference including a 
@@ -240,6 +290,23 @@
         else:
             return None
 
+    def get_configuration(self):
+        """
+        Return the containing configuration of this object.
+        """
+        parent = self._find_parent_or_default(type=Configuration)
+        return parent
+
+    def get_configuration_path(self):
+        """
+        Return the path of containing configuration of this object.
+        """
+        parent = self._find_parent_or_default(type=Configuration)
+        try:
+            return parent.get_full_path()
+        except AttributeError:
+            return None
+    
     def get_index(self):
         """
         @return : the index of the data element for sequential data defined inside the same configuration.
@@ -293,6 +360,27 @@
         """
         return None
 
+    def get_store_interface(self):
+        # if the project cannot be retrieved return None
+        try:
+            return self.get_project()
+        except exceptions.NotFound:
+            return None
+    
+    def get_id(self): 
+        try:
+            return self._id
+        except AttributeError:
+            return None
+
+    def set_id(self,value): 
+        self._id = value
+
+    def del_id(self): 
+        delattr(self,'_id')
+
+    """ The id as a property """
+    id = property(get_id,set_id, del_id)
 
 class Project(Base):
     """
@@ -309,10 +397,17 @@
             self._model = storage.persistentmodule.MODEL
         except AttributeError:
             self._model = None
-        
+        self.loaded = {}
         self.set_storage(storage)
         self.update()
-        self.loaded = {}
+
+    def __getstate__(self):
+        state = {}
+        state['storage'] = self.storage
+        return state
+
+    def __setstate__(self, state):
+        self.__init__(state['storage'])
 
     def __add_loaded__(self, ref, obj):
         """
@@ -353,8 +448,10 @@
                 return True
             else: 
                 return False
-        else: 
-            return True
+        else:
+            # Return False in case the object is loaded at all in this project 
+            # increases performance as unloading is not done on unchanged objects
+            return False
         
     def _supported_type(self, obj):
         if isinstance(obj, Configuration) \
@@ -383,10 +480,9 @@
         """
         Set the Storage instance of this Project.
         """
-        if isinstance(storage, Storage):
-            self.storage = storage
-        else:
+        if storage != None and not isinstance(storage, Storage):
             raise exceptions.StorageException("The given storage is not a instance of Storage!")
+        self.storage = storage
 
     def list_configurations(self, filter_or_filters=None):
         """
@@ -418,7 +514,9 @@
         List all configuration objects of the project (all configurations)
         @return: a list for configuration file paths
         """
-        return [obj.get_path() for obj in self._traverse(type=(Configuration, ConfigurationProxy))]
+        # TODO
+        # huge performance problem 
+        return [obj.get_full_path() for obj in self._traverse(type=(Configuration, ConfigurationProxy))]
 
     def get_configuration(self, path):
         """
@@ -445,27 +543,44 @@
         """
         # Changed from list_all_configurations to list_configurations
         # (list_all_configurations causes a insane performance problem with _traverse)
-        return path in self.list_configurations()
-
-    def add_configuration(self, config):
+        #
+        try:
+            return self.storage.is_resource(path)
+        except exceptions.NotSupportedException:
+            return path in self.list_configurations()
+        
+    def add_configuration(self, config, overwrite_existing=False):
         """
         Add a Configuration object to this project
-        """
+        @param config: The configuration object to add
+        @param overwrite_existing: When this is set true any existing configuration is 
+        overwritten. 
+        """ 
         if isinstance(config, Configuration):
-            if self.is_configuration(config.get_path()):
+            if not overwrite_existing and self.is_configuration(config.get_path()):
                 raise exceptions.AlreadyExists("%s" % config.get_path())
-            self._add(config)
+            
+            proxy = ConfigurationProxy(config.path)
+            proxy._set_obj(config)
+            self._add(proxy)
+            #self._add(config)
             self.__add_loaded__(config.get_path(), config)
             self.__loaded__(config.get_path())
         else:
             raise exceptions.IncorrectClassError("Only Configuration instance can be added to Project!")
 
-    def create_configuration(self, path, namespace=""):
+    def create_configuration(self, path, overwrite_existing=False, **kwargs):
         """
         Create a Configuration object to this project
-        """
-        config = self.get_configuration_class()(utils.resourceref.norm(path), namespace=namespace)
-        self.add_configuration(config)
+        @param path: The path of the new configuration file
+        @param overwrite_existing: When this is set true any existing configuration is 
+        overwritten. 
+        @param **kwargs: normal keyword arguments that are passed on to the newly 
+        created Configuration object. See Configuration object constructor description on what
+        you can pass on here.  
+        """
+        config = self.get_configuration_class()(utils.resourceref.norm(path), **kwargs)
+        self.add_configuration(config, overwrite_existing)
         return config
 
     def remove_configuration(self, path):
@@ -487,7 +602,7 @@
         self.storage.import_resources(configuration.list_resources(), configuration.get_storage())
         return
 
-    def export_configuration(self, configuration, export_storage, empty_folders=False):
+    def export_configuration(self, configuration, export_storage, **kwargs):
         """
         Export a configuration object to another storage
         """
@@ -504,8 +619,9 @@
         #l = []
         cpath = utils.resourceref.get_path(configuration.get_path()) 
         resr = [utils.resourceref.join_refs([cpath,related]) \
-                for related in configuration.get_layer().list_all_related(empty_folders)]        
-        self.storage.export_resources(resr ,export_storage, empty_folders)
+                for related in configuration.get_layer().list_all_related(**kwargs)]
+        
+        self.storage.export_resources(resr ,export_storage, kwargs.get("empty_folders", False))
         return
 
     def get_configuration_class(self):
@@ -545,7 +661,7 @@
         if not self.__get_loaded__(path):
             configuration = self.get_storage().load(path)
             if configuration.get_ref() == 'unknown':
-                 configuration.set_ref(utils.resourceref.to_dref(path))
+                configuration.set_ref(utils.resourceref.to_dref(path))
             self.__add_loaded__(path, configuration)
         """ increase the ref counter """
         self.__loaded__(path)
@@ -560,6 +676,15 @@
         """
         if self.__unloaded__(path):
             self.get_storage().unload(path, object)
+            # remove the configuration from this this project, 
+            # with proxy set the _obj reference to None
+            try:
+                conf =  self.get_configuration(path)
+                if isinstance(conf, ConfigurationProxy):
+                    conf._set_obj(None)
+            except exceptions.NotFound:
+                # if the configuration is not found at all then ignore the resetting
+                pass
 
     def get_path(self):
         """
@@ -578,6 +703,9 @@
         super(CompositeConfiguration, self).__init__(ref, **kwargs)
         self.container = True
 
+    def _configuration_class(self):
+        return Configuration
+
     def add_configuration(self, config):
         """
         Add an existing Configuration to this configuration
@@ -587,9 +715,23 @@
         """
         Merge the default view features from added config to this configs _default_view.
         """
-        self._add(config)
-
-    def include_configuration(self, configref):
+        # if the Configuration has a separate resource path, add it automatically behind proxy 
+        if utils.resourceref.is_path(config.path) and isinstance(config, Configuration):
+            proxy = ConfigurationProxy(config.path)
+            proxy._set_obj(config)
+            self._add(proxy)
+            # Add the new configuration to the list of "modified/loaded" configurations
+            try:
+                prj = self.get_project()
+                prj.__add_loaded__(config.get_full_path(), config)
+                prj.__loaded__(config.get_full_path())
+            except exceptions.NotFound:
+                # if the parent is not found this configuration is not (yet) a part of project and cant be stored 
+                pass
+        else:
+            self._add(config)
+
+    def include_configuration(self, configref, policy=0):
         """
         Add an existing Configuration to this configuration by its resource reference
         @param config: A Configuration instance:
@@ -597,7 +739,7 @@
         """
         # add the configuration load proxy to this configuration instead 
         # adding the configuration directly
-        self._add(ConfigurationProxy(configref))
+        self._add(ConfigurationProxy(configref), policy)
 
     def create_configuration(self, path):
         """
@@ -611,11 +753,9 @@
         """
         # normalise the path
         normpath = utils.resourceref.norm(path)
-        cklass = self.get_configuration_class()
+        cklass = self._configuration_class()
         conf = cklass(normpath, namespace=self.namespace)
-        proxy = ConfigurationProxy(normpath)
-        self.add_configuration(proxy)
-        proxy._set_obj(conf)
+        self.add_configuration(conf)
         return conf
 
     def remove_configuration(self, path):
@@ -636,9 +776,7 @@
         List all Layer objects in the Configuration
         @return: a copy array of layer references.
         """
-        # TODO
-        # huge performance problem 
-        return [config.get_path() for config in self._traverse(type=(Configuration, ConfigurationProxy))] 
+        return [config.get_path_for_parent(self) for config in self._traverse(type=(Configuration, ConfigurationProxy))] 
 
     def get_configuration(self, path):
         """
@@ -667,17 +805,6 @@
         except IndexError:
             return self 
 
-    def get_configuration_class(self):
-        """
-        return the default configuration class retrieved from the project if it is found.
-        Otherwise return cone.public.api.Configuration. 
-        """
-        try:
-            return self.get_project().get_configuration_class()
-        # catch the Parent/Project NotFound exception
-        except exceptions.NotFound:
-            return Configuration
-
     def add(self, child, policy=container.REPLACE):
         """
         A generic add function to add child objects. The function is intended to act as
@@ -690,18 +817,41 @@
         if isinstance(child, Configuration):
             self.add_configuration(child)
         elif isinstance(child, ConfigurationProxy):
-            self.add_configuration(child)
+            self._add(child)
         elif isinstance(child, Base):
             self._add(child)
         else:
             raise exceptions.IncorrectClassError("Cannot add %s to %s" % (child, self))
 
-    def layered_content(self, layers=None):
-        """
-        fetch content from first to last and override content 
-        if it is found from a later layer 
-        Create an array of the layers based on the layer indexes.
-        """
+    def layered_resources(self, layers=None, empty_folders=False, folder=None, resource_type=None):
+        """
+        Fetch resource paths by layers so that if a resource with the same name
+        exists on multiple layers, the one on the latest layer is the active one.
+        @param layers: List of layer indices to specify the layer to use, None
+            for all layers.
+        @param empty_folders: If True, empty folders are returned also.
+        @param folder: Name of a specific folder from which to get resources, or None.
+            If None, resource_type must be specified.
+        @param resource_type: Type of the resources to find. Must be one of
+            ('confml', 'implml', 'content', 'doc') or None.
+            If None, folder must be specified.
+        @return: A container.DataContainer instance containing the resource paths.
+            For example: {'foo.txt': ['layer1/content/foo.txt',
+                                      'layer2/content/foo.txt'],
+                          'bar.txt': ['layer1/content/bar.txt']}
+        """
+        MAPPING = {'confml':    lambda layer: layer.confml_folder(),
+                   'implml':    lambda layer: layer.implml_folder(),
+                   'content':   lambda layer: layer.content_folder(),
+                   'doc':       lambda layer: layer.doc_folder()}
+        if resource_type is not None and resource_type not in MAPPING:
+            raise ValueError("Invalid resource type %r, should be one of %r" % (resource_type, MAPPING.keys()))
+        
+        if folder and resource_type:
+            raise ValueError('Only one of folder and resource_type must be specified!')
+        if not folder and not resource_type:
+            raise ValueError('Either folder or resource_type must be specified!')
+        
         configuration_array = []
         if layers == None:
             configuration_array = self.list_configurations()
@@ -709,18 +859,43 @@
             all = self.list_configurations()
             for i in layers:
                 configuration_array.append(all[i])
-
-        content = container.DataContainer()
+        
+        # Add the current configuration as the last one in the list, in case
+        # the current configuration happens to be a layer root itself
+        configuration_array.append('')
+        
+        # Set up the get_folder function based on the parameters
+        if resource_type:
+            get_folder = MAPPING[resource_type]
+        else:
+            def get_folder(layer):
+                cpath = layer.get_current_path()
+                return Folder(layer.storage, utils.resourceref.join_refs([cpath, folder]))
+        
+        result = container.DataContainer()
         for configuration_path in configuration_array:
-            content_folder = self.get_configuration(configuration_path).get_layer().content_folder()
-            content_path = content_folder.get_current_path()
-            for content_file in content_folder.list_resources("", True):
-                source_file = utils.resourceref.join_refs([content_path, content_file])
-                content.add_value(content_file, source_file)
-                
-        return content
-
-
+            folder_obj = get_folder(self.get_configuration(configuration_path).get_layer())
+            folder_path = folder_obj.get_current_path()
+            for res_path in folder_obj.list_resources("", recurse=True, empty_folders=empty_folders):
+                if res_path == '': continue # ZipStorage sometimes returns empty paths
+                res_fullpath = utils.resourceref.join_refs([folder_path, res_path])
+                result.add_value(res_path, res_fullpath)
+        return result
+    
+    def layered_confml(self, layers=None, empty_folders=False):
+        return self.layered_resources(layers, empty_folders, resource_type='confml')
+    
+    def layered_implml(self, layers=None, empty_folders=False):
+        return self.layered_resources(layers, empty_folders, resource_type='implml')
+    
+    def layered_content(self, layers=None, empty_folders=False):
+        return self.layered_resources(layers, empty_folders, resource_type='content')
+    
+    def layered_doc(self, layers=None, empty_folders=False):
+        return self.layered_resources(layers, empty_folders, resource_type='doc')
+    
+    
+    
 class Configuration(CompositeConfiguration):
     """
     A Configuration is a container that can hold several Layer objects.
@@ -729,12 +904,33 @@
     def __init__(self, ref="", **kwargs):
         self.path = kwargs.get('path') or ref
         self.namespace = kwargs.get('namespace', '')
-        self.name = utils.resourceref.to_objref(self.path)
-        super(Configuration, self).__init__(utils.resourceref.to_objref(self.path))
+        self.name = kwargs.get('name',utils.resourceref.to_objref(self.path))
+        self.version = kwargs.get('version')
+        super(Configuration, self).__init__(utils.resourceref.to_objref(self.path), **kwargs)
         self.container = True
 
+    def __reduce_ex__(self, protocol_version):
+        """
+        Make the Configuration pickle a ConfigurationProxy object that would load this configuration
+        """
+        proxy = ConfigurationProxy(self.path, store_interface = self.get_project())
+        tpl = proxy.__reduce_ex__(protocol_version)
+        return tpl
+
+    def __getstate__(self):
+        return None
+
     def _default_object(self, name):
-        return Feature(name)
+        return self._default_class()(name)
+
+    def _default_class(self):
+        return self._feature_class()
+
+    def _feature_class(self):
+        return Feature
+
+    def _view_class(self):
+        return View
 
     def _supported_type(self, obj):
         if isinstance(obj, Configuration) \
@@ -747,16 +943,11 @@
         else:
             return False
 
-    def _dict(self):
+    def _dict(self, **kwargs):
         """
         Return the public variables in a dictionary
         """
-        dict = {}
-        for key in self.__dict__.keys():
-            if key.startswith('_'):
-                continue
-            else:
-                dict[key] = self.__dict__[key]
+        dict = super(Configuration, self)._dict(**kwargs)
         dict['namespace'] = self.namespace
         return dict
     
@@ -783,10 +974,8 @@
         Set the path of the configuration resource, and update the name and ref to correspond
         """
         self.path = path
-        #self.name = utils.resourceref.to_objref(self.path)
         self.set_ref(utils.resourceref.to_objref(self.path))
 
-    #@property
     def get_full_path(self):
         """
         Return the path of the configuration resource
@@ -796,7 +985,19 @@
             parent_path = utils.resourceref.get_path(parentconfig.get_path()) 
         except exceptions.NotFound:
             parent_path = ""
-
+        return utils.resourceref.join_refs([parent_path, self.path])
+
+    def get_path_for_parent(self, parent):
+        """
+        Return the path to this configuration for a defined parent Configuration object.
+        """
+        parent_path = ""
+        try:
+            parentconfig = self._find_parent(type=Configuration)
+            if parent != parentconfig:
+                parent_path = utils.resourceref.get_path(parentconfig.get_path_for_parent(parent)) 
+        except exceptions.NotFound:
+            pass
         return utils.resourceref.join_refs([parent_path, self.path])
 
     def get_layer(self):
@@ -821,7 +1022,6 @@
         @param namespace: The new namespace of the object
         """
         self._namespace =  namespace
-        #self.root.set_namespace(namespace)
 
     def get_namespace(self):
         """
@@ -836,7 +1036,7 @@
         self._namespace = None
     namespace = property(get_namespace, set_namespace, del_namespace)
 
-    def list_resources(self, empty_folders=False):
+    def list_resources(self, **kwargs):
         """
         List all resources used in this configuration
         """
@@ -848,10 +1048,10 @@
         
         
         resources = [self.get_full_path()]
-        for config in self._traverse(type=Configuration):
+        for config in self._traverse(type=(Configuration,ConfigurationProxy)):
             resources.append(config.get_full_path())
         layer = self.get_layer()
-        for resref in layer.list_all_resources(empty_folders):
+        for resref in layer.list_all_resources():
             resources.append(utils.resourceref.join_refs([layer.get_current_path(), resref]))
     
         return utils.distinct_array(resources)
@@ -891,6 +1091,18 @@
         """
         return self._get(ref)
 
+    def create_feature(self, ref, **kwargs):
+        """
+        Create a feature object to the configuration.
+        @param ref: The ref for the Feature object.
+        @param **kwargs: keyword arguments  
+        e.g. to add fea2 under fea1 add_feature(fea2, 'fea1')
+        @return: the new feature object.
+        """
+        fea = self._feature_class()(ref, **kwargs)
+        self._add(fea)
+        return fea
+
     def add_feature(self, feature, namespace=""):
         """
         Add a feature object to the configuration.
@@ -899,7 +1111,11 @@
         e.g. to add fea2 under fea1 add_feature(fea2, 'fea1')
         @return: None
         """
-        self._add_to_path(namespace, feature)
+        if namespace and self._has(namespace):
+            # Add the feature directly with an existing feature's add_feature functionality
+            self.get_feature(namespace).add_feature(feature)
+        else:
+            self._add_to_path(namespace, feature)
 
     def remove_feature(self, ref):
         """
@@ -927,13 +1143,27 @@
     def add_data(self, data, policy=container.REPLACE):
         """
         Add a data object to this configuration object.
-        @param data: The Data object to add.
+        @param data: The Data object or list of Data objects to add.
         @return: None
-        """ 
-        if not self._has(data.attr):
-            self._add(DataContainer(data.attr, container=True))
-        (namespace, name) = utils.dottedref.psplit_ref(data.get_fearef())
-        self._get(data.attr)._add_to_path(namespace, data, policy)
+        """
+        data_objs = utils.get_list(data)
+        
+        if policy == container.PREPEND:
+            data_objs = reversed(data_objs)
+            policy_first = container.PREPEND
+            policy_rest = container.PREPEND
+        else:
+            policy_first = policy
+            policy_rest = container.APPEND
+        
+        for i, data_obj in enumerate(data_objs):
+            if not self._has(data_obj.attr):
+                self._add(DataContainer(data_obj.attr, container=True))
+            (namespace, name) = utils.dottedref.psplit_ref(data_obj.get_fearef())
+            
+            if i == 0:  p = policy_first
+            else:       p = policy_rest
+            self._get(data_obj.attr)._add_to_path(namespace, data_obj, p)
 
     def get_data(self, ref):
         """
@@ -1009,13 +1239,24 @@
         view.populate()
         return view
 
-    def add_view(self, viewname):
+    def create_view(self, viewname):
+        """
+        Create a view object to the configuration.
+        @param viewname: The name of the view to add. 
+        @return: view object
+        """
+        viewobj = self._view_class()(viewname)
+        self.add_view(viewobj)
+        return viewobj
+
+    def add_view(self, viewobj):
         """
         Add a view object to the configuration.
-        @param viewname: The name of the view to add. 
+        @param viewobj: The existing view object to add. 
         @return: None
         """
-        return self._add(View(viewname))
+        assert(isinstance(viewobj, View))
+        return self._add(viewobj)
 
     def remove_view(self, ref):
         """
@@ -1038,10 +1279,13 @@
         Save the object to the permanent Storage object. Calls the save operation of 
         all the children.
         """
+        # Change the recursion order so that the current object 
+        # is saved first and then its childen.
+        # This increases performance in cases where this object requires information about its childen (no unload -> load cases)
+        self.get_project().unload(self.get_full_path(), self)
         for child in self._objects():
             if isinstance(child, (Configuration,ConfigurationProxy)):
                 child.save()
-        self.get_project().unload(self.get_full_path(), self)
 
     def close(self):
         """
@@ -1077,13 +1321,13 @@
         This returns always the view from the Root configuration point of view.
         """
         try:
-            parent = self._find_parent_or_default() 
+            parent = self._find_parent_or_default()
             if parent and isinstance(parent, Configuration):
                 return parent.get_default_view()
             else:
-                if not hasattr(self, '_default_view'):
+                if not self._has('?default_view'):
                     self._create_default_view()
-                return self._default_view
+                return self._get('?default_view')
         except exceptions.NotFound, e:
             raise e
         # raise exceptions.NotFound("Default View is not found! No root configuration?")
@@ -1101,17 +1345,19 @@
     
     def _create_default_view(self):
         # Rebuild the default view for this Configuration
-        self._default_view = View("_default_view", data=True)
-        self._default_view._parent= self
+        default_view = View("?default_view", data=True)
+        #self._default_view._parent= self
+        self._add(default_view)
         # First add all features of the configuration to the view. 
         # Then add all data elements under the features
         for child in self._traverse(type=Feature):
-            self._default_view.add_feature(child, child.namespace)
+            # TODO print "Adding : %s -> %s" % (child.namespace, child)
+            default_view.add_feature(child, child.namespace)
         for child in self._traverse(type=Data):
             #parent_config = child._find_parent_or_default(type=Configuration)
             #print "Adding data %s: fqr: %s from file %s." % (child.get_value(), child.fqr, parent_config.get_path())
             try:
-                fea = self._default_view.get_feature(child.fqr)
+                fea = default_view.get_feature(child.fqr)
                 fea.add_data(child)
             except exceptions.NotFound, e:
                 data_parent_config = child._find_parent_or_default(type=Configuration)
@@ -1128,9 +1374,15 @@
         The ConfigurationProxy trust to get the store_interface from the parent object with get_storage() function.
         
         """
-        container.LoadProxy.__init__(self, path)
+        super(ConfigurationProxy,self).__init__(path, **kwargs)
         self.set('_name', utils.resourceref.to_objref(path))
 
+    def __reduce_ex__(self, protocol_version):
+        """
+        Make the Configuration pickle a ConfigurationProxy object that would load this configuration
+        """
+        return super(ConfigurationProxy, self).__reduce_ex__(protocol_version)
+    
     def _clone(self, **kwargs):
         """
         A ConfigurationProxy specific implementation for cloning.
@@ -1152,7 +1404,7 @@
                 newobj = self._get_obj()._clone(**kwargs) 
                 obj._set_obj(newobj)
         return obj
-
+    
     def _dict(self):
         """
         Return the public variables in a dictionary
@@ -1164,7 +1416,7 @@
             else:
                 dict[key] = self.__dict__[key]
         return dict
-
+    
     def _get_mapper(self,modelname):
         """
         Return a instance of appropriate mapper for given model.
@@ -1177,32 +1429,27 @@
     """
     def __init__(self, ref="", **kwargs):
         super(Group, self).__init__(ref, **kwargs)
-        self.name = ref
+        self.name = kwargs.get('name', ref)
         self.support_data = kwargs.get("data", False)
 
     def _supported_type(self, obj):
         if isinstance(obj, (Group, \
                            Base, \
                            _FeatureProxy, \
-                           FeatureLink)): 
+                           FeatureLink, \
+                           ConfigurationProxy)): 
             return True
         else:
             return False
 
     def _default_object(self, name):
-        return Group(name)
-
-    def get_name(self):
-        """
-        Return the name of the configuration
-        """
-        return self.name
-
-    def set_name(self, name):
-        """
-        Set the name
-        """
-        self.name
+        return self._group_class()(name)
+
+    def _group_class(self):
+        return Group
+
+    def _featurelink_class(self):
+        return FeatureLink
 
     def add(self, child, policy=container.REPLACE):
         """
@@ -1213,10 +1460,7 @@
         @param child: the child object to add
         @raise IncorrectClassError: if the given class cannot be added to this object.  
         """
-        if isinstance(child, (Group, \
-                              Base, \
-                              _FeatureProxy, \
-                              FeatureLink)):
+        if self._supported_type(child):
             self._add(child)
         else:
             raise exceptions.IncorrectClassError("Cannot add %s to %s" % (child, self))
@@ -1233,6 +1477,21 @@
         """
         self.name = name
 
+    def create_featurelink(self, feature_ref, **kwargs):
+        """
+        create a feature link object to this element, with the given ref
+        @param feature_ref: the reference for the featurelink which should
+        point to a exising feature in the configuration.
+        @param **kwargs: keyword arguments are passed to the featurelink object 
+        directly.
+        """
+        fealink = self._featurelink_class()(feature_ref, **kwargs)
+        self.add(fealink)
+        return fealink
+
+    def get_featurelink(self, ref):
+        return self._get(FeatureLink.get_featurelink_ref(ref))
+    
     def add_feature(self, feature, path=""):
         """
         Add feature to this Group.
@@ -1260,26 +1519,65 @@
         except exceptions.NotFound:
             raise exceptions.NotFound("Feature '%s' not found." % ref)
 
-    def get_features(self, ref, **kwargs):
+    def get_features(self, refs, **kwargs):
         """
         Get a list of features that match the ref. 
+        
+        @param refs: The paths (refs) to the given feature or xpath like expression. The refs
+        argument can be a single reference or a list of references to features. 
+        @return: A list of features.
+        
+        NOTE! the invalid references will not raise an exception.
+         
         Example1: get_features('foo.bar') would be the same as get_feature('foo.bar'), but this returns 
         always a list [<Feature>].
         Example2: get_features('foo.*') would try to retrieve a list of all foo children.
         Example3: get_features('foo.*', type='') would try to retrieve a list of all foo children, 
         that have a defined type.
-        @param path: The path (ref) to the given feature or xpath like expression 
+        Example4: get_features(['foo','bar.set1']) would try to retrieve a foo and then bar.set1.
+        
+        """
+        
+        if utils.is_list(refs):
+            features = []
+            for ref in refs:
+                features += self.get_matching_features(ref, **kwargs)
+            return features
+        else:
+            return self.get_matching_features(refs, **kwargs)
+
+    def get_matching_features(self, ref, **kwargs):
+        """
+        Get a list of features that match the ref. 
+        
+        @param refs: The paths (refs) to the given feature or xpath like expression. The refs
+        argument can be a single reference or a list of references to features. 
         @return: A list of features.
-        """
-        (startref, last) = utils.dottedref.psplit_ref(ref)
-        startelem = self._get(startref)
-        if last == '**':
-            return [fea for fea in startelem._traverse(**kwargs)]
-        elif last == '*':
-            return [fea for fea in startelem._objects(**kwargs)] 
-        else:
-            return [self._get(ref)]
-
+
+        NOTE! the invalid references will not raise an exception but return an empty list.
+        
+        Example1: get_features('foo.bar') would be the same as get_feature('foo.bar'), but this returns 
+        always a list [<Feature>].
+        Example2: get_features('foo.*') would try to retrieve a list of all foo children.
+        Example3: get_features('foo.*', type='') would try to retrieve a list of all foo children, 
+        that have a defined type.
+        
+        """
+        try:
+            (startref, last) = utils.dottedref.psplit_ref(ref)
+            startelem = self._get(startref)
+            kwargs['type'] = _FeatureProxy
+            if last == '**':
+                return [fea for fea in startelem._traverse(**kwargs)]
+            elif last == '*':
+                return [fea for fea in startelem._objects(**kwargs)] 
+            elif ref != "":
+                return [self._get(ref)]
+            else:
+                return []
+        except exceptions.NotFound:
+            return []
+         
     def list_features(self):
         """
         Return a array of all Feature children references under this object.
@@ -1292,10 +1590,20 @@
         """
         return [fea.fqr for fea in self._traverse(type=(_FeatureProxy))]
 
-    def add_group(self, groupname):
-        """
-        """
-        self._add(Group(groupname))
+    def create_group(self, groupname, **kwargs):
+        """
+        create a group object to this element with given group name.
+        @param groupname: the name for the new group
+        @param **kwargs: keyword arguments are passed on to the new group object.  
+        """
+        grp = self._group_class()(groupname, **kwargs)
+        self.add_group(grp)
+        return grp
+
+    def add_group(self, grp):
+        """
+        """
+        self._add(grp)
 
     def remove_group(self, ref):
         """
@@ -1313,7 +1621,7 @@
     def list_groups(self):
         """
         """
-        return [group.get_name() for group in self._objects(type=Group)]
+        return [group.ref for group in self._objects(type=Group)]
 
     def populate(self):
         """
@@ -1332,7 +1640,6 @@
     """
     def __init__(self, ref="", **kwargs):
         super(View, self).__init__(self.to_ref(ref), **kwargs)
-        self.name = ref
         self.container = True
 
     @classmethod
@@ -1350,8 +1657,10 @@
     PROPERTIES = ['value']
     def __init__(self, ref="", **kwargs):
         super(Feature, self).__init__(ref, **kwargs)
-        self.name = kwargs.get('name', ref)
+        self.name = kwargs.get('name', None)
         self.type = kwargs.get('type', None)
+        self.relevant = kwargs.get('relevant', None)
+        self.constraint = kwargs.get('constraint', None)
         self._dataproxy = None
 
     def __copy__(self):
@@ -1364,7 +1673,17 @@
         fea = self.__class__(self.ref, **dict)
         return fea
 
-
+    def __getstate__(self):
+        state = super(Feature, self).__getstate__()
+        # remove the dataproxy value so that it is not stored in serializings
+        state.pop('_dataproxy', None)
+        return state
+
+    def __setstate__(self, state):
+        super(Feature, self).__setstate__(state)
+        self._dataproxy = None
+
+        
     def _supported_type(self, obj):
         # For now support added for desc element via support for Base
         if isinstance(obj, (Feature, Option, Base)):
@@ -1372,6 +1691,9 @@
         else:
             return False
 
+    def _feature_class(self):
+        return Feature
+
     def add(self, child, policy=container.REPLACE):
         """
         A generic add function to add child objects. The function is intended to act as
@@ -1387,6 +1709,8 @@
             self._add(child, policy)
         elif isinstance(child, Base):
             self._add(child, policy)
+        elif isinstance(child, Property):
+            self._add(child, policy)
         else:
             raise exceptions.IncorrectClassError("Cannot add %s to %s" % (child, self))
 
@@ -1402,22 +1726,53 @@
         """
         self.name = name
 
+    def get_relevant(self):
+        """
+        Return the relevant attribute of the feature
+        """
+        return self.relevant
+
+    def set_relevant(self, relevant):
+        """
+        Set the relevant attribute
+        """
+        self.relevant = relevant
+
+    def get_constraint(self):
+        """
+        Return the constraint attribute of the feature
+        """
+        return self.constraint
+
+    def set_constraint(self, constraint):
+        """
+        Set the constraint attribute
+        """
+        self.constraint = constraint
+
     def get_type(self):
         return self.type
 
     def set_type(self, type):
         self.type = type
 
+    def create_feature(self, ref, **kwargs):
+        """
+        Create a feature object to the configuration.
+        @param ref: The ref for the Feature object.
+        @param **kwargs: keyword arguments  
+        e.g. to add fea2 under fea1 add_feature(fea2, 'fea1')
+        @return: the new feature object.
+        """
+        fea = self._feature_class()(ref, **kwargs)
+        self.add_feature(fea)
+        return fea
+
     def add_feature(self, feature, path=""):
         """
         @param feature: The Feature object to add 
         """
-        configuration = self.find_parent(type=Configuration)
-        if configuration:
-            feapath = utils.dottedref.join_refs([self._path(configuration), path])
-            configuration.add_feature(feature, feapath)
-        else:
-            self._add_to_path(path, feature)
+        self._add_to_path(path, feature)
 
     def get_feature(self, path):
         """
@@ -1430,12 +1785,7 @@
         remove a given feature from this view by reference. 
         @param ref: 
         """
-        configuration = self.find_parent(type=Configuration)
-        if configuration:
-            fullfqr = utils.dottedref.join_refs([self._path(configuration), ref])
-            configuration.remove_feature(fullfqr)
-        else:
-            self._remove(ref)
+        self._remove(ref)
 
     def list_features(self):
         """
@@ -1491,40 +1841,107 @@
         # Return option refs without the leading 'opt_'
         return [opt.ref[4:] for opt in self._objects(type=Option)]
 
+    def add_property(self, property):
+        """
+        @param property: property object to add
+        """
+        if not isinstance(property, Property):
+            raise TypeError("%r is not an instance of Property!" % property)
+        self._add(property)
+
+    def create_property(self, **kwargs):
+        """
+        @param name=str: property name 
+        @param value=str: property value
+        @param unit=str: property unit, e.g. kB
+        """
+        self._add(Property(**kwargs))
+
+
+    def get_property(self, ref):
+        """
+        @param ref: The ref of the property
+        """
+        obj = self._get(Property.to_propertyref(ref))
+        
+        if not isinstance(obj, Property):
+            raise TypeError('Object %r is not an instance of Property (%r instead)' % (Property.to_propertyref(ref), type(obj)))
+        return obj
+
+    def remove_property(self, ref):
+        """
+        remove a given property from this feature by ref. 
+        @param ref: 
+        """
+        obj = self._get(Property.to_propertyref(ref))
+        if not isinstance(obj, Property):
+            raise TypeError('Trying to remove property with ref %r, but object with ref %r is not an instance of Property (%s instead)' % (ref, Property.to_propertyref(ref), type(obj)))
+        self._remove(Property.to_propertyref(ref))
+
+    def list_properties(self):
+        """
+        Return a array of all Feature properties under this object.
+        """
+        
+        return [Property.to_normref(property.ref) for property in self._objects(type=Property)]
+
     def get_value(self, attr=None):
         """
-        Get the current value of the feature
+        Get the current value of the feature. 
         @param attr: The attribute name of the data. E.g. attr='data', attr='rfs' 
         """
-        # Do not allow getting of setting of sequence values directly with Feature object
-        if not self.is_sequence():
-            return self.get_value_cast(self.dataproxy._get_value(attr), attr)
-        else:
-            """ get the feature specific data from sequence => a column of data table """
-            coldata =  []
-            feasequence = self.get_sequence_parent()
-            feapath = self._path(feasequence)
-            for row in feasequence.data:
-                feadata = row.get_feature(feapath)
-                coldata.append(feadata.value)
-            return coldata
+        return self.convert_data_to_value(self.dataproxy._get_datas(attr=attr), cast=True, attr=attr)
 
     def set_value(self, value, attr=None):
         """
         Set the current value for this feature. Set the value on the topmost layer.
         @param value: the value to set
         """
-        # Do not allow setting of setting of sequence values directly with Feature object
-        if not self.is_sequence():
-            value = self.set_value_cast(value, attr)
-            self.dataproxy._set_value(value, attr)
-
+        data_objs = self.convert_value_to_data(value, attr)
+        
+        # Set the created data objects to the dataproxy and the
+        # last configuration, overriding any existing elements
+        self.dataproxy._set_datas(data_objs, attr)
+        last_config = self.get_root_configuration().get_last_configuration()
+        last_config.add_data(data_objs, container.REPLACE)
+    
+    def convert_data_to_value(self, data_objects, cast=True, attr=None):
+        """
+        Convert the given list of Data objects into a suitable value
+        for this setting.
+        @param data_objects: The Data object list.
+        @param cast: If True, the value should be cast to its correct Python type
+            (e.g. int), if False, the value should remain in the string form
+            it was in the data objects.
+        @param attr: The attribute name of the data. E.g. attr='data', attr='rfs'
+        @return: The converted value.
+        """
+        if not data_objects:    return None
+        
+        data_obj = data_objects[-1]
+        if data_obj.map:
+            value = self._resolve_name_id_mapped_value(data_obj.map, cast_value=cast)
+        else:
+            value = data_obj.value
+            if cast: value = self.get_value_cast(value, attr)
+        return value
+    
+    def convert_value_to_data(self, value, attr=None):
+        """
+        Convert the given value to a list of Data objects that can be placed
+        in the configuration's last layer's data section (DataContainer object).
+        @param value: The value to convert.
+        @param attr: The attribute name of the data. E.g. attr='data', attr='rfs'
+        @return: The converted Data objects.
+        """
+        value = self.set_value_cast(value, attr)
+        return [Data(fqr=self.fqr, value=value, attr=attr)]
+    
     def del_value(self, attr=None):
         """
         Delete the topmost value for this feature.
         """
-        if not self.is_sequence():
-            self.dataproxy._del_value(attr)
+        self.dataproxy._del_value(attr)
 
     def get_value_cast(self, value, attr=None):
         """
@@ -1547,18 +1964,7 @@
         Get the current value of the feature
         @param attr: The attribute name of the data. E.g. attr='data', attr='rfs' 
         """
-        # Do not allow getting of setting of sequence values directly with Feature object
-        if not self.is_sequence():
-            return self.dataproxy._get_value(attr)
-        else:
-            """ get the feature specific data from sequence => a column of data table """
-            coldata =  []
-            feasequence = self.get_sequence_parent()
-            feapath = self._path(feasequence.data)
-            for row in feasequence.data:
-                feadata = row.get_feature(feapath)
-                coldata.append(feadata.value)
-            return coldata
+        return self.convert_data_to_value(self.dataproxy._get_datas(attr=attr), cast=False, attr=attr)
 
     def add_data(self, data):
         """
@@ -1616,6 +2022,10 @@
         except AttributeError:
             return False
 
+    def is_sequence_root(self):
+        """ Return true if this feature is a sequence object it self """
+        return False
+
     def get_sequence_parent(self):
         """ Try to get a FeatureSequence object for this Feature if it is found """
         try:
@@ -1630,7 +2040,163 @@
     def setdataproxy(self, value): self._dataproxy = value
     def deldataproxy(self): self._dataproxy = None
     dataproxy = property(getdataproxy, setdataproxy, deldataproxy)
-    value = property(get_value, set_value, del_value)
+    """ Use custom OProperty to enable overriding value methods in subclasses """
+    value = utils.OProperty(get_value, set_value, del_value)
+
+    def get_column_value(self, attr=None):
+        """
+        Get the value of the featuresequence column
+        @param ref: the reference to the column   
+        @param attr: The attribute name of the data. E.g. attr='data', attr='rfs' 
+        """
+        """ get the feature specific data from sequence => a column of data table """
+        seq_parent = self.get_sequence_parent()
+        if seq_parent._has_empty_sequence_marker():
+            return []
+        
+        coldata =  []
+        colref = self.path(seq_parent)
+        for row in seq_parent.data:
+            feadata = row.get_feature(colref)
+            coldata.append(feadata.get_value(attr))
+        return coldata
+    
+    def get_column_original_value(self, attr=None):
+        """
+        Get the value of the featuresequence column
+        @param feasequence: the feature sequence object
+        @param ref: the reference to the column   
+        @param attr: The attribute name of the data. E.g. attr='data', attr='rfs' 
+        """
+        """ get the feature specific data from sequence => a column of data table """
+        seq_parent = self.get_sequence_parent()
+        if seq_parent._has_empty_sequence_marker():
+            return []
+        
+        coldata =  []
+        colref = self.path(seq_parent)
+        for row in seq_parent.data:
+            feadata = row.get_feature(colref)
+            coldata.append(feadata.get_original_value(attr))
+        return coldata
+    
+    def set_column_value(self, value, attr=None):
+        """
+        Get the value of the featuresequence column
+        @param feasequence: the feature sequence object
+        @param ref: the reference to the column   
+        @param value: the value to set. This must be a list instance. 
+        @param attr: The attribute name of the data. E.g. attr='data', attr='rfs' 
+        """
+        seq_parent = self.get_sequence_parent()
+        colref = self.path(seq_parent)
+        
+        if not isinstance(value,list): 
+            raise exceptions.ConeException("The value for feature sequence '%s' column '%s' must be a list instance. Got %r" % (self.get_sequence_parent().fqr, colref, value))
+        
+        # Handle the special case where the sequence is marked as empty
+        # with the empty sequence marker (single empty data element)
+        if seq_parent._has_empty_sequence_marker():
+            seqrows = []
+        else:
+            seqrows = seq_parent.data
+        
+        if len(seqrows) < len(value):
+            raise exceptions.ConeException("Too many values for feature sequence '%s' column '%s'. Sequence holds only %d rows. Got %d data values in %r" % (self.get_sequence_parent().fqr, colref, len(seqrows), len(value), value))
+        for i in range(0, len(value)):
+            feadata = seqrows[i].get_feature(colref)
+            feadata.set_value(value[i])
+
+    def add_sequence_feature(self, feature, path=""):
+        """
+        Override of the add_feature function in sequence to set the sequence childs to act 
+        as columns of the feature sequence
+        @param feature: The Feature object to add 
+        @param path: path to feature if it not added directly under parent_fea 
+        """
+        # modify all possible children of feature
+        for fea in feature._traverse(type=Feature):
+            to_sequence_feature(fea)
+            
+        # Finally modify and add this feature to parent_feat
+        to_sequence_feature(feature)
+        self._add_to_path(path, feature)
+    
+    def _resolve_name_id_mapped_value(self, mapping_string, cast_value=True):
+        """
+        Resolve the name-ID mapped value based on the given mapping string.
+        @param mapping_string: The name-ID mapping string in the data element, e.g.
+            "FooFeature/FooSequence[@key='123']"
+        @param cast_value: If True, the resolved value will be cast to the corresponding
+            Python type, otherwise the raw string representation of the value in the
+            data element will be returned.
+        @return: The resolved value.
+        """
+        def fail(msg): raise exceptions.NameIdMappingError(msg)
+        
+        pattern = r"^([\w/]+)\[@key='(.*)'\]$"
+        m = re.match(pattern, mapping_string)
+        if m is None: fail("Malformed mapping expression: %s" % mapping_string)
+        
+        source_seq_ref = m.group(1).replace('/', '.')
+        mapping_key = m.group(2)
+        
+        dview = self.get_root_configuration().get_default_view()
+        
+        try:
+            source_seq = dview.get_feature(source_seq_ref)
+        except exceptions.NotFound:
+            fail("Mapping source sequence '%s' does not exist" % source_seq_ref)
+        
+        if source_seq.type != 'sequence':
+            fail("Mapping source setting '%s' is not a sequence setting" % source_seq_ref)
+        if not source_seq.mapKey or not source_seq.mapValue:
+            fail("Source sequence '%s' must have both mapKey and mapValue specified" % source_seq_ref)
+        
+        def get_subsetting(ref):
+            """
+            Return the sub-setting by the given mapKey or mapValue ref from the
+            source sequence.
+            @param ref: The reference in the format it is in the ConfML file.
+                E.g. 'SubSetting', 'FileSubSetting/localPath', 'FileSubSetting/targetPath'
+            """
+            subsetting = source_seq.get_feature(ref.replace('/', '.'))
+            # Use localPath for file and folder settings by default
+            if subsetting.type in ('file', 'folder'):
+                subsetting = subsetting.get_feature('localPath')
+            return subsetting
+        
+        try:
+            key_subsetting = get_subsetting(source_seq.mapKey)
+        except exceptions.NotFound:
+            fail("Invalid mapKey in source sequence '%s': no sub-setting with ref '%s'" % (source_seq_ref, source_seq.mapKey))
+        
+        
+        # Get possible override for mapValue from options
+        value_subsetting_ref = source_seq.mapValue
+        value_subsetting_ref_overridden = False
+        for opt in self._objects(type=Option):
+            if not opt.map or not opt.map_value: continue
+            if opt.map.replace('/', '.') == source_seq_ref:
+                value_subsetting_ref = opt.map_value
+                value_subsetting_ref_overridden = True
+        
+        try:
+            value_subsetting = get_subsetting(value_subsetting_ref)
+        except exceptions.NotFound:
+            if value_subsetting_ref_overridden:
+                fail("Invalid mapValue override in option: sub-setting '%s' does not exist under source sequence '%s'" % (value_subsetting_ref, source_seq_ref))
+            else:
+                fail("Invalid mapValue in source sequence '%s': no sub-setting with ref '%s'" % (source_seq_ref, value_subsetting_ref))
+        
+        key_list = key_subsetting.get_original_value()
+        if mapping_key not in key_list:
+            fail("No item-setting in source sequence '%s' matches key '%s'" % (source_seq_ref, mapping_key))
+        
+        if cast_value:  value_list = value_subsetting.get_value()
+        else:           value_list = value_subsetting.get_original_value()
+        return value_list[key_list.index(mapping_key)]
+
 
 class FeatureSequence(Feature):
     POLICY_REPLACE = 0
@@ -1642,11 +2208,9 @@
     dataelem_name = '?datarows'
     template_name = '?template'
     def __init__(self, ref="", **kwargs):
-        super(FeatureSequence, self).__init__(ref)
+        super(FeatureSequence, self).__init__(ref, **kwargs)
         self.name = kwargs.get('name', ref)
         self.type = 'sequence'
-        self.mapKey   = kwargs.get('mapKey')
-        self.mapValue = kwargs.get('mapValue')
         self._templatedata = None
 
     def _get_policy(self, data):
@@ -1665,8 +2229,8 @@
         elif firstdata.policy == 'prefix':
             return self.POLICY_PREPEND
         elif firstdata == data:
-             # otherwise the policy is either replace or undefined
-             # (firstdata.policy == 'replace' or firstdata.policy == ''):
+            # otherwise the policy is either replace or undefined
+            # (firstdata.policy == 'replace' or firstdata.policy == ''):
             return self.POLICY_REPLACE
         else:
             return self.POLICY_APPEND
@@ -1675,7 +2239,6 @@
         """
         Set the template of the feature sequence  
         """
-        # If template data is not existing, create it
         if data != None:
             self._templatedata = data
             for feaname in self.list_features():
@@ -1690,11 +2253,19 @@
         """
         Add a feature data row for a new data in this sequence 
         """
+        create_sub_data_objs = True
         if dataobj == None:
             dataobj = Data(fqr=self.fqr)
         elif dataobj.attr != 'data':
             # Add data rows only for data objects (not e.g. RFS)
             return
+        else:
+            # If the data object is given, but it doesn't contain any child
+            # elements, don't add them automatically. This is to account for the
+            # case where there is only one empty data element that specifies
+            # that the sequence is set to be empty
+            if len(dataobj._order) == 0:
+                create_sub_data_objs = False
         fea = FeatureSequenceSub(self.dataelem_name)
         rowproxy = _FeatureDataProxy(fea._name, fea)
         """ the imaginary features share the parent relation of the proxy objects """
@@ -1707,13 +2278,32 @@
         # add a data element under each feature.
         for feaname in self.list_all_features():
             (pathto_fea, fearef) = utils.dottedref.psplit_ref(feaname)
-            rowproxy.add_feature(FeatureSequenceSub(fearef), pathto_fea)
+            subfea = self.get_feature(feaname)
+            cellfea = FeatureSequenceSub(fearef)
+            cellfea.set_value_cast = subfea.set_value_cast
+            cellfea.get_value_cast = subfea.get_value_cast
+            cellfea.convert_data_to_value = subfea.convert_data_to_value
+            cellfea.convert_value_to_data = subfea.convert_value_to_data
+            rowproxy.add_feature(cellfea, pathto_fea)
             subproxy = rowproxy.get_feature(feaname)
-            subproxy._obj._parent = subproxy._parent 
-            if not dataobj._has(feaname):
+            subproxy._obj._parent = subproxy._parent
+            if create_sub_data_objs and not dataobj._has(feaname):
                 dataobj._add_to_path(pathto_fea, Data(ref=fearef))
             subproxy._add_data(dataobj._get(feaname))
-
+        return dataobj
+    
+    def _has_empty_sequence_marker(self):
+        """
+        Return True if the sequence setting has the empty sequence marker (a single
+        empty data element), which denotes that the sequence is set to empty.
+        """
+        datatable = self.get_data()
+        if len(datatable) == 1:
+            data_elem = datatable[0].get_datas()[0]
+            if len(data_elem._order) == 0:
+                return True
+        return False
+    
     def add(self, child, policy=container.REPLACE):
         """
         A generic add function to add child objects. The function is intended to act as
@@ -1731,38 +2321,83 @@
             self._add(child)
         else:
             raise exceptions.IncorrectClassError("Cannot add %s to %s" % (child, self))
+    
+    def add_feature(self, feature, path=""):
+        """
+        Override of the add_feature function in sequence to set the sequence childs to act 
+        as columns of the feature sequence
+        @param feature: The Feature object to add 
+        """
+        add_sequence_feature(self, feature, path)
 
     def add_sequence(self, data=None, policy=POLICY_APPEND):
         """
         Add a feature data row for a new data in this sequence 
         """
-        self._add_datarow(None, policy)
+        if self._has_empty_sequence_marker():
+            # We currently have the empty sequence marker (single empty data
+            # element), so this one that we are adding should replace it
+            policy = self.POLICY_REPLACE
+            
+        datarow = self._add_datarow(None, policy)
+        # add the new data sequence/row to the last configuration layer
+        last_config = self.get_root_configuration().get_last_configuration()
+        
+        container_policy = {self.POLICY_REPLACE: container.REPLACE,
+                            self.POLICY_APPEND:  container.APPEND,
+                            self.POLICY_PREPEND: container.PREPEND}[policy]
+        last_config.add_data(datarow, container_policy)
+        
         # set the initial data if it is given
         rowproxy = utils.get_list(self.dataproxy._get(self.dataelem_name))[-1]
         if data != None:
             for index in range(len(data)):
-                rowproxy[index].set_value(data[index])
-        # add the new data sequence/row to the last configuration layer
-        dataobj = rowproxy._get_data()
-        last_config = self.get_root_configuration().get_last_configuration()
-        last_config.add_data(dataobj, container.APPEND)
-        return dataobj
+                if data[index] != None:
+                    rowproxy[index].set_value(data[index])
 
     def set_template(self, data=None):
         """
         Set the template of the feature sequence  
         """
-        # If template data is not existing, create it
-        if self._templatedata == None:
-            self._set_template_data(Data(ref=self.ref, template=True))
-            # Add the template data to parent config
-            pconfig = self.find_parent(type=Configuration)
-            pconfig.add_data(self._templatedata)
-
-        if data != None:
-            templdatas = self._templatedata._objects()
-            for index in range(len(data)):
-                templdatas[index].set_value(data[index])
+        if data is None:
+            self._templatedata = None
+            return
+        
+        if not isinstance(data, list):
+            raise TypeError('data must be a list (got %r)' % data)
+        
+        # Create the new template data object
+        templatedata = Data(fqr=self.fqr, template=True)
+        
+        # Add all sub-objects to the data object
+        def add_data_objects(feature, data_obj, value_list):
+            refs = feature.list_features()
+            if len(refs) != len(value_list):
+                raise ValueError("Data value list is invalid")
+            for i, ref in enumerate(refs):
+                value = value_list[i]
+                subfea = feature.get_feature(ref)
+                if isinstance(value, list):
+                    subdata = Data(ref=ref)
+                    data_obj.add(subdata)
+                    add_data_objects(feature.get_feature(ref), subdata, value)
+                else:
+                    if value is not None:
+                        subdata = Data(ref=ref, value=subfea.set_value_cast(value))
+                        data_obj.add(subdata)
+        add_data_objects(self, templatedata, data)
+        
+        self._set_template_data(templatedata)
+        
+        # Remove any existing template data
+        pconfig = self.find_parent(type=Configuration)
+        dataobjs = pconfig._traverse(type=Data, filters=[lambda x: x.template and x.fqr == self.fqr])
+        if dataobjs:
+            for dataobj in dataobjs:
+                dataobj._parent._remove(dataobj.get_fullref())
+        
+        # Add the template data to the parent config (beginning of the data section)
+        pconfig.add_data(self._templatedata, policy=container.PREPEND)
 
     def get_template(self):
         """
@@ -1771,7 +2406,19 @@
         #self._set_template(None)
         # set the initial data if it is given
         if self._templatedata:
-            return [data.get_value() for data in self._templatedata._objects()]
+            def get_data_items(feature, data_obj):
+                refs = feature.list_features()
+                if refs:
+                    result = []
+                    for ref in refs:
+                        if data_obj._has(ref):
+                            result.append(get_data_items(feature.get_feature(ref), data_obj._get(ref)))
+                        else:
+                            result.append(None)
+                    return result
+                else:
+                    return data_obj.value
+            return get_data_items(self, self._templatedata)
         else:
             return None
 
@@ -1796,69 +2443,73 @@
             # Get the data index
             self._add_datarow(data, self._get_policy(data))
         return
-    
-    def get_map_key(self):
-        """
-        Returns the setting that corresponds to mapKey attribute of this sequence feature.
-        """
-        if self.mapKey != None:
-            mapkey = self.get_feature(self.mapKey)
-            return mapkey
-        else:
-            return None
-
-    def get_map_key_value(self,key):
-        """
-        Returns the setting that corresponds to mapKey attribute of this sequence feature.
-        """
-        value = None
-        if self.mapKey != None and self.mapValue != None:
-            data = self.get_data()
-            for item in data:
-                kv = item.get_feature(self.mapKey).get_value()
-                if kv == key:
-                    value = item.get_feature(self.mapValue).get_value()
-        return value
-
-    def get_map_value(self):
-        """
-        Returns the setting that corresponds to mapValue attribute of this sequence feature.
-        """
-        if self.mapValue != None:
-            mapvalue = self.get_feature(self.mapValue)
-            return mapvalue
-        else:
-            return None
         
     def get_value(self, attr=None):
         """
         Helper function to get the topmost data value from the default view.
         """
+        if self._has_empty_sequence_marker():
+            return []
+        
         datatable =  self.get_data()
-        rettable = [] 
+        rettable = []
         for row in datatable:
             rowvalues = row.value
             rettable.append(rowvalues)
         return rettable
 
+    def get_original_value(self, attr=None):
+        """
+        Get the current value of the feature
+        @param attr: The attribute name of the data. E.g. attr='data', attr='rfs' 
+        """
+        if self._has_empty_sequence_marker():
+            return []
+        
+        datatable =  self.get_data()
+        rettable = []
+        for row in datatable:
+            rowvalues = row.get_original_value()
+            rettable.append(rowvalues)
+        return rettable
+    
     def set_value(self, value, attr=None):
         """
         Set the current value for this feature. Set the value on the topmost layer.
         @param value: the value to set. The value must be a two dimensional array (e.g. matrix)
         """
-        # sets the first data element to replace policy
-        try:
-            self.add_sequence(value.pop(0), self.POLICY_REPLACE)
-        # ignore the index error of an empty list
-        except IndexError:
-            pass
-        for row in value:
-            self.add_sequence(row)
+        if value:
+            # Add the first item with replace policy
+            self.add_sequence(value[0], self.POLICY_REPLACE)
+            for row in value[1:]:
+                self.add_sequence(row)
+        else:
+            # Setting the sequence to empty, so add one empty item-setting
+            # to signify that
+            self.add_sequence(None, self.POLICY_REPLACE)
+            
+            # Strip all sub-elements from the data element just created,
+            # since the ConfML spec says that an empty sequence is denoted
+            # by a single empty data element
+            data_elem = self.get_data()[0].get_datas()[0]
+            for r in list(data_elem._order):
+                data_elem._remove(r)
 
     def is_sequence(self):
         """ Return always true from a sequence object """
         return True
 
+    def is_sequence_root(self):
+        """ Return true if this feature is a sequence object it self """
+        return True
+
+    def get_column_features(self):
+        """ Return a list of sequence subfeature, which are the columns of the sequence """
+        columns = []
+        for subref in self.list_features():
+            columns.append(self.get_feature(subref))
+        return columns
+
     def get_sequence_parent(self):
         """ Return this object as a sequence parent """
         return self
@@ -1866,12 +2517,84 @@
     value = property(get_value, set_value)
     data = property(get_data)
 
+
+def add_sequence_feature(parent_feature, feature, path=""):
+    """
+    Override of the add_feature function in sequence to set the sequence childs to act 
+    as columns of the feature sequence
+    @param parent_feature: The parent feature where the feature object is added 
+    @param feature: The Feature object to add 
+    @param path: path to feature if it not added directly under parent_fea 
+    """
+    # modify all possible children of feature
+    for fea in feature._traverse(type=Feature):
+        to_sequence_feature(fea)
+        
+    # Finally modify and add this feature to parent_feat
+    to_sequence_feature(feature)
+    parent_feature._add_to_path(path, feature)
+
+def to_sequence_feature(feature):
+    """
+    modify a Feature object to sequence feature that will return column like data from a sequence.
+    @param feature: The Feature object for which is modified.
+    """
+    feature.get_value = feature.get_column_value 
+    feature.get_original_value = feature.get_column_original_value
+    feature.set_value = feature.set_column_value
+    feature.add_feature = feature.add_sequence_feature
+
+def get_column_value(feasequence, ref, attr=None):
+    """
+    Get the value of the featuresequence column
+    @param feasequence: the feature sequence object
+    @param ref: the reference to the column   
+    @param attr: The attribute name of the data. E.g. attr='data', attr='rfs' 
+    """
+    """ get the feature specific data from sequence => a column of data table """
+    coldata =  []
+    for row in feasequence.data:
+        feadata = row.get_feature(ref)
+        coldata.append(feadata.get_value(attr))
+    return coldata
+
+def get_column_original_value(feasequence, ref, attr=None):
+    """
+    Get the value of the featuresequence column
+    @param feasequence: the feature sequence object
+    @param ref: the reference to the column   
+    @param attr: The attribute name of the data. E.g. attr='data', attr='rfs' 
+    """
+    """ get the feature specific data from sequence => a column of data table """
+    coldata =  []
+    for row in feasequence.data:
+        feadata = row.get_feature(ref)
+        coldata.append(feadata.get_original_value(attr))
+    return coldata
+
+def set_column_value(feasequence, ref, value, attr=None):
+    """
+    Get the value of the featuresequence column
+    @param feasequence: the feature sequence object
+    @param ref: the reference to the column   
+    @param value: the value to set. This must be a list instance. 
+    @param attr: The attribute name of the data. E.g. attr='data', attr='rfs' 
+    """
+    if not isinstance(value,list): 
+        raise exceptions.ConeException("The value for feature sequence '%s' column '%s' must be a list instance. Got %r" % (feasequence.fqr, ref, value))
+    seqrows = feasequence.data
+    if len(seqrows) < len(value): 
+        raise exceptions.ConeException("Too many values for feature sequence '%s' column '%s'. Sequence holds only %d rows. Got %d data values in %r" % (feasequence.fqr, ref, len(seqrows), len(value), value))
+    for i in range(0, len(value)):
+        feadata = seqrows[i].get_feature(ref)
+        feadata.set_value(value[i])
+
 class FeatureSequenceCell(Feature):
     """
     A Feature class. Feature is the base for all Configurable items in a Configuration.
     """
     def __init__(self, ref="", **kwargs):
-        super(Feature, self).__init__(ref)
+        super(FeatureSequenceCell, self).__init__(ref)
         self.name = kwargs.get('name', ref)
         self.type = 'seqcell'
  
@@ -1897,11 +2620,16 @@
     A Feature class. Feature is the base for all Configurable items in a Configuration.
     """
     def __init__(self, ref="", **kwargs):
-        super(Feature, self).__init__(ref)
+        super(FeatureSequenceSub, self).__init__(ref)
         self.name = kwargs.get('name', ref)
         self.type = 'subseq'
         self._index = 0
 
+    def __getstate__(self):
+        state = super(FeatureSequenceSub,self).__getstate__()
+        state['_children'].pop('?datarows', None)
+        return state
+
     def get_index(self):
         """
         @return : the index of the data element for sequential data defined inside the same configuration.
@@ -1915,24 +2643,46 @@
         @param value: the value row to set
         """
         if utils.is_list(value):
-            for subindex in range(0, len(value)):  
+            for subindex in range(0, len(value)):
                 self.dataproxy[subindex].get_data().set_value(value[subindex])
-        else: 
-            self.dataproxy.get_data().set_value(value)
+        else:
+            data_objs = self.convert_value_to_data(value)
+            data_object_where_to_add = self._parent._get_data()
+            
+            self.dataproxy._set_datas(data_objs, attr)
+            data_object_where_to_add._add(data_objs, container.REPLACE)
 
     def get_value(self, attr=None):
         """
         Set the current value for this feature. Set the value on the topmost layer.
         @param value: the value to set
         """
-        # dataproxy = self.get_default_view().get_feature(self.get_fullfqr())
+        # Handle empty sequences
+        if self.get_sequence_parent()._has_empty_sequence_marker():
+            return []
+        
         # The sequence cell only updates the latest value in the proxy
         childdatas = self.dataproxy._objects()
         if len(childdatas) > 0:
             return [subdata.value for subdata in childdatas]
         else: 
-            return self.dataproxy._get_value(attr=attr)
-
+            return super(FeatureSequenceSub,self).get_value(attr)
+
+    def get_original_value(self, attr=None):
+        """
+        Get the current value of the feature
+        @param attr: The attribute name of the data. E.g. attr='data', attr='rfs' 
+        """
+        # Handle empty sequences
+        if self.get_sequence_parent()._has_empty_sequence_marker():
+            return []
+        
+        childdatas = self.dataproxy._objects()
+        if len(childdatas) > 0:
+            return [subdata.get_original_value() for subdata in childdatas]
+        else:
+            return self.dataproxy._get_value(attr)
+        
     value = property(get_value, set_value)
 
 
@@ -1941,14 +2691,49 @@
     A _FeatureProxy class. _FeatureProxy is the object that is added to View as a 
     link to the actual Feature object. 
     """
-    def __init__(self, link="", **kwargs):
+    """ class variable for defining the override attributes"""
+    override_attributes = ['name']
+    ref_prefix = 'link_'
+    PROXYREF_PREFIX = 'proxy_'
+    
+    def __init__(self, ref="", **kwargs):
         # Store the fully qualified reference to this object
-        self.link = link
-        ref = link.replace('.', '_')
-        super(FeatureLink, self).__init__(ref)
+        self.link = kwargs.get('link', ref)
+        self.name = kwargs.get('name', None)
+        ref = self.get_featurelink_ref(self.link)
+        # the reference of this particular object
+        super(FeatureLink, self).__init__(ref, **kwargs)
         self._obj = None
         self._populated = False
 
+    def add(self, child, policy=container.REPLACE):
+        """
+        Add an override to enable adding any override attribute to a featurelink object.
+        
+        A generic add function to add child objects. The function is intended to act as
+        proxy function that call the correct add function based on the child objects class.
+        
+        Example: obj.add(Feature("test")), actually obj.add_feature(Feature("test"))
+        @param child: the child object to add
+        @raise IncorrectClassError: if the given class cannot be added to this object.  
+        """
+        if isinstance(child, Base):
+            self._add(child, policy)
+        else:
+            raise exceptions.IncorrectClassError("Cannot add %s to %s" % (child, self))
+
+    def get_name(self):
+        """
+        Return the name of the featurelink
+        """
+        return self.name
+
+    def set_name(self, name):
+        """
+        Set the name
+        """
+        self.name = name
+
     @property
     def fqr(self):
         return self.link
@@ -1962,14 +2747,58 @@
         try:
             if not self._populated:
                 feas = self.get_default_view().get_features(self.link)
+                # get the non wildcard part of ref
+                static_ref = utils.dottedref.get_static_ref(self.link)
                 # add the found features to the parent
                 for fea in feas:
-                    self._get_parent().add_feature(fea._obj)
+                    override_attrs = {}
+                    # override the FeatureProxy object with exactly same reference 
+                    # (in feat/* case dont override the children features)
+                    if fea.fqr == static_ref:
+                        override_attrs = self.get_attributes()
+                    feature = fea._obj
+                    proxy_ref = self.get_featureproxy_ref(feature.fqr)
+                    proxy = _FeatureProxy(proxy_ref, feature, **override_attrs)
+                    self._get_parent()._add(proxy)
+                    
         except exceptions.NotFound, e:
                 parent_view = self._find_parent_or_default(type=View)
                 view_name = parent_view.get_name()
                 logging.getLogger('cone').info("Warning: Feature '%s' in view '%s' not found." % (self.link, view_name))
 
+    def get_attributes(self):
+        """
+        Returns a list of FeatureLink attributes that override settings of the original feature.
+        @return: a dictionary of attribute key : value pairs.
+        """
+        attrs = {}
+        for attr in self.override_attributes:
+            # try to get the attribute from this object
+            # and set it to the attribute list if it not None
+            try:
+                value = getattr(self, attr)
+                if value != None: attrs[attr] = value
+            except AttributeError:
+                pass
+        return attrs
+
+    @classmethod
+    def get_featurelink_ref(cls, ref):
+        """
+        return a featurelink ref from a feature ref. 
+        This is needed to make the featurelink object refs unique in a container
+        that has Features. 
+        """
+        return cls.ref_prefix + ref.replace('.', '_').replace('/','_')
+    
+    @classmethod
+    def get_featureproxy_ref(cls, ref):
+        """
+        Return a ref for a given setting fqr to be used under a group.
+        This is needed to make the featureproxy object refs unique in a container
+        that has Features. 
+        """
+        return cls.PROXYREF_PREFIX + ref.replace('.', '_').replace('/','_')
 
 class _FeatureProxy(container.ObjectProxyContainer, Base):
     """
@@ -1977,10 +2806,10 @@
     link to the actual Feature object. 
     """
     def __init__(self, ref="", obj=None, **kwargs):
-        super(_FeatureProxy, self).__init__(obj, ref)
-        Base.__init__(self, ref)
+        container.ObjectProxyContainer.__init__(self, obj, ref)
+        Base.__init__(self, ref, **kwargs)
         self.support_data = False
-
+        
     def __getattr__(self, name):
         """
         First check if the requested attr is a children then 
@@ -1995,7 +2824,7 @@
         return self._objects()[index]
 
     def __setitem__(self, index, value):
-        raise exceptions.NotSupported()
+        raise exceptions.NotSupportedException()
 
     def __delitem__(self, index):
         item = self.__getitem__(index)
@@ -2020,6 +2849,12 @@
         """
         self._parent = newparent
 
+    def get_proxied_obj(self):
+        """
+        @return: Returns proxied object.
+        """
+        return self._obj
+
     def add_feature(self, feature, path=""):
         """
         """
@@ -2061,7 +2896,65 @@
         """
         pass
 
-
+    def has_attribute(self, name):
+        """
+        Perform a check whether an attribute with given name is stored inside the 
+        _FeatureProxy. The check does not extend to the proxied (_obj) insanses or 
+        children of this proxy.
+        
+        @return: True when an attribute is a real attribute in this _FeatureProxy object. 
+        """
+        return self.__dict__.has_key(name)
+
+    def get_option(self, ref):
+        """
+        @param name: The option reference of the option (as returned by list_options()) 
+        """
+        real_ref = 'opt_' + ref
+        for op in self.options.values():
+            if op.ref == real_ref:
+                return op
+        else:
+            
+            obj = self.get_proxied_obj()._get(real_ref)
+            if not isinstance(obj, Option):
+                raise TypeError('Object %r is not an instance of Option (%r instead)' % (real_ref, type(obj)))
+            return obj
+
+    def list_options(self):
+        """
+        Return a array of all Option children references under this object.
+        """
+        opts = self.get_proxied_obj().list_options()
+        
+        for opt in self.options:
+            opts.append(self.options[opt].ref[4:])
+        
+        return opts
+
+    def get_property(self, ref):
+        """
+        @param name: The property reference of the property (as returned by list_properties()) 
+        """
+        for prop in self.properties.values():
+            if prop.ref == Property.to_propertyref(ref):
+                return prop
+        else:
+            obj = self.get_proxied_obj()._get(Property.to_propertyref(ref))
+            return obj
+
+    def list_properties(self):
+        """
+        Return a array of all Property children references under this object.
+        """
+        props = self.get_proxied_obj().list_properties()
+        
+        for pr in self.properties:
+            props.append(Property.to_normref(self.properties[pr].ref))
+        
+        return props
+
+    
 class _FeatureDataProxy(_FeatureProxy):
     """
     A Feature class. Feature is the base for all Configurable items in a Configuration.
@@ -2085,10 +2978,10 @@
         """
         """
         if object.__getattribute__(self, '_obj') is not None:
-            self._obj.dataproxy = self
+            self.get_proxied_obj().dataproxy = self
         
         if name in Feature.PROPERTIES:
-            return getattr(self._obj, name)
+            return getattr(self.get_proxied_obj(), name)
         else:
             return super(_FeatureDataProxy, self).__getattr__(name)
     
@@ -2096,10 +2989,10 @@
         """
         """
         if object.__getattribute__(self, '_obj') is not None:
-            self._obj.dataproxy = self
+            self.get_proxied_obj().dataproxy = self
             
         if name in Feature.PROPERTIES:
-            return setattr(self._obj, name, value)
+            return setattr(self.get_proxied_obj(), name, value)
         else:
             super(_FeatureDataProxy, self).__setattr__(name, value)
 
@@ -2107,15 +3000,19 @@
         """
         """
         if name in Feature.PROPERTIES:
-            return delattr(self._obj, name)
+            return delattr(self.get_proxied_obj(), name)
         else:
             return super(_FeatureDataProxy, self).__delattr__(name)
 
     def _add_data(self, data):
         """
-        Add a data value.
+        Add a data value or a list of data values.
         @param data: A Data object  
         """
+        if isinstance(data, list):
+            for d in data: self._add_data(d)
+            return
+        
         try:
             self.datas[data.attr].append(data)
         except KeyError:
@@ -2142,7 +3039,14 @@
         Get the entire data array.
         """
         dataattr = attr or self.defaultkey
-        return self.datas[dataattr]
+        return self.datas.get(dataattr, [])
+    
+    def _set_datas(self, datas, attr=None):
+        """
+        Set the entire data array.
+        """
+        dataattr = attr or self.defaultkey
+        self.datas[dataattr] = list(datas)
 
     def _get_value(self, attr=None):
         """
@@ -2152,7 +3056,7 @@
             return self._get_data(attr).get_value()
         else:
             return None
-
+    
     def _set_value(self, datavalue, attr=None):
         """
         Set the value for the feature the last configuration in the current hierarchy
@@ -2253,6 +3157,18 @@
         self.policy = kwargs.get('policy', '')
         self.template = kwargs.get('template', False)
         self.map    = kwargs.get('map')
+        self.empty  = kwargs.get('empty', False)
+        self.lineno = None
+
+    def __setstate__(self, state):
+        super(Data, self).__setstate__(state)
+        self.value = state.get('value', None)
+        self.attr = state.get('attr', None)
+        self.policy = state.get('policy', '')
+        self.map = state.get('map', None)
+        self.template = state.get('template', False)
+        self.lineno = state.get('lineno', None)
+        self.fearef = state.get('fearef', None)
 
     def get_fearef(self):
         if self.fearef:
@@ -2261,14 +3177,7 @@
             return self.fqr
 
     def get_value(self):
-        if self.map != None:
-            ref = utils.resourceref.to_dref(self.get_map_ref())
-            key = self.get_map_key_value()
-            dview = self.get_root_configuration().get_default_view()
-            fea = dview.get_feature(ref)
-            return fea.get_map_key_value(key)
-        else:
-            return self.value
+        return self.value
 
     def get_map(self):
         return self.map
@@ -2279,18 +3188,6 @@
             #Either value or mapping can be defined. Not both.
             self.value = None
 
-    def get_map_ref(self):
-        if self.map != None:
-            return utils.DataMapRef.get_feature_ref(self.map)
-        else:
-            return None
-
-    def get_map_key_value(self):
-        if self.map != None:
-            return utils.DataMapRef.get_key_value(self.map)
-        else:
-            return None
-
     def set_value(self, value):
         self.value = value
         if self.map:
@@ -2303,7 +3200,7 @@
     policy = property(get_policy, set_policy, del_policy)
 
 
-class ValueSet(sets.Set):
+class ValueSet(set):
     """
     A value set object to indicate a set of possible values for a feature. 
     e.g. A boolean feature ValueSet([True, False])
@@ -2337,6 +3234,51 @@
             return False
     
 
+class Property(Base):
+    """
+    Confml property class
+    """
+    def __init__(self, **kwargs):
+        """
+        @param name=str: name string (mandatory)
+        @param value=str: value for the property, string 
+        @param unit=str: unit of the property
+        """
+        if kwargs.get('name',None) == None:
+            raise ValueError("Property name cannot be None!")
+        super(Property,self).__init__(Property.to_propertyref(kwargs.get('name',None)))
+        self.name = kwargs.get('name',None)
+        self.value = kwargs.get('value',None)
+        self.unit = kwargs.get('unit',None)
+
+    @classmethod
+    def to_propertyref(cls, name):
+        """ 
+        @param name: name of the property 
+        @return: A property reference.
+        """
+        if name is not None:
+            return "property_%s" % name
+        else:
+            raise ValueError("Property name cannot be None!")
+    
+    @classmethod
+    def to_normref(cls, ref):
+        """
+        @param ref: a property reference 
+        @return: normalized property reference
+        """
+        return ref[9:]
+
+    def get_name(self):
+        return self.name
+
+    def get_value(self):
+        return self.value
+
+    def get_unit(self):
+        return self.unit
+
 class Option(Base):
     """
     Confml option class.
@@ -2347,6 +3289,8 @@
         self.value = value
         self.map = kwargs.get('map', None)
         self.relevant = kwargs.get('relevant', None)
+        self.map_value = kwargs.get('map_value', None)
+        self.display_name = kwargs.get('display_name', None)
 
     @classmethod
     def to_optref(cls, value, map):
@@ -2391,7 +3335,7 @@
     MODE_APPEND = 3
     MODE_DELETE = 4
 
-    def __init__(self, path):
+    def __init__(self, path, mode=''):
         """
         @param path: the reference to the root of the storage.
         """
@@ -2399,7 +3343,16 @@
         self.curpath = ""
         self.container = True
         self.__opened_res__ = {}
-
+        self.mode = mode
+        self.cpath_stack = []
+    
+    def __reduce_ex__(self, protocol_version):
+        return  (open_storage, 
+                 (self.path, self.mode),
+                 None,
+                 None,
+                 None)
+        
     def __opened__(self, res):
         """
         Internal function to add a newly opened Resource object to the list of open resources.
@@ -2496,6 +3449,34 @@
         """
         return self.rootpath
 
+    def push(self, path):
+        """
+        Set the current path under the Storage to the given path and push the possible existing path to a stack. 
+        The current path can be reverted with pop method.
+        
+        @return: None 
+        @param path: The path which is set as current path.
+        """
+        self.cpath_stack.append(self.curpath)
+        self.curpath = path
+
+    def pop(self):
+        """
+        Pop a path from path stack and set the current path to the popped element. The path can be pushed to the 
+        current path stack with push. 
+        
+        NOTE! if the pop is called when the current path stack is empty, the path will just remain is empty path 
+        keeping the active path in the storages root path. 
+        
+        @return: The new path.
+        """
+        try:
+            path = self.cpath_stack.pop()
+            self.curpath = path
+        except IndexError:
+            pass
+        return self.curpath
+
     def set_current_path(self, path):
         """
         @param path: the current path under the Storage. 
@@ -2556,7 +3537,7 @@
         """
         raise exceptions.NotSupportedException()
 
-    def list_resources(self, path, recurse=False):
+    def list_resources(self, path, **kwargs):
         """
         find the resources under certain ref/path 
         @param ref : reference to path where resources are searched
@@ -2581,14 +3562,6 @@
         """  
         raise exceptions.NotSupportedException()
 
-    def close_resource(self, path):
-        """
-        Close a given resource instance. Normally this is called by the Resource object 
-        in its own close.
-        @param ref the reference to the resource to close. 
-        """
-        raise exceptions.NotSupportedException()
-
     def save_resource(self, path):
         """
         Flush the changes of a given resource instance. Normally this is called by the Resource object 
@@ -2691,13 +3664,13 @@
         Trunkate this resource data to the given size.
         @param size: The size to trunkate. Default value is zero, which make the resource empty. 
         """
-        raise NotSupportedException()
+        raise exceptions.NotSupportedException()
 
     def save(self, size=0):
         """
         Save all changes to data to storage.
         """
-        raise NotSupportedException()
+        raise exceptions.NotSupportedException()
 
     def get_mode(self):
         return self.storage.get_mode(self.mode)
@@ -2768,27 +3741,208 @@
             except Exception, e:
                 self.logger.warning("Invalid BMP-file: %s" % resource.get_path())
         
+
+class currentdir(object):
+    def __init__(self, storage, curdir):
+        self.storage = storage
+        # make sure that the curdir does not contain path prefix
+        self.curdir = curdir.lstrip('/')
+
+    def __enter__(self):
+        self.storage.push(self.curdir)
+
+    def __exit__(self, type, value, tb):
+        self.storage.pop()
+
+
 class Folder(object):
     """
     A Folder object is a subfolder of a Storage, offering access to part of the Storages resources.
     """
-    def __init__(self, storage, path):
+    def __init__(self, storage, path, **kwargs):
         """
         Create a layer folder to the storage if it does not exist.
         """
-        #if not storage.is_folder(path):
-        #    storage.create_folder(path)
-        self.storage = copy.copy(storage)
-        self.storage.set_current_path(path)
-
-    def __getattr__(self, name):
-        return getattr(self.storage, name)
-
-class CompositeLayer(object):
+        self.curpath = path
+        self.storage = storage
+
+    def set_path(self, path):
+        """
+        """
+        self.curpath = path
+
+    def get_path(self):
+        """
+        """
+        return self.curpath
+
+    def set_current_path(self, path):
+        """
+        @param path: the current path under the Storage. 
+        """
+        self.curpath = utils.resourceref.remove_end_slash(utils.resourceref.remove_begin_slash(path))
+
+    def get_current_path(self):
+        """
+        get the current path under the Storage. 
+        """
+        return self.curpath
+
+    def close(self):
+        """
+        Close the repository, which will save and close all open resources.  
+        """
+        self.storage.close()
+
+    def save(self):
+        """
+        Flush changes from all resources to the repository.  
+        """        
+        return self.storage.save()
+
+    def open_resource(self, path, mode="r"):
+        """
+        Open the given resource and return a File object.
+        @param path : reference to the resource 
+        @param mode : the mode in which to open. Can be one of r = read, w = write, a = append.
+        raises a NotResource exception if the ref item is not a resource.
+        """  
+        with currentdir(self.storage, self.curpath):
+            res = self.storage.open_resource(path, mode)
+            return res
+        
+    def delete_resource(self, path):
+        """
+        Delete the given resource from storage
+        @param path: reference to the resource 
+        raises a NotSupportedException exception if delete operation is not supported by the storage
+        """  
+        with currentdir(self.storage, self.curpath):
+            res = self.storage.delete_resource(path)
+            return res
+
+    def close_resource(self, path):
+        """
+        Close a given resource instance. Normally this is called by the Resource object 
+        in its own close.
+        @param path the reference to the resource to close. 
+        """
+        with currentdir(self.storage, self.curpath):
+            res = self.storage.close_resource(path)
+            return res
+
+    def is_resource(self, path):
+        """
+        Return true if the ref is a resource
+        @param ref : reference to path where resources are searched
+        """
+        with currentdir(self.storage, self.curpath):
+            res = self.storage.is_resource(path)
+            return res
+
+    def list_resources(self, path, **kwargs):
+        """
+        find the resources under certain ref/path 
+        @param ref : reference to path where resources are searched
+        @param recurse : defines whether to return resources directly under the path or does the listing recurse to subfolders. 
+        Default value is False. Set to True to enable recursion.
+        """  
+        with currentdir(self.storage, self.curpath):
+            res = self.storage.list_resources(path, **kwargs)
+            return res
+
+    def import_resources(self, paths, storage):
+        """
+        import resources from a list of resources to this storage
+        @param paths : a list of Resourse objects.
+        @param storage : the external storage from which files are imported.
+        """  
+        with currentdir(self.storage, self.curpath):
+            res = self.storage.import_resources(paths, storage)
+            return res
+
+    def export_resources(self, paths, storage):
+        """
+        export resources from this storage based on a list of reference to this storage
+        @param path : a list of resource paths in this storage (references).
+        @param storage : the external storage where to export.
+        """  
+        with currentdir(self.storage, self.curpath):
+            res = self.storage.export_resources(paths, storage)
+            return res
+
+    def save_resource(self, path):
+        """
+        Flush the changes of a given resource instance. Normally this is called by the Resource object 
+        in its own save.
+        @param ref the reference to the resource to close. 
+        """
+        with currentdir(self.storage, self.curpath):
+            res = self.storage.save_resource(path)
+            return res
+
+    def create_folder(self, path):
+        """
+        Create a folder entry to a path
+        @param path : path to the folder
+        """  
+        with currentdir(self.storage, self.curpath):
+            res = self.storage.create_folder(path)
+            return res
+
+    def delete_folder(self, path):
+        """
+        Delete a folder entry from a path. The path must be empty.
+        @param path : path to the folder
+        """  
+        with currentdir(self.storage, self.curpath):
+            res = self.storage.delete_folder(path)
+            return res
+
+    def is_folder(self, path):
+        """
+        Check if the given path is an existing folder in the storage
+        @param path : path to the folder
+        """
+        with currentdir(self.storage, self.curpath):
+            res = self.storage.is_folder(path)
+            return res
+
+    def get_mode(self, mode_str):
+        return self.storage.get_mode()
+
+    def unload(self, path, object):
+        """
+        Dump a given object to the storage 
+        @param object: The object to dump to the storage, which is expected to be an instance 
+        of Base class.
+        @param path: The reference where to store the object 
+        @param object: The object instance to dump 
+        @raise StorageException: if the given object cannot be dumped to this storage 
+        """
+        with currentdir(self.storage, self.curpath):
+            res = self.storage.unload(path, object)
+            return res
+
+    def load(self, path):
+        """
+        Load an object from a reference.
+        @param path: The reference where to load the object 
+        @raise StorageException: if the given object cannot be loaded as an object from this storage 
+        """
+        with currentdir(self.storage, self.curpath):
+            res = self.storage.load(path)
+            return res
+
+    path = property(get_path, set_path)
+
+
+class CompositeLayer(Folder):
     """
     A base class for composite Configuration objects.  
     """
-    def __init__(self, path="", **kwargs):
+    def __init__(self, storage, path="", **kwargs):
+        super(CompositeLayer, self).__init__(storage, path, **kwargs)
         self.layers = kwargs.get('layers', [])
         self.path = path
 
@@ -2850,18 +4004,29 @@
                 lres.append(utils.resourceref.join_refs([layerpath, respath]))
         return lres
 
-    def list_all_resources(self, empty_folders=False):
+    def list_all_resources(self, **kwargs):
         """
         Returns a list of all layer related resource paths with full path in the storage.
         """
         lres = []
         for layerpath in self.list_layers():
             sublayer = self.get_layer(layerpath)
-            for respath in sublayer.list_all_resources(empty_folders):
+            for respath in sublayer.list_all_resources(**kwargs):
                 lres.append(utils.resourceref.join_refs([layerpath, respath]))
-                
         return lres
-
+    
+    def list_all_related(self, **kwargs):
+        """
+        Returns a list of all (non confml) layer related resource paths with full path in the storage.
+        """
+        lres = []
+        for layerpath in self.list_layers():
+            sublayer = self.get_layer(layerpath)
+            for respath in sublayer.list_all_related(**kwargs):                
+                lres.append(utils.resourceref.join_refs([layerpath, respath]))
+        
+        return lres
+    
 class Layer(CompositeLayer):
     """
     A Layer object is a subfolder of a Storage, offering access to part of the Storages resources.
@@ -2876,11 +4041,9 @@
         @param content_path: optional parameter for content files path (give in content_path="something")
         @param doc_path: optional parameter for doc files path (give in doc_path="something")
         """
-        super(Layer, self).__init__(path, **kwargs)
+        super(Layer, self).__init__(storage, path, **kwargs)
         #if not storage.is_folder(path):
         #    storage.create_folder(path)
-        self.storage = copy.copy(storage)
-        self.storage.set_current_path(path)
         self.predefined = {'confml_path' : 'confml', 
                            'implml_path' : 'implml', 
                            'content_path' : 'content', 
@@ -2894,11 +4057,26 @@
     def __getattr__(self, name):
         return getattr(self.storage, name)
 
+    def __getstate__(self):
+        state = {}
+        state['predefined'] = self.predefined
+        state['path'] = self.path
+        state['layers'] = self.layers
+        return state
+
+    def __setstate__(self, state):
+        state = {}
+        self.predefined = state.get('predefined',{})
+        self.path = state.get('path','')
+        self.layers = state.get('layers',[])
+        
+        return state
+    
     def list_confml(self):
         """
         @return: array of confml file references.
         """
-        res = self.storage.list_resources(self.predefined['confml_path'], True)
+        res = self.list_resources(self.predefined['confml_path'], recurse=True)
         res += super(Layer, self).list_confml()
         return res 
 
@@ -2906,7 +4084,7 @@
         """
         @return: array of implml file references.
         """
-        res = self.storage.list_resources(self.predefined['implml_path'], True)
+        res = self.list_resources(self.predefined['implml_path'], recurse=True)
         res += super(Layer, self).list_implml()
         return res 
 
@@ -2914,7 +4092,7 @@
         """
         @return: array of content file references.
         """
-        res = self.storage.list_resources(self.predefined['content_path'], True)
+        res = self.list_resources(self.predefined['content_path'], recurse=True)
         res += super(Layer, self).list_content()
         return res
 
@@ -2922,59 +4100,85 @@
         """
         @return: array of document file references.
         """
-        res = self.storage.list_resources(self.predefined['doc_path'], True)
+        res = self.list_resources(self.predefined['doc_path'], recurse=True)
         res += super(Layer, self).list_doc()
         return res
 
     def confml_folder(self):
-        cpath = self.storage.get_current_path()
+        cpath = self.get_current_path()
         spath = self.predefined['confml_path']
         return Folder(self.storage,  utils.resourceref.join_refs([cpath, spath]))
 
     def implml_folder(self):
-        cpath = self.storage.get_current_path()
+        cpath = self.get_current_path()
         spath = self.predefined['implml_path']
         return Folder(self.storage,  utils.resourceref.join_refs([cpath, spath]))
 
     def content_folder(self):
-        cpath = self.storage.get_current_path()
+        cpath = self.get_current_path()
         spath = self.predefined['content_path']
         return Folder(self.storage,  utils.resourceref.join_refs([cpath, spath]))
 
     def doc_folder(self):
-        cpath = self.storage.get_current_path()
+        cpath = self.get_current_path()
         spath = self.predefined['doc_path']
         return Folder(self.storage,  utils.resourceref.join_refs([cpath, spath]))
 
-    def list_all_resources(self, empty_folders=False):
+    def list_all_resources(self, **kwargs):
         """
         Returns a list of all layer related resource paths with full path in the storage.
         """
         lres = []
-        mypath = self.get_current_path()
-        
         for folderpath in sorted(self.predefined.values()):
-            lres += self.storage.list_resources(folderpath, recurse=True, empty_folders=empty_folders)
+            lres += self.list_resources(folderpath, recurse=True)
                  
-        lres += super(Layer, self).list_all_resources(empty_folders)
-        
+        lres += super(Layer, self).list_all_resources()
         return lres
 
-    def list_all_related(self, empty_folders=False):
+    def list_all_related(self, **kwargs):
         """
         Returns a list of all (non confml) layer related resource paths with full path in the storage.
         """
+        
         lres = []
+        exclude_filters = kwargs.get('exclude_filters', {})
+        kwargs['recurse'] = True
         predef = self.predefined.copy()
         del predef['confml_path']
-        mypath = self.get_current_path()
         for folderpath in sorted(predef.values()):
-            lres += self.storage.list_resources(folderpath, recurse=True, empty_folders=empty_folders)
-        lres += super(Layer, self).list_all_resources(empty_folders=empty_folders)
+            filter = exclude_filters.get(folderpath, None)
+            resources = self.list_resources(folderpath, **kwargs)
+            if filter:
+                lres += [res for res in resources if not re.search(filter, res, re.IGNORECASE)]
+            else:            
+                lres += resources
+        lres += super(Layer, self).list_all_related(**kwargs)
        
         return lres
 
 
+class Include(Base, container.LoadLink):
+    """
+    A common include element that automatically loads a resource 
+    and its object under this include element.
+    """
+    def __init__(self, ref="", **kwargs):
+        path = kwargs.get('path') or ref
+        store_interface = kwargs.get('store_interface',None)
+        ref = utils.resourceref.to_objref(path)
+        container.LoadLink.__init__(self, path, store_interface)
+        Base.__init__(self, ref)
+    
+    def get_store_interface(self):
+        if not self._storeint and self._parent:
+            try:
+                self._storeint = self._parent.get_store_interface()
+            except exceptions.NotFound:
+                # If project is not found, let the store interface be None 
+                pass
+        return self._storeint
+
+
 class Rule(object):
     """
     Base class for Rules in the system.
@@ -3007,7 +4211,104 @@
     return mapmodule.public.mapping.BaseMapper()
 
 
-##################################################################
+class Problem(object):
+    SEVERITY_ERROR      = "error"
+    SEVERITY_WARNING    = "warning"
+    SEVERITY_INFO       = "info"
+    
+    def __init__(self, msg, **kwargs):
+        self.msg = msg
+        self.type = kwargs.get('type', '')
+        self.line = kwargs.get('line', None)
+        self.file = kwargs.get('file', None)
+        self.severity = kwargs.get('severity', self.SEVERITY_ERROR)
+        self.traceback = kwargs.get('traceback', None)
+        # A slot for any problem specific data 
+        self.problem_data = kwargs.get('problem_data', None)
+    
+    def log(self, logger, current_file=None):
+        """
+        Log this problem with the given logger.
+        """
+        file = self.file or current_file
+        if self.line is None:
+            msg = "(%s) %s" % (file, self.msg)
+        else:
+            msg = "(%s:%d) %s" % (file, self.line, self.msg)
+        
+        mapping = {self.SEVERITY_ERROR:   logging.ERROR,
+                   self.SEVERITY_WARNING: logging.WARNING,
+                   self.SEVERITY_INFO:    logging.INFO}
+        level = mapping.get(self.severity, logging.ERROR)
+        logger.log(level, msg)
+        
+        if self.traceback:
+            logger.debug(self.traceback)
+    
+    @classmethod
+    def from_exception(cls, ex):
+        """
+        Create a Problem object from an exception instance.
+        
+        If the exception is a sub-class of ConeException, then it may contain
+        extra information (like a line number) for the problem.
+        """
+        if isinstance(ex, exceptions.ConeException):
+            return Problem(msg      = ex.problem_msg or unicode(ex),
+                           type     = ex.problem_type or '',
+                           line     = ex.problem_lineno,
+                           severity = cls.SEVERITY_ERROR)
+        else:
+            return Problem(msg      = unicode(ex),
+                           severity = cls.SEVERITY_ERROR)
+    
+    def __repr__(self):
+        var_data = []
+        for varname in ('msg', 'type', 'line', 'file', 'severity'):
+            var_data.append("%s=%r" % (varname, getattr(self, varname)))
+        return "%s(%s)" % (self.__class__.__name__, ', '.join(var_data))
+    
+    def __eq__(self, other):
+        if not isinstance(other, Problem):
+            return False
+        for varname in ('msg', 'type', 'line', 'file', 'severity'):
+            self_val = getattr(self, varname)
+            other_val = getattr(other, varname)
+            if self_val != other_val:
+                return False
+        return True
+    
+    def __ne__(self, other):
+        return self == other
+    
+    def __lt__(self, other):
+        if not isinstance(other, Problem):
+            return False
+        return (self.file, self.line) < (other.file, other.line)
+
+def make_content_info(resource, data):
+    """
+    Factory for ContentInfo
+    """
+    cnt_inf = None
+    
+    if resource != None:
+        guessed_type = mimetypes.guess_type(resource.get_path())
+        mimetype = None
+        mimesubtype = None
+        
+        if guessed_type != None:
+            mimetype, mimesubtype = guessed_type[0].split('/') 
+        
+        if mimetype == 'image' and mimesubtype == 'x-ms-bmp':
+            cnt_inf = BmpImageContentInfo(resource, data)
+        else:
+            cnt_inf = ContentInfo(mimetype, mimesubtype)
+    return cnt_inf
+
+def open_storage(path, mode="r", **kwargs):
+    return Storage.open(path, mode="r", **kwargs)
+
 class NullHandler(logging.Handler):
     """
     Default handler that does not do anything.
--- a/configurationengine/source/cone/public/container.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/public/container.py	Tue Aug 10 14:29:28 2010 +0300
@@ -22,7 +22,8 @@
 import re
 import pickle
 import logging
-import utils, exceptions
+import utils
+from cone.public import exceptions
 
 def object_container_filter(obj,**kwargs):
     """ Create a list of filter functions for each argument """ 
@@ -137,7 +138,35 @@
         return self.data.clear()
 
 class ContainerBase(object):
+    def __init__(self, name="",**kwargs):
+        if len(name.split(".")) > 1 or len(name.split("/")) > 1:
+            raise exceptions.InvalidRef("Illegal name for ObjectContainer %s" % name)
+        self._name = name
+        self._parent = None
+        self._order = []
+        self._children = {}
+        self._respath = ""
+        for arg in kwargs.keys():
+            setattr(self, arg, kwargs.get(arg))
+
+    def __getstate__(self):
+        state = {}
+        if self._parent: state['_parent'] = self._parent
+        if self._order: state['_order'] = self._order
+        if self._children: state['_children'] = self._children
+        if self._respath: state['_respath'] = self._respath
+        return state
     
+    def __setstate__(self, state):
+        self._name = state.get('ref','')
+        self._parent = state.get('_parent',None)
+        self._order = state.get('_order',[])
+        self._children = state.get('_children',{})
+        self._respath = state.get('_respath',"")
+        # update the parent link for all the children of this object
+        for child in self._objects():
+            child._parent = self
+
     def _set_parent(self, newparent):
         """
         @param newparent:  The new parent object
@@ -157,6 +186,18 @@
         """
         self._parent = None
 
+    def get_store_interface(self):
+        """
+        Get a possible store interface for this ContainerBase object
+        """
+        return None
+
+    def get_path(self):
+        """
+        Return the path of the object
+        """
+        return self._respath
+
     parent = property(_get_parent, _set_parent,_del_parent)
 
 
@@ -189,7 +230,7 @@
 
 class LoadInterface(ContainerBase):
     def load(self,ref):
-        file = open(ref,"r")
+        file = open(ref,"rb")
         self._parent = None
         return pickle.load(file)
 
@@ -197,7 +238,7 @@
         """
         unload or release
         """
-        file = open(ref,"w")
+        file = open(ref,"wb")
         pickle.dump(obj,file)
         file.close()
 
@@ -207,138 +248,6 @@
         """
         return ""
 
-class LoadProxy(ContainerBase):
-    """
-    This class is meant for loading & unloading an object, when it need.
-    """
-    def __init__(self, path, store_interface=None):
-        """
-        @param path: the path which is used in loadin
-        @param store_interface: the loading interface object, which is used. 
-        Expects load(path) and dump(obj) functions  
-        """
-        self.set('_obj', None)
-        self.set('_parent', None)
-        self.set('path', path)
-        self.set('_storeint', store_interface)
-
-    def __getattr__(self,name):
-        """
-        direct all not found attribute calls to the sub object getattr
-        """
-        if not self._obj: 
-            self._load()
-        return getattr(self._obj,name)
-
-    def __setattr__(self, name, value):
-        """
-        direct attribute setting calls to the sub object setattr
-        """
-        if not self._obj: 
-            self._load()
-        setattr(self._obj,name,value)
-
-    def __delattr__(self, name):
-        """
-        direct attribute setting calls to the sub object setattr
-        """
-        if not self._obj: 
-            self._load()
-        delattr(self._obj,name)
-
-    def _set_parent(self, newparent):
-        """
-        @param newparent:  The new parent object
-        @return: None
-        """
-        self.set('_parent',newparent)
-        if self._obj:
-            self._obj._parent = self._parent
-
-    def _set_obj(self, obj):
-        self.set('_obj',obj)
-        # set the same _parent for the actual object as is stored for the proxy
-        self._obj._parent = self._parent
-        self._obj.set_path(self.path)
-
-    def _get_obj(self):
-        if not self._obj: 
-            self._load()
-        return self._obj
-
-    def _load(self):
-        # Should the loading of layer external resources be supported?
-        # E.g. resources with absolute path relative to the storage (starts with slash)
-        """ If the loading of the object fails => Raise an InvalidObject exception """ 
-        try:
-            obj = self._store_interface().load(self.fullpath)
-            self._set_obj(obj)
-            obj.set_ref(utils.resourceref.to_objref(self.path))
-        except exceptions.NotResource,e:
-            logging.getLogger('cone').warning("Loading %s from parent %s failed! %s" % (self.path,self.get_parent_path(), e))
-            raise exceptions.InvalidObject("Invalid configuration object %s" % self.path)
-
-    def _unload(self):
-        if self._obj:
-            self._store_interface().unload(self.fullpath, self._obj)
-            self.set('_obj',None)
-
-    def _store_interface(self):
-        if not self._storeint:
-            self.set('_storeint',self._parent.get_project())
-        return self._storeint
-
-    def set(self,name,value):
-        """
-        Proxy has a specific attribute setting function, because by default all attributes are 
-        stored to the actual proxy object  
-        """
-        self.__dict__[name] = value
-
-    def get(self,name):
-        """
-        Proxy has also a specific attribute getting function, because by default all attributes are 
-        stored to the actual proxy object  
-        """
-        return self.__dict__[name]
-
-    def save(self):
-        if hasattr(self._obj,'save'):
-            self._obj.save()
-        self._unload()
-
-    def close(self):
-        if hasattr(self._obj,'close'):
-            self._obj.close()
-
-    def get_parent_path(self):
-        """
-        Return the path of the configuration resource
-        """
-        if self._parent:
-            return utils.resourceref.get_path(self._parent.get_path())
-        else:
-            return ""
-
-    def get_path(self):
-        """
-        Return the path of the configuration resource
-        """
-        if self._obj:
-            return self._obj.get_path()
-        else:
-            return self.path
-
-    @property
-    def fullpath(self):
-        """
-        Return the path of the configuration resource
-        """
-        try:
-            return self._obj.get_full_path() 
-        except AttributeError:
-            parent_path = self.get_parent_path() 
-            return utils.resourceref.join_refs([parent_path,self.path])
 
 class ObjectContainer(ContainerBase):
     """
@@ -348,14 +257,7 @@
     def __init__(self,name="",**kwargs):
         """
         """
-        if len(name.split(".")) > 1 or len(name.split("/")) > 1:
-            raise exceptions.InvalidRef("Illegal name for ObjectContainer %s" % name)
-        self._name = name
-        self._parent = None
-        self._order = []
-        self._children = {}
-        for arg in kwargs.keys():
-            setattr(self, arg, kwargs.get(arg))
+        super(ObjectContainer,self).__init__(name, **kwargs)
 
     def __getattr__(self,name):
         """
@@ -364,7 +266,10 @@
         try:
             return self.__dict__['_children'][name]
         except KeyError:
-            return getattr(super(ObjectContainer),name)
+            try:
+                return getattr(super(ObjectContainer),name)
+            except AttributeError,e:
+                raise AttributeError("%s object has not attribute '%s'" % (self.__class__, name))
 
     def _path(self, toparent=None):
         """
@@ -384,13 +289,32 @@
         else:
             return self._name
     
-    def _add(self, child, policy=REPLACE):
+    def _add(self, child_or_children, policy=REPLACE):
         """
-        Add a child object. 
-        @param child: The child object to add. The child needs to be an instance of ObjectContainer. 
+        Add a child object or multiple child objects. 
+        @param child_or_children: The child object or list of child objects to add.
+            The children need to be instances of ObjectContainer. 
         @param policy: The policy which is used when an object with same name exists already  
         """
+        if isinstance(child_or_children, list):
+            objs = child_or_children
+            if policy == PREPEND:
+                objs = reversed(objs)
+                policy_first = PREPEND
+                policy_rest = PREPEND
+            else:
+                policy_first = policy
+                policy_rest = APPEND
+            
+            for i, obj in enumerate(objs):
+                if i == 0:  p = policy_first
+                else:       p = policy_rest
+                self._add(obj, p)
+            return
+        
+        
         # check that the child is a supported type
+        child = child_or_children
         if not self._supported_type(child):
             raise exceptions.IncorrectClassError("Cannot add instance of %s to %s." % (child.__class__,self.__class__))
         if policy == REPLACE:
@@ -443,12 +367,17 @@
             if not child._name.startswith('?'):
                 self._order.append(child._name)
         else:
-            """ if the existing child is a instance of ObjectContainer, 
-                add all children of the existing contianer to this new object """
+            """ 
+            if the existing child is a instance of ObjectContainer, 
+            add all children of the existing container to this new object, except if the 
+            child already exists in the new child. 
+            """
             existingchild = self._children[child._name]
             if isinstance(existingchild, ObjectContainer):
                 for subchild in existingchild._objects():
-                     child._add(subchild)
+                    if not child._children.has_key(subchild._name):
+                        child._add(subchild)
+                     
         
         self._children[child._name] = child
         return
@@ -508,8 +437,8 @@
                     curelem = utils.get_list(curelem._children[name])[index]
             return curelem
         # Catch the KeyError exception from dict and IndexError from list
-        except (KeyError,IndexError): 
-            raise exceptions.NotFound("Child %s not found!" % path)
+        except (KeyError,IndexError), e: 
+            raise exceptions.NotFound("Child %s not found from %s! %s" % (path, self, e))
 
     def _has(self, path):
         """
@@ -545,7 +474,9 @@
                 del self._order[self._order.index(name)]
         elif self._get(path) != None: # delete if the child is found
             del self._children[path]
-            del self._order[self._order.index(path)]
+            # hidded children are not added to the order list 
+            if not path.startswith('?'):
+                del self._order[self._order.index(path)]
             
         else:
             raise exceptions.NotFound("Child %s not found!" % path)
@@ -565,6 +496,8 @@
         given as dict, so they must be given with name. E.g. _traverse(name='test')
         @param name: The node name or part of name which is used as a filter. This is a regular expression (uses internally re.match()) 
         @param path: The path name or part of name which is used as a filter. This is a regular expression (uses internally re.match())
+        @param type: The type (class) of the objects that should be returned (this can be a tuple of types)
+        @param depth: The max recursion depth that traverse goes through. 
         @param filters: A list of predefined filters can be given as lambda functions. E.g. filters=[lambda x: isinstance(x._obj, FooClass)]  
         @return: a list of ObjectContainer objects.
         """
@@ -582,7 +515,7 @@
 
         ret = []
         for child in self._objects():
-            subchildren = child._tail_recurse(_apply_filter,filters=filterlist)
+            subchildren = child._tail_recurse(_apply_filter,filters=filterlist,depth=kwargs.get('depth',-1))
             ret += subchildren
         return ret
     
@@ -611,20 +544,25 @@
         @param kwargs: a list of arguments as dict
         @return: an list of objects, which can be anything that the funtion returns   
         """
-        
+        depth = kwargs.get('depth',-1)
         ret = []
-        ret += function(self,**kwargs)
-        for child in self._objects():
-            try:
-                # We wont add the object to the ret until we know that it is a valid object
-                subchildren = child._tail_recurse(function,**kwargs)
-                #ret += function(child,**kwargs)
-                ret += subchildren
-            except exceptions.InvalidObject,e:
-                # remove the invalid object from this container
-                logging.getLogger('cone').warning('Removing invalid child because of exception %s' % e)
-                self._remove(child._name)
-                continue
+        # check the if the recursion maximum depth has been reached
+        # if not reached but set, decrease it by one and set that to subrecursion
+        if depth != 0:
+            ret += function(self,kwargs.get('filters',[]))
+            kwargs['depth'] = depth - 1
+            for child in self._objects():
+                try:
+                    # We wont add the object to the ret until we know that it is a valid object
+                    subchildren = child._tail_recurse(function,**kwargs)
+                    #ret += function(child,**kwargs)
+                    ret += subchildren
+                except exceptions.InvalidObject,e:
+                    # remove the invalid object from this container
+                    logging.getLogger('cone').warning('Removing invalid child because of exception %s' % e)
+                    self._remove(child._name)
+                    continue
+        
         return ret
 
     def _head_recurse(self, function,**kwargs):
@@ -695,7 +633,7 @@
         This function should be overloaded by a subclass if the supported types need to be changed.
         @return: True if object is supported, otherwise false.  
         """
-        return isinstance(obj, ObjectContainer)
+        return isinstance(obj, (ObjectContainer,ContainerBase))
 
     def _default_object(self,name):
         """
@@ -773,6 +711,13 @@
         """
         return self.ref
 
+    def has_ref(self, ref):
+        """
+        Check if object container contains the given reference.
+        @param ref: reference
+        """
+        return self._has(ref)
+
 class ObjectProxyContainer(ObjectProxy,ObjectContainer):
     """
     Combines the Container and Proxy classes to one.
@@ -792,3 +737,317 @@
             return self.__dict__['_children'][name] 
         except KeyError:
             return getattr(self._obj,name)
+
+class LoadContainer(ContainerBase):
+    """
+    This class is meant for loading & unloading an object(s), to a ObjectContainer. 
+    The loading is done if the object container methods are accessed.
+    """
+    def __init__(self, path, store_interface=None):
+        """
+        @param path: the path which is used in loading
+        @param store_interface: the loading interface object, which is used. 
+        Expects load(path) and dump(obj) functions  
+        """
+        super(LoadContainer, self).__init__()
+        self._parent = None
+        self._container = None
+        self._storeint = store_interface
+        self._respath = path
+    
+    def __getattr__(self,name):
+        """
+        Load the container objects if they are not allready loaded
+        """
+        if not self._container:
+            self._load()
+        return getattr(self._container,name)
+    
+    def _load(self):
+        """ If the loading of the object fails => Raise an InvalidObject exception """ 
+        try:
+            self._container = ObjectContainer()
+            # this should be modified to support loading multiple elements 
+            intf = self.get_store_interface()
+            # Do not try to load the objects if interface cannot be found
+            if intf:
+                obj = intf.load(self.get_full_path())
+                self._container._add(obj)
+        except exceptions.NotResource,e:
+            logging.getLogger('cone').warning("Loading %s from parent %s failed! %s" % (self.path,self.get_parent_path(), e))
+            raise exceptions.InvalidObject("Invalid configuration object %s" % self.path)
+
+    def _unload(self):
+        # go through objects in the container
+        intf = self.get_store_interface()
+        for obj in self._container._objects():
+            # remove the parent link 
+            obj._parent = None
+            if intf:
+                intf.unload(self.get_full_path(), obj)
+            self._container._remove(obj._name)
+        # set the container back to None
+        self._container = None
+        
+    def get_store_interface(self):
+        if not self._storeint and self._parent:
+            try:
+                self._storeint = self._parent.get_store_interface()
+            except exceptions.NotFound:
+                # If project is not found, let the store interface be None 
+                pass
+        return self._storeint
+
+    def get_parent_path(self):
+        """
+        Return the path of the configuration resource
+        """
+        if self._parent:
+            return utils.resourceref.get_path(self._parent.get_path())
+        else:
+            return ""
+
+    def get_full_path(self, obj=None):
+        """
+        Return the path of the configuration resource
+        """
+        if obj != None:
+            try:
+                return obj.get_full_path()
+            except AttributeError:
+                pass
+        # default path processing returns the fullpath of this elem
+        parent_path = self.get_parent_path() 
+        return utils.resourceref.join_refs([parent_path,self.get_path()])
+
+
+class LoadLink(ContainerBase):
+    """
+    This class is meant for loading & unloading an object(s), to a ObjectContainer. 
+    The loading is done if the object container methods are accessed.
+    """
+    def __init__(self, path, store_interface=None):
+        """
+        @param path: the path which is used in loading
+        @param store_interface: the loading interface object, which is used. 
+        Expects load(path) and dump(obj) functions  
+        """
+        super(LoadLink, self).__init__()
+        self._parent = None
+        self._loaded = False
+        self._storeint = store_interface
+        self._respath = path
+    
+    def populate(self):
+        """
+        Populate the object to the parent
+        """
+        if self._parent == None:
+            raise exceptions.NoParent("Cannot populate a LoadLink object without existing parent object")
+        if not self._loaded:
+            for obj in self._load():
+                self._parent._add(obj)
+    
+    def _load(self):
+        """ If the loading of the object fails => Raise an InvalidObject exception """ 
+        objs = []
+        try:
+            # this should be modified to support loading multiple elements 
+            intf = self.get_store_interface()
+            # Do not try to load the objects if interface cannot be found
+            if intf:
+                obj = intf.load(self.get_full_path())
+                objs.append(obj)
+        except exceptions.NotResource,e:
+            logging.getLogger('cone').warning("Loading %s from parent %s failed! %s" % (self.path,self.get_parent_path(), e))
+            raise exceptions.InvalidObject("Invalid configuration object %s" % self.path)
+        return objs
+    
+    def _unload(self):
+        pass
+    
+    def get_store_interface(self):
+        if not self._storeint and self._parent:
+            try:
+                self._storeint = self._parent.get_store_interface()
+            except exceptions.NotFound:
+                # If project is not found, let the store interface be None 
+                pass
+        return self._storeint
+
+    def get_parent_path(self):
+        """
+        Return the path of the configuration resource
+        """
+        if self._parent:
+            return utils.resourceref.get_path(self._parent.get_path())
+        else:
+            return ""
+
+    def get_full_path(self, obj=None):
+        """
+        Return the path of the configuration resource
+        """
+        if obj != None:
+            try:
+                return obj.get_full_path()
+            except AttributeError:
+                pass
+        # default path processing returns the fullpath of this elem
+        parent_path = self.get_parent_path() 
+        return utils.resourceref.join_refs([parent_path,self.get_path()])
+
+
+class LoadProxy(ContainerBase):
+    """
+    This class is meant for representing any object loading & unloading an object, 
+    when it is actually needed.  
+    object 
+    """
+    def __init__(self, path, store_interface=None):
+        """
+        @param path: the path which is used in loadin
+        @param store_interface: the loading interface object, which is used. 
+        Expects load(path) and dump(obj) functions  
+        """
+        self.set('_obj', None)
+        self.set('_parent', None)
+        self.set('path', path)
+        self.set('_storeint', store_interface)
+
+    def __getattr__(self,name):
+        """
+        direct all not found attribute calls to the sub object getattr
+        """
+        if not self._obj: 
+            self._load()
+        return getattr(self._obj,name)
+
+    def __getstate__(self):
+        """
+        Return a state which should have sufficient info to load the proxy object but 
+        dont serialize the object itself.
+        """
+        state = {}
+        state['path'] = self.path
+        state['_obj'] = None
+        # state['_parent'] = self._parent
+        state['_storeint'] = self._storeint
+        return state
+    
+    def __setstate__(self, state):
+        self.set('_obj', state.get('_obj',None))
+        self.set('_storeint', state.get('_storeint',None))
+        self.set('_parent', state.get('_parent',self._storeint))
+        self.set('path', state.get('path',''))
+
+    def __setattr__(self, name, value):
+        """
+        direct attribute setting calls to the sub object setattr
+        """
+        if not self._obj: 
+            self._load()
+        setattr(self._obj,name,value)
+
+    def __delattr__(self, name):
+        """
+        direct attribute setting calls to the sub object setattr
+        """
+        if not self._obj: 
+            self._load()
+        delattr(self._obj,name)
+
+    def _set_parent(self, newparent):
+        """
+        @param newparent:  The new parent object
+        @return: None
+        """
+        self.set('_parent',newparent)
+        if self._obj:
+            self._obj._parent = self._parent
+
+    def _set_obj(self, obj):
+        self.set('_obj',obj)
+        # set the same _parent for the actual object as is stored for the proxy
+        if self._obj:
+            self._obj._parent = self._parent
+            self._obj.set_path(self.path)
+
+    def _get_obj(self):
+        if not self._obj: 
+            self._load()
+        return self._obj
+
+    def _load(self):
+        # Should the loading of layer external resources be supported?
+        # E.g. resources with absolute path relative to the storage (starts with slash)
+        """ If the loading of the object fails => Raise an InvalidObject exception """ 
+        try:
+            obj = self.get_store_interface().load(self.fullpath)
+            self._set_obj(obj)
+            obj.set_ref(utils.resourceref.to_objref(self.path))
+        except exceptions.NotResource,e:
+            logging.getLogger('cone').warning("Loading %s from parent %s failed! %s" % (self.path,self.get_parent_path(), e))
+            raise exceptions.InvalidObject("Invalid configuration object %s" % self.path)
+
+    def _unload(self):
+        if self._obj:
+            self.get_store_interface().unload(self.fullpath, self._obj)
+            self.set('_obj',None)
+
+    def get_store_interface(self):
+        if not self._storeint:
+            self.set('_storeint',self._parent.get_store_interface())
+        return self._storeint
+
+    def set(self,name,value):
+        """
+        Proxy has a specific attribute setting function, because by default all attributes are 
+        stored to the actual proxy object  
+        """
+        self.__dict__[name] = value
+
+    def get(self,name):
+        """
+        Proxy has also a specific attribute getting function, because by default all attributes are 
+        stored to the actual proxy object  
+        """
+        return self.__dict__[name]
+
+    def save(self):
+        if hasattr(self._obj,'save'):
+            self._obj.save()
+        self._unload()
+
+    def close(self):
+        if hasattr(self._obj,'close'):
+            self._obj.close()
+
+    def get_parent_path(self):
+        """
+        Return the path of the configuration resource
+        """
+        if self._parent:
+            return utils.resourceref.get_path(self._parent.get_path())
+        else:
+            return ""
+
+    def get_path(self):
+        """
+        Return the path of the configuration resource
+        """
+        if self._obj:
+            return self._obj.get_path()
+        else:
+            return self.path
+
+    @property
+    def fullpath(self):
+        """
+        Return the path of the configuration resource
+        """
+        try:
+            return self._obj.get_full_path() 
+        except AttributeError:
+            parent_path = self.get_parent_path() 
+            return utils.resourceref.join_refs([parent_path,self.path])
--- a/configurationengine/source/cone/public/exceptions.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/public/exceptions.py	Tue Aug 10 14:29:28 2010 +0300
@@ -17,7 +17,34 @@
 # @author Teemu Rytkonen
 
 class ConeException(Exception):
-    pass
+    """
+    Base class for ConE exceptions.
+    
+    The attributes ``problem_desc`` and ``problem_lineno`` contain a description of
+    the error and the line on which the error occurred, if available.
+    The exception message itself may be composed of these two to make it more
+    readable, but it may also just be the same as the description.
+    
+    @message: Exception message.
+    @param problem_lineno: The line number for api.Problem conversion. Can be None to
+        signify that the line number is not available.
+    @param problem_desc: Error description for api.Problem conversion. If None,
+        the exception message will be used here also.
+    @param problem_type: Problem type for api.Problem conversion. If None, the
+        class-level default will be used.
+    """
+    
+    #: Problem type for conversion to api.Problem.
+    #: A default can be set on the exception class level, but it may
+    #: also be set for individual exception instances.
+    problem_type = None
+    
+    def __init__(self, message='', problem_lineno=None, problem_msg=None, problem_type=None):
+        Exception.__init__(self, message)
+        self.problem_lineno = problem_lineno
+        self.problem_msg = problem_msg or message
+        if problem_type is not None:
+            self.problem_type = problem_type
 
 class NotSupportedException(ConeException):
     def __init__(self, message=""):
@@ -46,27 +73,19 @@
     pass
     
 class ParseError(ConeException):
-    """
-    Exception raised when invalid data is attempted to be parsed.
-    
-    The attributes ``desc`` and ``lineno`` contain a description of
-    the error and the line on which the error occurred, if available.
-    The exception message itself may be composed of these two to make it more
-    readable, but it may also just be the same as the description.
-    
-    @message: Exception message.
-    @param lineno: The line number where the error occurred. Can be None to
-        signify that the line number is not available.
-    @param desc: Error description. If None, the exception message will be
-        used here also.
-    """
-    def __init__(self, message, lineno=None, desc=None):
-        ConeException.__init__(self, message)
-        self.lineno = lineno
-        self.desc = desc or message
+    pass
 
 class XmlParseError(ParseError):
-    pass
+    problem_type = 'xml'
+
+class XmlSchemaValidationError(ParseError):
+    problem_type = 'schema'
+
+class ConfmlParseError(ParseError):
+    problem_type = 'model.confml'
+
+class ImplmlParseError(ParseError):
+    problem_type = 'model.implml'
 
 class IncorrectClassError(ConeException):
     pass
@@ -79,3 +98,10 @@
     operation an invalid object is encountered. 
     """
     pass
+
+class NameIdMappingError(ConeException):
+    """
+    Exception raised when resolving a name-ID mapped value fails.
+    """
+    pass
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/parsecontext.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,137 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+import threading
+import logging
+
+import cone.public.utils
+
+class ParseContext(object):
+    """
+    Parse context class for handling exceptions and problems encountered
+    when parsing a file (ConfML, ImplML or anything included from those).
+    
+    The context contains the path to the file that is currently being parsed,
+    but the file path can also be overridden when calling a handler method
+    (e.g. an ImplML file includes some other file, which in contains a problem).
+    
+    Sub-classes should override _handle_exception() and _handle_problem(),
+    NOT handle_exception() and handle_problem().
+    """
+    def __init__(self):
+        #: The file that is currently being parsed.
+        self.current_file = None
+    
+    def handle_exception(self, exception, file_path=None):
+        """
+        Handle an exception that occurred while parsing a file.
+        
+        @param exception: The exception that occurred.
+        @param file_path: Override for the name of the file that was being parsed.
+            If this is None, self.current_file is used.
+        """
+        if file_path is None:
+            file_path = self.current_file
+        
+        self._handle_exception(exception, file_path)
+    
+    def handle_problem(self, problem, file_path=None):
+        """
+        Handle a Problem that occurred while parsing a file.
+        
+        @param problem: The problem object.
+        @param file_path: Override for the name of the file that was being parsed.
+            If this is None, self.current_file is used.
+        """
+        if file_path is None:
+            file_path = self.current_file
+        
+        self._handle_problem(problem, file_path)
+    
+    def _handle_exception(self, exception, file_path):
+        """
+        Called to handle an exception that occurred while parsing a file.
+        
+        Note that this should always be called in an exception handler,
+        so you can safely use e.g. traceback.format_exc().
+        
+        @param exception: The exception that occurred.
+        @param file_path: The file that was being parsed.
+        """
+        cone.public.utils.log_exception(
+            logging.getLogger('cone'),
+            "Error parsing '%s': %s" % (file_path, str(exception)))
+    
+    def _handle_problem(self, problem, file_path):
+        """
+        Called when parsing a file yields a problem.
+        @param problem: The problem object.
+        @param file_path: Override for the name of the file that was being parsed.
+            If this is None, self.current_file is used.
+        """
+        problem.file = file_path
+        problem.log(logging.getLogger('cone'))
+
+# Thread-local storage for the contexts
+_contexts = threading.local()
+
+def _init_contexts():
+    """
+    Initialize thread-local contexts if they are not initialized yet.
+    """
+    if not hasattr(_contexts, 'implml'):
+        _contexts.implml = None
+        _contexts.confml = None
+        _contexts.implml_default = ParseContext()
+        _contexts.confml_default = ParseContext()
+
+def get_implml_context():
+    """
+    Get the current ImplML parse context.
+    """
+    _init_contexts()
+    if _contexts.implml is not None:
+        return _contexts.implml
+    else:
+        return _contexts.implml_default
+
+def set_implml_context(context):
+    """
+    Set the current ImplML parse context.
+    @param context: The context to set. If None, the default context
+        will be used.
+    """
+    _init_contexts()
+    _contexts.implml = context
+
+def get_confml_context():
+    """
+    Get the current ConfML parse context.
+    """
+    _init_contexts()
+    if _contexts.confml is not None:
+        return _contexts.confml
+    else:
+        return _contexts.confml_default
+
+def set_confml_context(context):
+    """
+    Set the current ConfML parse context.
+    @param context: The context to set. If None, the default context
+        will be used.
+    """
+    _init_contexts()
+    _contexts.confml = context
--- a/configurationengine/source/cone/public/plugin.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/public/plugin.py	Tue Aug 10 14:29:28 2010 +0300
@@ -18,13 +18,12 @@
 
 import sys
 import os
-import re
 import logging
-import sets
 import inspect
-import xml.parsers.expat
+import re
+import codecs
 
-from cone.public import exceptions, utils, api, container, settings, rules
+from cone.public import exceptions, utils, api, settings, rules, parsecontext
 import _plugin_reader
 
 debug = 0
@@ -69,34 +68,95 @@
     """
     return hasattr(feature, _plugin_reader.TEMP_FEATURE_MARKER_VARNAME)
 
-class GenerationContext(object):
+def uses_ref(refs, impl_refs):
+    """
+    Compare two lists of setting references and return whether any of the
+    references in ``refs`` is used in ``impl_refs``.
+    """
+    for ref in refs:
+        for impl_ref in impl_refs:
+            if ref.startswith(impl_ref):
+                if len(ref) == len(impl_ref):
+                    return True
+                elif ref[len(impl_ref)] == '.':
+                    return True
+    return False
+
+class GenerationContext(rules.DefaultContext):
     """
     Context object that can be used for passing generation-scope
     data to implementation instances.
     """
     
-    def __init__(self, tags={}):
+    def __init__(self, **kwargs):
         #: The tags used in this generation context
         #: (i.e. the tags passed from command line)
-        self.tags = tags
+        self.tags = kwargs.get('tags', {})
         
         #: The tags policy used in this generation context
-        self.tags_policy = "OR"
+        self.tags_policy = kwargs.get('tags_policy', "OR")
         
         #: A dictionary that implementation instances can use to
         #: pass any data between each other
         self.impl_data_dict = {}
         
-        #: A string for the phase of the generation
-        self.phase = ""
+        #: A string for the phase of the generation.
+        #: If None, no filtering based on phase is done when
+        #: running the implementations
+        self.phase = kwargs.get('phase', None)
         
         #: a list of rule results
         self.results = []
         
         #: a pointer to the configuration 
-        self.configuration = None
+        self.configuration = kwargs.get('configuration', None)
+        
+        #: If True, then all implementation filtering done by
+        #: should_run() is disabled, and it always returns True.
+        self.filtering_disabled = False
+        
+        #: if True, then the execution flow should normal except 
+        #: no output files are actually generated
+        self.dry_run= kwargs.get('dry_run', None)
+        
+        #: the output folder for generation
+        #: ensure already here that the output exists
+        self.output= kwargs.get('output', 'output')
+        
+        #: List of references of the settings that have been modified in 
+        #: listed layers and should trigger an implementation to be executed.
+        #: None if ref filtering is not used
+        self.changed_refs = kwargs.get('changed_refs', None)
+        
+        
+        #: A boolean flag to determine whether to use ref filtering or not
+        self.filter_by_refs = kwargs.get('filter_by_refs', False)
+        
+        #: Temp features
+        self.temp_features = kwargs.get('temp_features', [])
+        
+        #: Executed implementation objects. This is a set so that a 
+        #: implementation would exist only once in it. Even if it executed 
+        #: more than once. The generation_output will show the actual 
+        #: output several times if a implementation is executed several times.
+        self.executed = set()
+        
+        #: Set of all implementation objects in the configuration context 
+        self.impl_set = kwargs.get('impl_set', ImplSet())
+        
+        #: Generation output elements as a list 
+        self.generation_output = []
 
-    def eval(self, ast, expression, value):
+        #: possible log elemement 
+        self.log = []
+        self.log_file = ""
+
+    def __getstate__(self):
+        state = self.__dict__
+        state['impl_data_dict'] = {}
+        return state
+    
+    def eval(self, ast, expression, value, **kwargs):
         """
         eval for rule evaluation against the context
         """
@@ -107,31 +167,396 @@
         Handle a terminal object 
         """
         try:
-            if isinstance(expression, str): 
-                m = re.match("\${(.*)}", expression)
-                if m:
-                    try:
-                        dview = self.configuration.get_default_view()
-                        return dview.get_feature(m.group(1)).value
-                    except Exception, e:
-                        logging.getLogger('cone').error("Could not dereference feature %s. Exception %s" % (expression, e))
-                        raise e
-                elif expression in ['true','1','True']:
-                    return True
-                elif expression in ['false','0','False']:
-                    return False
-                else:
-                    try:
-                        return eval(expression)
-                    except NameError:
-                        # If the expression is a string in it self it can be returned
-                        return expression
-            else:
-                return expression
+            if isinstance(expression, basestring): 
+                try:
+                    dview = self.configuration.get_default_view()
+                    return dview.get_feature(expression).value
+                except Exception, e:
+                    logging.getLogger('cone').error("Could not dereference feature %s. Exception %s" % (expression, e))
+                    raise e
         except Exception,e:
             logging.getLogger('cone').error("Exception with expression %s: %s" % (expression, e))
             raise e
+    
+    def convert_value(self, value):
+        try:
+            # Handle some special literals
+            if value == 'true':     return True
+            if value == 'false':    return False
+            if value == 'none':     return None
+            
+            # Values can be any Python literals, so eval() the string to
+            # get the value
+            return eval(value)
+        except Exception:
+            ref_regex = re.compile('^[\w\.\*]*$', re.UNICODE) 
+            if ref_regex.match(value) is None:
+                raise RuntimeError("Could not evaluate '%s'" % value)
+            else:
+                raise RuntimeError("Could not evaluate '%s'. Did you mean a setting reference and forgot to use ${}?" % value)
+    
+    def set(self, expression, value, **kwargs):
+        log = logging.getLogger('cone.ruleml')
+        try:
+            feature = self.configuration.get_default_view().get_feature(expression)
+            feature.set_value(value)
+            
+            relation = kwargs.get('relation')
+            if relation:
+                log.info("Set %s = %r from %r" % (expression, value, relation))
+            else:
+                log.info("Set %s = %r" % (expression, value))
+            
+            refs = [feature.fqr]
+            if feature.is_sequence():
+                refs = ["%s.%s" % (feature.fqr,subref) for subref in feature.list_features()]
+                
+            self.add_changed_refs(refs, relation)
 
+            if relation:
+                self.generation_output.append(GenerationOutput(expression, 
+                                                               relation,
+                                                               type='ref'))
+            return True
+        except exceptions.NotFound,e:
+            log.error('Set operation for %s failed, because feature with that reference was not found! Exception %s', expression, e) 
+            raise e
+    
+    def should_run(self, impl, log_debug_message=True):
+        """
+        Return True if the given implementation should be run (generated).
+        
+        Also optionally log a message that the implementation is
+        filtered out based on phase, tags or setting references.
+        
+        Calling this method also affects the output of executed_impls. Every
+        implementation for which a call to this method has returned True
+        will also be in that list.
+        
+        @param impl: The implementation to check.
+        @param log_debug_message: If True, a debug message will be logged
+            if the implementation is filtered out based on phase, tags
+            or setting references.
+        """
+        if self.filtering_disabled:
+            return True
+        
+        if isinstance(impl, ImplContainer):
+            # Don't perform any filtering on containers
+            return True
+        
+        impl_phases = impl.invocation_phase()
+        if isinstance(impl_phases, basestring):
+            impl_phases = [impl_phases]
+        
+        if self.phase is not None and self.phase not in impl_phases:
+            # Don't log a debug message for phase-based filtering to
+            # avoid unnecessary spamming (uncomment if necessary
+            # during development)
+            #logging.getLogger('cone').debug('Filtered out based on phase: %r (%r not in %r)' % (impl, self.phase, impl_phases))
+            return False
+        if self.tags and not impl.has_tag(self.tags, self.tags_policy):
+            if log_debug_message:
+                logging.getLogger('cone').debug('Filtered out based on tags: %r' % impl)
+            return False
+        if self.filter_by_refs and self.changed_refs and impl.has_ref(self.changed_refs) == False:
+            if log_debug_message:
+                logging.getLogger('cone').debug('Filtered out based on refs: %r' % impl)
+            return False
+        
+        # Assumption is that when a implementation should be run it is added to the executed pile
+        self.executed.add(impl)
+        return True
+    
+    def have_run(self, impl):
+        """
+        This function will add the given implementation 
+        outputs to the list of generation_outputs.
+        """
+        # Add outputs only from actual leaf implementations
+        # not from ImplContainers
+        if not isinstance(impl, ImplContainer):
+            self.generation_output += impl.get_outputs()
+    
+    def create_file(self, filename, **kwargs):
+        """
+        Create a file handle under the output folder. Also adds the output file to the generation outputs list.
+        @param filename: the filename with path, that is created under the output folder of the generation context.
+        @param **kwargs: the keyword arguments that can provide essential information for the GenerationOutput 
+        object creation. They should at least contain the implementation argument for the GenerationObject.
+          @param **kwargs implementation: the implementation object that created this output
+          @param **kwargs mode: the mode of the output file created 
+          @param **kwargs encoding: the possible encoding of the output file. When this parameter is given the create_file will 
+          use codecs.open method to create the file. 
+        @return: the filehandle of the new file. 
+        """
+        
+        implml   = kwargs.get('implementation', None)
+        mode     = kwargs.get('mode', 'wb')
+        encoding = kwargs.get('encoding', None)
+        targetfile = os.path.normpath(os.path.join(self.output, filename))
+        
+        if not os.path.exists(os.path.dirname(targetfile)):
+            os.makedirs(os.path.dirname(targetfile))
+        
+        if not encoding:
+            outfile = open(targetfile, mode)
+        else: 
+            outfile = codecs.open(targetfile, mode, encoding)
+        # Add the generation output
+        self.generation_output.append(GenerationOutput(utils.resourceref.norm(targetfile), 
+                                                       implml, 
+                                                       phase=self.phase,
+                                                       type='file',
+                                                       output=self.output))
+        return outfile
+    
+    def add_file(self, filename, **kwargs):
+        """
+        Add a file to the generation outputs list.
+        @param filename: the filename with path, that is added. If the path is a relative path
+        the path is added under the output folder of the generation context. Absolute path is added as such and not manipulated.
+        @param **kwargs: the keyword arguments that can provide essential information for the GenerationOutput 
+        object creation. They should at least contain the implementation argument for the GenerationObject.
+        @return: None 
+        """
+        if not os.path.isabs(filename):
+            targetfile = os.path.join(self.output, filename)
+        else:
+            targetfile = filename
+        # Add the generation output
+        self.generation_output.append(GenerationOutput(utils.resourceref.norm(targetfile), 
+                                                       kwargs.get('implementation'), 
+                                                       phase=self.phase,
+                                                       type='file',
+                                                       output=self.output))
+
+    def get_output(self, **kwargs):
+        """
+        Get a output object from the generation_output list.
+        @param **kwargs: the keyword arguments. 
+            @param implml_type: a filter for generation outputs to filter generation outputs only with given implementation type. 
+        @return: list of generation output objects
+        """
+        filters = []
+        if kwargs.get('implml_type'):
+            filters.append(lambda x: x.implementation and x.implementation.IMPL_TYPE_ID == kwargs.get('implml_type'))
+             
+        outputs = []
+        # go through all the generation_output items with all provided filters
+        # if the item passes all filters add it to the outputs list 
+        for item in self.generation_output:
+            passed = True
+            for filter in filters:
+                if not filter(item):
+                    passed = False
+                    continue
+            if passed:
+                outputs.append(item)
+        return outputs
+
+    def add_changed_refs(self, refs, implml=None):
+        """
+        Add changed refs to the current set of changed refs if necessary.
+        
+        If there are new refs and they are added, log also a debug message.
+        """
+        if self.changed_refs is None:
+            return
+        for ref in refs:
+            self.add_changed_ref(ref, implml)
+    
+    def add_changed_ref(self, ref, implml=None):
+        """
+        Add changed ref to the current set of changed refs if necessary.
+        
+        If there are new refs and they are added, log also a debug message.
+        """
+        if self.changed_refs is None:
+            return
+        
+        if ref not in self.changed_refs:
+            self.changed_refs.append(ref)
+            logging.getLogger('cone').debug('Added ref %s from implml %s' % (ref, implml))
+
+    def get_refs_with_no_output(self, refs=None):
+        if not refs:
+            refs = self.changed_refs
+        if refs:
+            # create a set from the changed refs 
+            # then remove the refs that have a generation output
+            # and return the remaining refs as a list
+            refsset = set(refs)
+            implrefs = set()
+            for output in self.generation_output:
+                if output.implementation:
+                    implrefs |= set(output.implementation.get_refs() or [])
+                    if output.type == 'ref':
+                        implrefs.add(output.name)
+            # Add all sequence subfeatures to the list of implementation references
+            dview = self.configuration.get_default_view()
+            for fea in dview.get_features(list(implrefs)):
+                if fea.is_sequence():
+                    seqfeas = ["%s.%s" % (fea.fqr,fearef) for fearef in fea.get_sequence_parent().list_features()] 
+                    implrefs |= set(seqfeas)
+            
+            refsset = refsset - implrefs
+            return sorted(list(refsset))
+        else:
+            return []
+
+    def get_refs_with_no_implementation(self, refs=None):
+        if not refs:
+            refs = self.changed_refs
+        if refs:
+            # create a set from the changed refs 
+            # then remove the refs that have a generation output
+            # and return the remaining refs as a list
+            refsset = set(refs)
+            implrefs = set(self.impl_set.get_implemented_refs())
+            logging.getLogger('cone').debug("changed_refs: %s" % refsset)
+            logging.getLogger('cone').debug("implrefs: %s" % implrefs)
+            # Add all sequence subfeatures to the list of implementation references
+            dview = self.configuration.get_default_view()
+            for fea in dview.get_features(list(implrefs)):
+                if fea.is_sequence():
+                    seqfeas = ["%s.%s" % (fea.fqr,fearef) for fearef in fea.get_sequence_parent().list_features()] 
+                    implrefs |= set(seqfeas)
+            
+            refsset = refsset - implrefs
+            return sorted(list(refsset))
+        else:
+            return []
+
+    @property
+    def executed_impls(self):
+        """
+        List of all executed implementations (implementations for which
+        a call to should_run() has returned True).
+        """
+        return list(self.executed)
+
+    @property
+    def features(self):
+        """
+        return the default view of the context configuration to access all features of the configuration.
+        """
+        return self.configuration.get_default_view()
+
+    def grep_log(self, entry):
+        """
+        Grep the self.log entries for given entry and return a list of tuples with line (index, entry) 
+        """
+        return utils.grep_tuple(entry, self.log)
+
+class MergedContext(GenerationContext):
+    def __init__(self, contexts):
+        self.contexts = contexts
+        self.configuration = None
+        self.changed_refs = []
+        self.temp_features = []
+        self.executed = set()
+        self.impl_set = ImplSet()
+        self.impl_dict = {}
+        self.generation_output = []
+        self.log = []
+        self.log_files = []
+        self.outputs = {}
+        for context in contexts:
+            self.changed_refs += context.changed_refs
+            self.temp_features += context.temp_features
+            self.configuration = context.configuration
+            self.executed |= context.executed
+            self.generation_output += context.generation_output
+            self.log += context.log
+            self.log_files.append(context.log_file)
+            for output in context.generation_output:
+                self.outputs[output.name] = output
+            for impl in context.impl_set:
+                self.impl_dict[impl.ref] = impl
+        self.impl_set = ImplSet(self.impl_dict.values())
+
+    def get_changed_refs(self, **kwargs):
+        changed_refs = set()
+        operation = kwargs.get('operation', 'union')
+        for context in self.contexts:
+            if not changed_refs:
+                # set the base set from the first context
+                changed_refs = set(context.changed_refs)
+            else:
+                if operation == 'union':
+                    changed_refs |= set(context.changed_refs)
+                elif operation == 'intersection':
+                    changed_refs &= set(context.changed_refs)
+                elif operation == 'difference':
+                    changed_refs -= set(context.changed_refs)
+                elif operation == 'symmetric_difference':
+                    changed_refs ^= set(context.changed_refs)
+                else:
+                    raise exceptions.NotSupportedException('Illegal opration %s for get_changed_refs!' % operation)
+        #remove temp features
+        if kwargs.get('ignore_temps'):
+            changed_refs = changed_refs - set(self.temp_features)
+        return list(changed_refs)
+
+class GenerationOutput(object):
+    """
+    A GenerationOutput object that is intended to be part of GenerationContext.generation_outputs.
+    The data should hold information about
+    """
+    TYPES = ['file', 'ref']
+    
+    def __init__(self, name, implementation, **kwargs):
+        """
+        @param name: the name of the output as string
+        @param implementation: the implementation object that generated this output
+        @param type: the type of the output that could be file|ref
+        """
+        
+        """ The name of the output """
+        self.name = name
+        
+        """ The implementation object that generated the output """
+        self.implementation = implementation
+        
+        """ The type of the output """
+        self.type = kwargs.get('type', None)
+
+        """ phase of the generation """
+        self.phase = kwargs.get('phase', None)
+
+        """ the context output path of the generation """
+        self.output = kwargs.get('output', None)
+        
+        """ the possible exception """
+        self.exception = kwargs.get('exception', None)
+         
+    def __str__(self):
+        return "%s(%s, %s)" % (self.__class__.__name__, self.name, self.implementation)
+
+    @property
+    def filename(self):
+        """
+        return the filename part of the the output name. Valid only if the output name is a path.
+        """
+        return os.path.basename(self.name)
+
+    @property
+    def relpath(self):
+        """
+        return the relative name part of the the output name, with relation to the context output path. 
+        """
+        return utils.relpath(self.name, self.output)
+        
+    @property
+    def abspath(self):
+        """
+        return the relative name part of the the output name, with relation to the context output path. 
+        """
+        if os.path.isabs(self.name):
+            return os.path.normpath(self.name)
+        else:
+            return os.path.abspath(os.path.normpath(self.name))
 
 class FlatComparisonResultEntry(object):
     """
@@ -316,8 +741,9 @@
         self._settings = None
         self.ref = ref
         self.index = None
+        self.lineno = None
         self.configuration = configuration
-        self._output_root = self.settings.get('output_root','output')
+        self._output_root = self.settings.get('output_root','')
         self.output_subdir = self.settings.get('output_subdir','')
         self.plugin_output = self.settings.get('plugin_output','')
         
@@ -328,32 +754,32 @@
         self.condition = None
         self._output_root_override = None
 
-    def _eval_context(self, context):
-        """
-        This is a internal function that returns True when the context matches to the 
-        context of this implementation. For example phase, tags, etc are evaluated.
-        """
-        if context.tags and not self.has_tag(context.tags, context.tags_policy):
-            return False
-        if context.phase and not context.phase in self.invocation_phase():
-            return False
-        if self.condition and not self.condition.eval(context):
-            return False 
-        
-        return True
+    def __reduce_ex__(self, protocol_version):
+        config = self.configuration
+        if protocol_version == 2:
+            tpl =  (read_impl_from_location,
+                    (self.ref, config, self.lineno),
+                    None,
+                    None,
+                    None)
+            return tpl
+        else:
+            return (read_impl_from_location,
+                    (self.ref, config, self.lineno))
+            
 
     def _dereference(self, ref):
         """
         Function for dereferencing a configuration ref to a value in the Implementation configuration context. 
         """
-        return configuration.get_default_view().get_feature(ref).value
+        return self.configuration.get_default_view().get_feature(ref).value
 
     def _compare(self, other, dict_keys=None):
         """ 
         The plugin instance against another plugin instance
         """
         raise exceptions.NotSupportedException()
-
+    
     def generate(self, context=None):
         """
         Generate the given implementation.
@@ -383,6 +809,18 @@
         """
         return []
     
+    def get_outputs(self):
+        """
+        Return a list of GenerationOutput objets as a list. 
+        """
+        outputs = []
+        phase = None 
+        if self.generation_context: phase = self.generation_context.phase
+        for outfile in self.list_output_files():
+            outputs.append(GenerationOutput(outfile,self,type='file', phase=phase) )
+        return outputs
+    
+    
     def get_refs(self):
         """
         Return a list of all ConfML setting references that affect this
@@ -404,14 +842,7 @@
         if isinstance(refs, basestring):
             refs = [refs]
         
-        for ref in refs:
-            for impl_ref in impl_refs:
-                if ref.startswith(impl_ref):
-                    if len(ref) == len(impl_ref):
-                        return True
-                    elif ref[len(impl_ref)] == '.':
-                        return True
-        return False
+        return uses_ref(refs, impl_refs)
 
     def flat_compare(self, other):
         """
@@ -457,6 +888,9 @@
 
     @property
     def settings(self):
+        """
+        return the plugin specific settings object.
+        """
         if not self._settings:
             parser = settings.SettingsFactory.cone_parser()
             if self.IMPL_TYPE_ID is not None:
@@ -468,9 +902,15 @@
 
     @property
     def output(self):
+        """
+        return the output folder for this plugin instance.
+        """
         vars = {'output_root': self.output_root,'output_subdir': self.output_subdir,'plugin_output': self.plugin_output}
         default_format = '%(output_root)s/%(output_subdir)s/%(plugin_output)s'
-        return utils.resourceref.norm(self.settings.get('output',default_format,vars))
+        output = utils.resourceref.remove_begin_slash(utils.resourceref.norm(self.settings.get('output',default_format,vars)))
+        if os.path.isabs(self.output_root):
+            output = utils.resourceref.insert_begin_slash(output) 
+        return output
     
     def _get_output_root(self):
         if self._output_root_override is not None:
@@ -616,8 +1056,32 @@
         return [self]
     
     def __repr__(self):
-        return "%s(ref=%r, type=%r, index=%r)" % (self.__class__.__name__, self.ref, self.IMPL_TYPE_ID, self.index)
+        return "%s(ref=%r, type=%r, lineno=%r)" % (self.__class__.__name__, self.ref, self.IMPL_TYPE_ID, self.lineno)
+
+    @property
+    def path(self):
+        """
+        return path relative to the Configuration projec root
+        """
+        return self.ref
 
+    @property
+    def abspath(self):
+        """
+        return absolute system path to the implementation
+        """
+        return os.path.abspath(os.path.join(self.configuration.storage.path,self.ref))
+    
+    def uses_layers(self, layers, context):
+        """
+        Return whether this implementation uses any of the given layers
+        in the given context, i.e., whether the layers contain anything that would
+        affect generation output.
+        """
+        # The default implementation checks against refs changed in the layers
+        refs = []
+        for l in layers: refs.extend(l.list_leaf_datas())
+        return self.has_ref(refs)
 
 class ImplContainer(ImplBase):
     """
@@ -655,43 +1119,66 @@
          
         @return: 
         """
-        if context:
-            if not self._eval_context(context):
-                # should we report something if we exit here?
-                return
-            
+        log = logging.getLogger('cone')
+        
+        if self.condition and not self.condition.eval(context):
+            log.debug('Filtered out based on condition %s: %r' % (self.condition, self))
+            return
+        
         # run generate on sub impls
         for impl in self.impls:
-            impl.generate(context)
+            if context:
+                # 1. Check should the implementation be run from context
+                # 2. Run ImplContainer if should
+                # 3. run other ImplBase objects if this is not a dry_run                      
+                if context.should_run(impl):
+                    if isinstance(impl, ImplContainer) or \
+                        not context.dry_run:
+                        impl.generate(context)
+                        # context.have_run(impl)
+            else:
+                impl.generate(context)
 
     def get_refs(self):
+        # Containers always return None, because the ref-based filtering
+        # happens only on the actual implementations
+        return None
+    
+    def get_child_refs(self):
         """
-        Return a list of all ConfML setting references that affect this
-        implementation. May also return None if references are not relevant
-        for the implementation.
+        ImplContainer always None with get_refs so it one wants to get the references from all 
+        leaf child objects, one can use this get_child_refs function
+        @return: a list of references.
         """
         refs = []
         for impl in self.impls:
-            subrefs = impl.get_refs()
-            if subrefs:
-                refs += subrefs
-        if refs:
-            return utils.distinct_array(refs)
-        else:
-            return None 
+            if isinstance(impl, ImplContainer):
+                refs += impl.get_child_refs()
+            else:
+                refs += impl.get_refs() or []
+        return utils.distinct_array(refs)
 
+    def has_tag(self, tags, policy=None):
+        # Container always returns True
+        return True
+    
     def get_tags(self):
+        # Containers always return None, because the tag-based filtering
+        # happens only on the actual implementations
+        return None
+
+    def get_child_tags(self):
         """
-        overloading the get_tags function in ImplContainer to create sum of 
-        tags of all subelements of the Container
-        @return: dictionary of tags
+        ImplContainer always None with get_tags so it one wants to get the teags from all 
+        leaf child objects, one can use this get_child_tags function
+        @return: a list of references.
         """
-        tags = ImplBase.get_tags(self)
+        tags = {}
         for impl in self.impls:
-            # Update the dict by appending new elements to the values instead 
-            # of overriding
-            for key,value in impl.get_tags().iteritems():
-                tags[key] = tags.get(key,[]) + value 
+            if isinstance(impl, ImplContainer):
+                utils.update_dict(tags, impl.get_child_tags())
+            else:
+                utils.update_dict(tags, impl.get_tags())
         return tags
 
     def list_output_files(self):
@@ -703,6 +1190,15 @@
             files += impl.list_output_files()
         return utils.distinct_array(files)
 
+    def get_outputs(self):
+        """
+        Return a list of GenerationOutput objets as a list. 
+        """
+        outputs = []
+        for impl in self.impls:
+            outputs += impl.get_outputs()
+        return outputs
+    
     def set_output_root(self,output):
         """
         Set the root directory for the output files. The output
@@ -712,25 +1208,6 @@
         for impl in self.impls:
             impl.set_output_root(output) 
 
-    def invocation_phase(self):
-        """
-        @return: the list of phase names in which phases this container wants to be executed. 
-        """
-        # use a dictionary to store phases only once 
-        phases = {}
-        phases[ImplBase.invocation_phase(self)] = 1
-        for impl in self.impls:
-            # for now only get the phases from sub ImplContainer objects 
-            # this is needed until the plugin phase can be overridden with the common elems
-            if isinstance(impl, ImplContainer):
-                subphases = impl.invocation_phase()
-                if isinstance(subphases, list):
-                    # join the two lists as one
-                    phases = phases.fromkeys(phases.keys() + subphases, 1)
-                else:
-                    phases[subphases] = 1
-        return phases.keys()
-    
     def get_temp_variable_definitions(self):
         tempvars = self._tempvar_defs[:]
         for impl in self.impls:
@@ -757,8 +1234,59 @@
         for subimpl in self.impls:
             actual_impls += subimpl.get_all_implementations()
         return actual_impls
-
-
+    
+    def uses_layers(self, layers, context):
+        #log = logging.getLogger('uses_layers(%r)' % self)
+        
+        # If no sub-implementation has matching tags, the implementations would
+        # never be run in this context, so there's no need to go further in that case
+        if not self._have_impls_matching_tags(context.tags, context.tags_policy):
+            #log.debug("No impls have matching tags, returning False")
+            return False
+        
+        # If the container has a condition depending on any of the changed refs,
+        # it means that the refs can affect generation output
+        if self.condition:
+            refs = []
+            for l in layers: refs.extend(l.list_leaf_datas())
+            if uses_ref(refs, self.condition.get_refs()):
+                #log.debug("Refs affect condition, returning True")
+                return True
+        
+        # If the condition evaluates to False (and doesn't depend on the
+        # changed refs), the implementations won't be run, and thus they
+        # don't use the layers in this context
+        if self.condition and not self.condition.eval(context):
+            #log.debug("Condition evaluates to False, returning False")
+            return False
+        
+        for impl in self.impls:
+            # Filter out based on tags if the implementation is not
+            # a container (using ImplBase.has_tag() here since RuleML v2
+            # overrides has_tag() to always return True)
+            if not isinstance(impl, ImplContainer):
+                if not ImplBase.has_tag(impl, context.tags, context.tags_policy):
+                    continue
+            
+            if impl.uses_layers(layers, context):
+                #log.debug("%r uses layer, returning True" % impl)
+                return True
+        
+        #log.debug("Returning False")
+        return False
+    
+    def _have_impls_matching_tags(self, tags, tags_policy):
+        """
+        Return if any of the container's leaf implementations use the given tags.
+        """
+        for impl in self.impls:
+            if isinstance(impl, ImplContainer):
+                if impl._have_impls_matching_tags(tags, tags_policy):
+                    return True
+            elif ImplBase.has_tag(impl, tags, tags_policy):
+                return True
+        return False
+        
 class ReaderBase(object):
     """
     Base class for implementation readers.
@@ -779,6 +1307,25 @@
     #: for different versions of an implementation).
     NAMESPACE = None
     
+    #: ID for the namespace used in the generated XML schema files.
+    #: Must be unique, and something simple like 'someml'. 
+    NAMESPACE_ID = None
+    
+    #: Sub-ID for schema problems for this ImplML namespace.
+    #: This is used as part of the problem type for schema validation
+    #: problems. E.g. if the sub-ID is 'someml', then a schema validation
+    #: problem would have the problem type 'schema.implml.someml'.
+    #: If this is not given, then the problem type will simply be
+    #: 'schema.implml'.
+    SCHEMA_PROBLEM_SUB_ID = None
+    
+    #: The root element name of the implementation langauge supported by
+    #: the reader. This is also used in the generate XML schema files, and
+    #: must correspond to the root element name specified in the schema data.
+    #: If get_schema_data() returns None, then this determines the name of
+    #: the root element in the automatically generated default schema.
+    ROOT_ELEMENT_NAME = None
+    
     #: Any extra XML namespaces that should be ignored by the
     #: implementation parsing machinery. This is useful for specifying
     #: namespaces that are not actual ImplML namespaces, but are used
@@ -806,6 +1353,37 @@
         raise exceptions.NotSupportedException()
     
     @classmethod
+    def read_impl_from_location(cls, resource_ref, configuration, lineno):
+        """
+        Read an implementation instance from the given resource at the given line number.
+        
+        @param resource_ref: Reference to the resource in the configuration in
+            which the given document root resides.
+        @param configuration: The configuration used.
+        @param lineno: the line number where the root node for this particular element is searched from.
+        @return: The read implementation instance, or None.
+        """
+        root =  cls._read_xml_doc_from_resource(resource_ref, configuration)
+        elemroot = utils.etree.get_elem_from_lineno(root, lineno)
+        ns, tag = utils.xml.split_tag_namespace(elemroot.tag)
+        reader = cls.get_reader_for_namespace(ns)
+        implml = reader.read_impl(resource_ref, configuration, elemroot)
+        implml.lineno = lineno
+        return implml
+
+    @classmethod
+    def get_reader_for_namespace(cls, namespace):
+        return ImplFactory.get_reader_dict().get(namespace, None)
+    
+    @classmethod
+    def get_schema_data(cls):
+        """
+        Return the XML schema data used for validating the ImplML supported by this reader.
+        @return: The schema data as a string, or None if not available.
+        """
+        return None
+    
+    @classmethod
     def _read_xml_doc_from_resource(cls, resource_ref, configuration):
         """
         Parse an ElementTree instance from the given resource.
@@ -847,6 +1425,7 @@
     
     @classmethod
     def read_impl(cls, resource_ref, configuration, doc_root, read_impl_count=None):
+        on_top_level = read_impl_count == None
         # The variable read_impl_count is used to keep track of the number of
         # currently read actual implementations. It is a list so that it can be used
         # like a pointer, i.e. functions called from here can modify the number
@@ -857,9 +1436,8 @@
         
         ns, tag = utils.xml.split_tag_namespace(doc_root.tag)
         if tag != "container":
-            logging.getLogger('cone').error("Error: The root element must be a container in %s" % (ns, resource_ref))
+            logging.getLogger('cone').error("Error: The root element must be a container in %s, %s" % (ns, resource_ref))
             
-        impls = []
         reader_classes = cls.get_reader_classes()
         namespaces = reader_classes.keys()
         # Read first the root container object with attributes 
@@ -867,7 +1445,7 @@
         containerobj = ImplContainer(resource_ref, configuration)
         containerobj.condition = cls.get_condition(doc_root)
         
-        common_data = _plugin_reader.CommonImplmlDataReader.read_data(doc_root)
+        containerobj._common_data = _plugin_reader.CommonImplmlDataReader.read_data(doc_root)
         
         # traverse through the subelements
         for elem in doc_root:
@@ -877,6 +1455,7 @@
                 # common namespace elements were handled earlier)
                 if tag == "container":
                     subcontainer = cls.read_impl(resource_ref, configuration, elem, read_impl_count=read_impl_count)
+                    subcontainer.lineno = utils.etree.get_lineno(elem)
                     containerobj.append(subcontainer)
                     subcontainer.index = None # For now all sub-containers have index = None
             else:
@@ -886,14 +1465,30 @@
                 else:
                     reader = reader_classes[ns]
                     subelem = reader.read_impl(resource_ref, configuration, elem)
-                    if common_data: common_data.apply(subelem)
+                    subelem.lineno = utils.etree.get_lineno(elem)
                     containerobj.append(subelem)
                     subelem.index = read_impl_count[0]
                     read_impl_count[0] = read_impl_count[0] +  1
-            
-        if common_data:
-            common_data.apply(containerobj)
-            containerobj._tempvar_defs = common_data.tempvar_defs + containerobj._tempvar_defs
+        
+        containerobj._tempvar_defs = containerobj._common_data.tempvar_defs
+        
+        if on_top_level:
+            def inherit_common_data(container):
+                for impl in container.impls:
+                    if isinstance(impl, ImplContainer):
+                        new_common_data = container._common_data.copy()
+                        new_common_data.extend(impl._common_data)
+                        impl._common_data = new_common_data
+                        inherit_common_data(impl)
+            def apply_common_data(container):
+                for impl in container.impls:
+                    if isinstance(impl, ImplContainer):
+                        apply_common_data(impl)
+                    else:
+                        container._common_data.apply(impl)
+            inherit_common_data(containerobj)
+            apply_common_data(containerobj)
+        
         return containerobj
 
     @classmethod
@@ -913,7 +1508,7 @@
         else:
             return None
 
-class ImplSet(sets.Set):
+class ImplSet(set):
     """
     Implementation set class that can hold a set of ImplBase instances. 
     """
@@ -925,13 +1520,16 @@
     INVOCATION_PHASES = ['pre','normal','post']
 
     def __init__(self,implementations=None, generation_context=None):
-        super(ImplSet,self).__init__(implementations)
+        super(ImplSet,self).__init__(implementations or [])
         self.output = 'output'
-        if generation_context:
-            self.generation_context = generation_context
-        else:
-            self.generation_context = GenerationContext()
-
+        self.generation_context = generation_context
+        self.ref_to_impl = {}
+    
+    def _create_ref_dict(self):
+        for impl in self:
+            for ref in impl.get_refs() or []:
+                self.ref_to_impl.setdefault(ref, []).append(impl)
+ 
     def invocation_phases(self):
         """
         @return: A list of possible invocation phases
@@ -957,7 +1555,21 @@
         #    impl.generation_context = self.generation_context
         if not context:
             context =  self.generation_context
-        self.execute(self, 'generate', context)
+        else:
+            self.generation_context = context
+        # Sort by file name so that execution order is always the same
+        # (easier to compare logs)
+        sorted_impls = sorted(self, key=lambda impl: impl.ref)
+
+        for impl in sorted_impls:
+            # 1. Check should the implementation be run from context
+            # 2. Run ImplContainer if should  
+            # 3. run other ImplBase objects if this is not a dry_run                      
+            if context.should_run(impl):
+                if isinstance(impl, ImplContainer) or \
+                    not context.dry_run:
+                    self.execute([impl], 'generate', context)
+                    # context.have_run(impl)
     
     def post_generate(self, context=None):
         """
@@ -965,7 +1577,16 @@
         """
         if not context:
             context =  self.generation_context
-        self.execute(self, 'post_generate', context)
+        
+        impls = []
+        # Sort by file name so that execution order is always the same
+        # (easier to compare logs)
+        sorted_impls = sorted(self, key=lambda impl: impl.ref)
+        for impl in sorted_impls:
+            if context.should_run(impl, log_debug_message=False):
+                impls.append(impl)
+        
+        self.execute(impls, 'post_generate', context)
 
     def execute(self, implementations, methodname, *args):
         """
@@ -978,17 +1599,21 @@
         @param implementations:
         @param methodname: the name of the function to execute  
         """
-        # Sort by (file_name, index_in_file) to ensure the correct execution order
-        impls = sorted(implementations, key=lambda impl: (impl.ref, impl.index))
-        for impl in impls:
+        for impl in implementations:
             try:
-                impl.set_output_root(self.output)
                 if hasattr(impl, methodname): 
                     _member = getattr(impl, methodname)
                     _member(*args)
                 else:
                     logging.getLogger('cone').error('Impl %r has no method %s' % (impl, methodname))
             except Exception, e:
+                if self.generation_context:
+                    self.generation_context.generation_output.append(GenerationOutput('exception from %s' % impl.ref, 
+                                                                                      impl, 
+                                                                                      phase=self.generation_context.phase,              
+                                                                                      type='exception',
+                                                                                      output=self.generation_context.output,
+                                                                                      exception=e))
                 utils.log_exception(logging.getLogger('cone'), 'Impl %r raised an exception: %s' % (impl, repr(e)))
         
     
@@ -1059,6 +1684,38 @@
                 impls.append(impl)
         return ImplSet(impls)
     
+    def find_implementations(self,**kwargs):
+        """
+        Find any implementation with certain parameters.
+        All arguments are given as dict, so they must be given with name. E.g. copy(phase='normal')
+        @param phase: name of the phase
+        @param refs: A list of refs that are filtered with function has_refs
+        @param tags: A dictionary of tags that are filtered with function has_tags
+        @return: a new ImplSet object with the filtered items.
+        """
+        impls = []
+        """ Create a list of filter functions for each argument """ 
+        filters=[]
+        filters.append(lambda x: x != None)
+        if kwargs.get('phase', None) != None:
+            filters.append(lambda x: kwargs.get('phase') in x.invocation_phase())
+        if kwargs.get('refs',None) != None:
+            # Changed has_ref usage to allow not supporting refs (meaning that non supported wont be filtered with refs)
+            filters.append(lambda x: x.has_ref(kwargs.get('refs')) == True)
+        if kwargs.get('tags', None) != None:
+            filters.append(lambda x: x.has_tag(kwargs.get('tags'),kwargs.get('policy')))
+            
+        """ Go through the implementations and add all to resultset that pass all filters """ 
+        for impl in self:
+            pass_filters = True
+            for filter in filters:
+                if not filter(impl):
+                    pass_filters = False
+                    break
+            if pass_filters:
+                impls.append(impl)
+        return ImplSet(impls)
+
     def flat_compare(self, other):
         """
         Perform a flat comparison between this implementation container and another one.
@@ -1201,8 +1858,8 @@
             to be created.
         @return: A list containing the references of all created temporary features.
         
-        @raise exceptions.AlreadyExists: Any of the temporary features already exists
-            in the configuration, or there are duplicate temporary features defined.
+        @raise exceptions.AlreadyExists: There are duplicate temporary features defined
+            in the configuration. Redefinitions of the temporaty features are only ignored.
         """
         # ----------------------------------------------------
         # Collect a list of all temporary variable definitions
@@ -1218,9 +1875,11 @@
                 # Check if already exists
                 try:
                     dview.get_feature(fea_def.ref)
-                    raise exceptions.AlreadyExists(
-                        "Temporary variable '%s' defined in file '%s' already exists in the configuration!" \
-                        % (fea_def.ref, impl.ref))
+                    #raise exceptions.AlreadyExists(
+                    #    "Temporary variable '%s' defined in file '%s' already exists in the configuration!" \
+                    #    % (fea_def.ref, impl.ref))
+                    logging.getLogger('cone').warning("Temporary variable '%s' re-definition ignored." % fea_def.ref)
+                    continue
                 except exceptions.NotFound:
                     pass
                 
@@ -1246,7 +1905,7 @@
         # ------------------------------
         refs = []
         if tempvar_defs:
-            logging.getLogger('cone').debug('Creating %d temporary variable(s)' % len(tempvar_defs))
+            logging.getLogger('cone').debug('Creating %d temporary variable(s) %r' % (len(tempvar_defs), tempvar_defs))
             autoconfig = get_autoconfig(configuration)
             for fea_def in tempvar_defs:
                 fea_def.create_feature(autoconfig)
@@ -1285,7 +1944,16 @@
             result += impl.get_all_implementations()
         return result
 
-
+    def get_implemented_refs(self):
+        if not self.ref_to_impl:
+            self._create_ref_dict()
+        return sorted(self.ref_to_impl.keys())
+    
+    def get_implementations_with_ref(self, ref):
+        if not self.ref_to_impl:
+            self._create_ref_dict()
+        return sorted(self.ref_to_impl.get(ref, []), lambda a,b: cmp(a.ref, b.ref))
+    
 class RelationExecutionResult(object):
     """
     Class representing a result from relation execution.
@@ -1334,7 +2002,7 @@
         self.entries = entries
         self.source = source
         
-    def execute(self):
+    def execute(self, context=None):
         """
         Execute all relations inside the container, logging any exceptions thrown
         during the execution.
@@ -1342,17 +2010,18 @@
         """
         results = []
         for i, entry in enumerate(self.entries):
+            
             if isinstance(entry, rules.RelationBase):
-                result = self._execute_relation_and_log_error(entry, self.source, i + 1)
+                result = self._execute_relation_and_log_error(entry, self.source, i + 1, context)
                 if isinstance(RelationExecutionResult):
                     results.append(result)
             elif isinstance(entry, RelationContainer):
-                results.extend(self._execute_container_and_log_error(entry))
+                results.extend(self._execute_container_and_log_error(entry, context))
             else:
                 logging.getLogger('cone').warning("Invalid RelationContainer entry: type=%s, obj=%r" % (type(entry), entry))
         return results
     
-    def _execute_relation_and_log_error(self, relation, source, index):
+    def _execute_relation_and_log_error(self, relation, source, index, context=None):
         """
         Execute a relation, logging any exceptions that may be thrown.
         @param relation: The relation to execute.
@@ -1360,27 +2029,32 @@
         @param index: The index of the rule, can be None if the index is not known.
         @return: The return value from the relation execution, or None if an error occurred.
         """
-        try:
-            return relation.execute()
+        try: 
+            return relation.execute(context)
         except Exception, e:
-            log = logging.getLogger('cone')
-            if index is not None:
-                utils.log_exception(log, "Error executing rule no. %s in '%s'" % (index, source))
-            else:
-                utils.log_exception(log, "Error executing a rule in '%s'" % relation_or_container.source)
+            msg = "Error executing rule %r: %s: %s" % (relation, e.__class__.__name__, e)
+            if context:
+                gout = GenerationOutput('exception from %s' % source, 
+                                        relation, 
+                                        phase=context.phase,
+                                        type='exception',
+                                        output=context.output,
+                                        exception=msg)
+                context.generation_output.append(gout)
+            utils.log_exception(logging.getLogger('cone'), msg)
             return None
     
-    def _execute_container_and_log_error(self, container):
+    def _execute_container_and_log_error(self, container, context):
         """
         Execute a relation container, logging any exceptions that may be thrown.
         @param relation: The relation container to execute.
         @return: The results from the relation execution, or an empty list if an error occurred.
         """
         try:
-            return container.execute()
+            return container.execute(context)
         except Exception, e:
             log = logging.getLogger('cone')
-            utils.log_exception(log, "Error executing rules in '%s'" % container.source)
+            utils.log_exception(log, "Exception executing rules in '%s': %s" % container.source, e)
             return []
     
     def get_relation_count(self):
@@ -1395,6 +2069,18 @@
                 count += 1
         return count
     
+    def get_relations(self):
+        """
+        Return a list of all relations in this container.
+        """
+        result = []
+        for entry in self.entries:
+            if isinstance(entry, RelationContainer):
+                result.extend(entry.get_relations())
+            else:
+                result.append(entry)
+        return result
+    
 
 class ImplFactory(api.FactoryBase):
 
@@ -1437,7 +2123,9 @@
         file_extensions = []
         for reader in cls.get_reader_classes():
             for fe in reader.FILE_EXTENSIONS:
-                file_extensions.append(fe.lower()) 
+                fe = fe.lower()
+                if fe not in file_extensions:
+                    file_extensions.append(fe)
         return file_extensions
 
     @classmethod
@@ -1478,7 +2166,7 @@
                 log.warn("'%s' entry point '%s' is not a sub-class of cone.plugin.ReaderBase (%r)" % (ENTRY_POINT, entry_point.name, reader_class))
             else:
                 msg = "Reader class for XML namespace '%s' loaded from egg '%s' entry point '%s'" % (reader_class.NAMESPACE, ENTRY_POINT, entry_point.name)
-                log.debug(msg)
+                #log.debug(msg)
                 #print msg
                 reader_classes.append(reader_class)
                 
@@ -1507,23 +2195,39 @@
         @raise NotSupportedException: The file contains an XML namespace that is
             not registered as an ImplML namespace.
         """
+        context = parsecontext.get_implml_context()
+        context.current_file = resource_ref
         try:
+            resource = configuration.get_resource(resource_ref)
+            try:        data = resource.read()
+            finally:    resource.close()
+            
+            # Schema-validation while parsing disabled for now
+            #cone.validation.schemavalidation.validate_implml_data(data)
+            
             impls = []
             reader_dict = cls.get_reader_dict()
-            root = ReaderBase._read_xml_doc_from_resource(resource_ref, configuration)
+            
+            root =  utils.etree.fromstring(data)
             ns = utils.xml.split_tag_namespace(root.tag)[0]
             if ns not in reader_dict.keys():
-                logging.getLogger('cone').error("Error: no reader for namespace '%s' in %s" % (ns, resource_ref))
+                context.handle_problem(api.Problem("No reader for namespace '%s'" % ns,
+                                                   type="xml.implml",
+                                                   file=resource_ref,
+                                                   line=utils.etree.get_lineno(root)))
+                #logging.getLogger('cone').error("Error: no reader for namespace '%s' in %s" % (ns, resource_ref))
                 return []
             rc = reader_dict[ns]
             # return the single implementation as a list to maintain 
             # backwards compability
             impl = rc.read_impl(resource_ref, configuration, root)
             impl.index = 0
+            impl.lineno = utils.etree.get_lineno(root)
             return [impl]
-        except exceptions.ParseError, e:
-            # Invalid XML data in the file
-            logging.getLogger('cone').error("Implementation %s reading failed with error: %s" % (resource_ref,e))
+        except Exception, e:
+            if isinstance(e, exceptions.XmlParseError):
+                e.problem_type = 'xml.implml'
+            context.handle_exception(e)
             return []
 
 def get_impl_set(configuration,filter='.*'):
@@ -1531,12 +2235,12 @@
     return a ImplSet object that contains all implementation objects related to the 
     given configuration
     """
-    impls = configuration.get_layer().list_implml()
+    impls = configuration.layered_implml().flatten().values()
     impls = pre_filter_impls(impls)
     # filter the resources with a given filter
     impls = utils.resourceref.filter_resources(impls,filter)
-    impl_container = create_impl_set(impls,configuration)
-    return impl_container
+    impl_set = create_impl_set(impls,configuration)
+    return impl_set
 
 def filtered_impl_set(configuration,pathfilters=None, reffilters=None):
     """
@@ -1544,7 +2248,7 @@
     given configuration
     """
     if pathfilters: logging.getLogger('cone').info('Filtering impls with %s' % pathfilters)
-    impls = configuration.get_layer().list_implml()
+    impls = configuration.layered_implml().flatten().values()
     impls = pre_filter_impls(impls)
     # filter the resources with a given filter
     if pathfilters:
@@ -1552,13 +2256,15 @@
         for filter in pathfilters:
             newimpls += utils.resourceref.filter_resources(impls,filter)
         impls = utils.distinct_array(newimpls)
-    impl_container = create_impl_set(impls,configuration,reffilters)
-    return impl_container
+    impl_set = create_impl_set(impls,configuration,reffilters)
+    return impl_set
 
 def create_impl_set(impl_filename_list, configuration,reffilters=None):
     impl_filename_list = pre_filter_impls(impl_filename_list)
     if reffilters: logging.getLogger('cone').info('Filtering with refs %s' % reffilters)
     impl_container = ImplSet()
+    impl_container.generation_context = GenerationContext()
+    impl_container.generation_context.configuration = configuration
     for impl in impl_filename_list:
         try:
             if configuration != None and ImplFactory.is_supported_impl_file(impl):
@@ -1578,3 +2284,6 @@
     """
     filter = r'(/|^|\\)\..*(/|$|\\)'
     return utils.resourceref.neg_filter_resources(impls, filter)
+
+def read_impl_from_location(resource_ref, configuration, lineno):
+    return ReaderBase.read_impl_from_location(resource_ref, configuration, lineno)
--- a/configurationengine/source/cone/public/rules.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/public/rules.py	Tue Aug 10 14:29:28 2010 +0300
@@ -17,10 +17,12 @@
 import operator as ops
 import logging
 import tokenize
-from token import ENDMARKER, NAME, ERRORTOKEN
+import re
+from token import ENDMARKER, NAME, ERRORTOKEN, OP
 import StringIO
 
-from cone.public import container
+from cone.public import container, exceptions, utils
+import types
 
 RELATIONS = {}
 
@@ -29,14 +31,20 @@
     caller = inspect.getouterframes(inspect.currentframe())[1][3]
     raise NotImplementedError(caller + ' needs to be implemented')
 
+REF_DOLLAR = '$'
+REF_START_BRACE = '{'
+REF_END_BRACE = '}'
+REF_REGEX = re.compile('(?P<ref>\${[\w\.\*]*})', re.UNICODE)
+
 def get_tokens(tokenstr):
     result = []
     tokens = []
     tokenstr = tokenstr.replace('\r', '')
     name_buffer = [] # Temp buffer for reading name tokens
     last_epos = None
+    
+    ref_start = False
     for toknum, tokval, spos, epos, _  in tokenize.generate_tokens(StringIO.StringIO(unicode(tokenstr)).readline):
-        #print "toknum: %r, tokval: %r, spos: %r, epos: %r" % (toknum, tokval, spos, epos)
         val = tokval.strip('\r\n\t ')
         
         if toknum == ENDMARKER and name_buffer:
@@ -46,15 +54,28 @@
         # since its value is empty)
         if val == '': continue
         
+        # Handle the references here, ${ref} is the format
+        if toknum in (OP, ERRORTOKEN) and\
+                tokval in (REF_DOLLAR, REF_START_BRACE, REF_END_BRACE) or\
+                ref_start:
+            if tokval == REF_DOLLAR:
+                ref_start = True
+            elif tokval == REF_END_BRACE:
+                ref_start = False
+            if name_buffer and spos[1] != last_epos[1]:
+                tokens.append(''.join(name_buffer))
+                name_buffer = []
+            name_buffer.append(tokval)
+            last_epos = epos
         # Put NAME, and ERRORTOKEN tokens through the temp
         # buffer
-        if toknum in (NAME, ERRORTOKEN):
+        elif toknum in (NAME, ERRORTOKEN):
             # If this and the previous token in the temp buffer are not adjacent,
             # they belong to separate tokens
             if name_buffer and spos[1] != last_epos[1]:
                 tokens.append(''.join(name_buffer))
                 name_buffer = []
-            
+
             name_buffer.append(val)
             last_epos = epos
         # Other tokens can just go directly to the token list
@@ -89,6 +110,8 @@
     relation_name = "RelationBase"
     def __init__(self, data, left, right):
         self.description = ""
+        self.ref = None
+        self.lineno = None
         self.data = data or container.DataContainer()
         self.left = left
         self.right = right
@@ -98,6 +121,9 @@
         @return: A string presentation of the relation object
         """
         return "%s %s %s" % (self.left,self.relation_name,self.right)
+    
+    def __repr__(self):
+        return "%s(ref=%r, lineno=%r)" % (self.__class__.__name__, self.ref, self.lineno)
 
     def get_name(self):
         """
@@ -111,7 +137,7 @@
         """
         return self.description
         
-    def execute(self):
+    def execute(self, context=None):
         """
         Execute the relation object.
         """
@@ -161,12 +187,12 @@
 class RelationContainerImpl(RelationContainer):
     """ Base implementation for RelationContainer to use in ConE rules
     """
-    def execute(self):
+    def execute(self, context=None):
         ret = True
         i = 0
         for relation in self:
             i += 1
-            r = relation.execute()
+            r = relation.execute(context)
             ret = ret and r
         return ret
 
@@ -225,8 +251,9 @@
         super(BaseRelation, self).__init__(data, left, right)
         self.interpreter = ASTInterpreter(context=self.context)
 
-    def execute(self):
+    def execute(self, context=None):
         """
+        @param context: The context for execution can be given as a parameter. 
         @return Returns error dictionary
 
         In the client code proper way to check if the rule applies:
@@ -236,7 +263,7 @@
         """
         # logger.debug("Interpreter context %s" % self.interpreter.context)
         self.interpreter.create_ast('%s %s %s' % (self.left, self.KEY, self.right))
-        ret = self.interpreter.eval()
+        ret = self.interpreter.eval(context, relation=self)
         return ret
 
     def get_keys(self):
@@ -255,8 +282,44 @@
         return bool(self.interpreter.errors)
 
     def get_refs(self):
-        return (ASTInterpreter.extract_refs(self.left), ASTInterpreter.extract_refs(self.right))
+        """
+        Get a list of left side references and right side references.
+        @return: left refs
+        """
+        try:
+            refs = []
+            tempast = ASTInterpreter()
+            tempast.create_ast("%s" % self.left)
+            for exp in tempast.expression_list:
+                refs += exp.get_refs()
+        except Exception, e:
+            utils.log_exception(logging.getLogger('cone.rules'), "Exception in get_refs() of relation %r: %s" % (self, e))
+            return []
+        return refs
 
+    def get_set_refs(self):
+        """
+        Get a list of references that could get altered by set expression in this rule. 
+        This list is empty if the relation does not have any set expressions.
+        @return: a list of references.
+        """
+        
+        return [exp.left.get_ref() for exp in self.get_set_expressions()]
+
+    def get_expressions(self):
+        if not self.interpreter.expression_list:
+            self.interpreter.create_ast('%s %s %s' % (self.left, self.KEY, self.right))
+        return self.interpreter.expression_list
+    
+    def get_set_expressions(self):
+        setelems = []
+        if not self.interpreter.expression_list:
+            self.interpreter.create_ast('%s %s %s' % (self.left, self.KEY, self.right))
+        for elem in self.interpreter.expression_list:
+            if isinstance(elem, SetExpression):
+                setelems.append(elem)
+        return setelems
+        
     def _eval_rside_value(self, value): abstract()
     def _compare_value(self, value): abstract()
 
@@ -279,7 +342,7 @@
         return self.interpreter.errors
 
     def expand_rule_elements(self, rule):
-        """ Expans rule elements base on the reference.
+        """ Expands rule elements base on the reference.
         Context is used for fetching the child elements for parent references
         which uses asterisk identifier for selecting all child features: 
         'parent_feature.*' -> 'child_fea_1 and child_fea_2'.
@@ -298,7 +361,11 @@
                 else:
                     expanded_rule = expanded_element.rstrip()
             elif token.lower() in OPERATORS:
-                expanded_rule += ' %s ' % token
+                operator_class = OPERATORS[token]
+                if operator_class.PARAM_COUNT == 2:
+                    expanded_rule += ' %s ' % token
+                else:
+                    expanded_rule += '%s ' % token
             else:
                 if expanded_rule:
                     expanded_rule += '%s'% token
@@ -337,13 +404,32 @@
     def eval(self, ast, expression, value):
         pass
 
-    def get_keys(self, refs):
-        return ASTInterpreter.extract_refs(refs)
+    def set(self, expression, value):
+        """
+        set a element described with expression to value
+        @param expression: the expression refering to a element 
+        @param value:  the value to set 
+        @raise exception: when the setting value to expression fails.  
+        """
+        pass
 
     def get_children_for_reference(self, reference):
         # implement ConE specific children expansion
         pass
 
+    def convert_value(self, value):
+        if value in ('True', 'true', '1'):
+            return True
+        elif value in ('False', 'false', '0'):
+            return False
+        elif value in ('None',):
+            return None
+        else:
+            try:
+                return int(value)
+            except:
+                return value
+
     def handle_terminal(self, expression):
         try:
             return int(expression)
@@ -374,10 +460,18 @@
     def get_title(self):
         return self.KEY
 
-    def eval(self, context): pass
+    def is_terminal(self):
+        return False
+
+    def eval(self, context, **kwargs): pass
+
+    def get_refs(self): return []
 
 class OneParamExpression(Expression):
     PARAM_COUNT = 1
+    # OP that return itself 
+    OP = lambda _, x : x
+
     def __init__(self, ast, expression):
         super(OneParamExpression, self).__init__(ast)
         self.expression = expression
@@ -385,8 +479,11 @@
     def __unicode__(self):
         return u'%s %s' % (self.KEY, self.expression)
 
-    def eval(self, context):
-        self.value = self.OP(self.expression.eval(context))
+    def __str__(self):
+        return '%s %s' % (self.KEY, self.expression)
+
+    def eval(self, context, **kwargs):
+        self.value = self.OP(self.expression.eval(context)) 
         context.eval(self.ast, self, self.value)
         return self.value
 
@@ -403,38 +500,128 @@
     def __unicode__(self):
         return u'%s %s %s' % (self.left, self.KEY, self.right)
 
-    def eval(self, context):
+    def __str__(self):
+        return '%s %s %s' % (self.left, self.KEY, self.right)
+
+    def eval(self, context, **kwargs):
         self.value = self.OP(self.left.eval(context), self.right.eval(context))
         context.eval(self.ast, self, self.value)
         return self.value
 
 class TwoOperatorBooleanExpression(TwoOperatorExpression):
-    def eval(self, context):
-        self.value = self.OP(bool(self.left.eval(context)), bool(self.right.eval(context)))
+    def eval(self, context, **kwargs):
+        self.value = self.OP(bool(self.left.eval(context, **kwargs)), bool(self.right.eval(context, **kwargs)))
         context.eval(self.ast, self, self.value)
         return self.value         
 
-class TerminalExpression(Expression):
-    KEY = 'terminal'
+class ReferenceTerminal(Expression):
+    PARAM_COUNT = 0
+    KEY = 'reference'
 
     def __init__(self, ast, expression):
-        super(TerminalExpression, self).__init__(ast)
+        super(ReferenceTerminal, self).__init__(ast)
+        if not ASTInterpreter.is_ref(unicode(expression)):
+            expression = ASTInterpreter.create_ref(expression)
         self.expression = expression
 
-    def eval(self, context):
+    def is_terminal(self):
+        return True
+
+    def eval(self, context, **kwargs):
         """ Use context to eval the value
-        Expression on TerminalExpression is feature reference or value
+        Expression on ReferenceTerminal is feature reference or value
         context should handle the reference conversion to correct value
         """
-        self.value = context.handle_terminal(self.expression)
+        self.value = context.handle_terminal(ASTInterpreter.clean_ref(self.expression))
+        return self.value
+    
+    def get_ref(self):
+        """
+        @return: The setting reference, e.g. 'MyFeature.MySetting'
+        """
+        return ASTInterpreter.clean_ref(self.expression)
+
+    def get_refs(self):
+        """
+        """
+        return [u'%s' % self.get_ref()]
+
+    def __unicode__(self):
+        return self.expression
+    
+    def __str__(self):
+        return "(%s => %s)" % (self.expression, self.value)
+
+    def __repr__(self):
+        return self.expression
+
+class ValueTerminal(Expression):
+    PARAM_COUNT = 0
+    KEY = 'value_terminal'
+
+    def __init__(self, ast, expression):
+        super(ValueTerminal, self).__init__(ast)
+        self.expression = expression
+
+    def is_terminal(self):
+        return True
+
+    def eval(self, context, **kwargs):
+        self.value = context.convert_value(self.expression)
         return self.value
 
     def __unicode__(self):
         return self.expression
     
-    def __repr__(self):
+    def __str__(self):
         return self.expression
 
+class TypeCoercionError(exceptions.ConeException):
+    pass
+
+class AutoValueTerminal(Expression):
+    PARAM_COUNT = 0
+    KEY = 'autovalue_terminal'
+
+    def __init__(self, ast, expression):
+        super(AutoValueTerminal, self).__init__(ast)
+        self.expression = expression
+
+    def is_terminal(self):
+        return True
+
+    def eval(self, context, **kwargs):
+        type = kwargs.get('type', None)
+        
+        if self.expression in ("None", None):
+            self.value = None
+        elif type in (types.IntType, types.FloatType):
+            try:
+                self.value = type(self.expression)
+            except ValueError:
+                raise TypeCoercionError("Cannot coerce %r to %s" % (self.expression, type))
+        elif type == types.BooleanType:
+            if self.expression in ('True', 'true', True):
+                self.value = True
+            elif self.expression in ('False', 'false', False):
+                self.value = False
+            else:
+                raise TypeCoercionError("Cannot coerce %r to %s" % (self.expression, type))
+        elif type in types.StringTypes:
+            self.value = unicode(self.expression)
+        elif type == types.ListType:
+            self.value = list(self.expression)
+        else:
+            raise TypeCoercionError("Cannot coerce %r to %s" % (self.expression, type))
+        return self.value
+    
+    def __unicode__(self):
+        return self.expression
+    
+    def __str__(self):
+        return self.expression
+
+
 class NegExpression(OneParamExpression):
     PRECEDENCE = PRECEDENCES['PREFIX_OPERATORS']
     KEY= '-'
@@ -470,6 +657,11 @@
     KEY = '=='
     OP = ops.eq
 
+    def eval(self, context, **kwargs):
+        self.value = self.OP(self.left.eval(context), self.right.eval(context))
+        context.eval(self.ast, self, self.value)
+        return self.value
+
 class NotEqualExpression(TwoOperatorExpression):
     PRECEDENCE = PRECEDENCES['COMPARISON_OPERATORS']
     KEY = '!='
@@ -496,6 +688,59 @@
     OP = ops.ge
 
 
+def handle_multiply(self, left, right):
+    return left * right
+
+class MultiplyExpression(TwoOperatorExpression):
+    expression = "multiply_operation"
+    PRECEDENCE = PRECEDENCES['MULDIV_OPERATORS']
+    KEY= '*'
+    OP = handle_multiply
+
+def handle_divide(self, left, right):
+    return left / right
+
+class DivideExpression(TwoOperatorExpression):
+    expression = "divide_operation"
+    PRECEDENCE = PRECEDENCES['MULDIV_OPERATORS']
+    KEY= '/'
+    OP = handle_divide
+
+def handle_plus(self, left, right):
+    return left + right
+
+class PlusExpression(TwoOperatorExpression):
+    expression = "plus_operation"
+    PRECEDENCE = PRECEDENCES['ADDSUB_OPERATORS']
+    KEY= '+'
+    OP = handle_plus
+
+def handle_minus(self, left, right):
+    return left - right
+
+class MinusExpression(TwoOperatorExpression):
+    expression = "minus_operation"
+    PRECEDENCE = PRECEDENCES['ADDSUB_OPERATORS']
+    KEY= '-'
+    OP = handle_minus
+
+def handle_set(self, left, right):
+    left.set_value(right)
+
+class SetExpression(TwoOperatorExpression):
+    PRECEDENCE = PRECEDENCES['SET_OPERATORS']
+    KEY= '='
+    OP = handle_set
+
+    def eval(self, context, **kwargs):
+        if not isinstance(self.left, ReferenceTerminal):
+            raise RuntimeError("Can only set the value of a setting, '%s' is not a setting reference. Did you forget to use ${}?" % self.left.expression)
+        
+        value = self.right.eval(context, **kwargs)
+        context.set(self.left.get_ref(), value, **kwargs)
+        return True
+
+
 def handle_require(expression, left, right):
     if left and right:
         return True
@@ -508,13 +753,12 @@
     KEY = 'requires'
     OP = handle_require
 
-    def eval(self, context):
+    def eval(self, context, **kwargs):
         super(RequireExpression, self).eval(context)
         if not self.value:
             left_keys = []
             for ref in self.ast.extract_refs(unicode(self.left)):
-                for key in context.get_keys(ref):
-                    left_keys.append(key)
+                left_keys.append(ref)
 
             for key in left_keys:
                 self.ast.add_error(key, { 'error_string' : 'REQUIRES right side value is "False"',
@@ -535,13 +779,12 @@
     KEY = 'excludes'
     OP = handle_exclude
 
-    def eval(self, context):
+    def eval(self, context, **kwargs):
         super(ExcludeExpression, self).eval(context)
         if not self.value:
             left_keys = []
             for ref in self.ast.extract_refs(unicode(self.left)):
-                for key in context.get_keys(ref):
-                    left_keys.append(key)
+                left_keys.append(ref)
                     
             for key in left_keys:
                 self.ast.add_error(key, { 'error_string' : 'EXCLUDE right side value is "True"',
@@ -568,11 +811,38 @@
     A simple condition object that can refer to a model object and evaluate if the value matches  
     """
     def __init__(self, left, right):
-        lterm = TerminalExpression(None, left)
-        rterm = TerminalExpression(None, right)
+        if isinstance(left, basestring) and ASTInterpreter.is_ref(left):
+            lterm = ReferenceTerminal(None, left)
+        else:
+            lterm = ValueTerminal(None, left)
+        if isinstance(right, basestring) and ASTInterpreter.is_ref(right):
+            rterm = ReferenceTerminal(None, right)
+        else:
+            rterm = AutoValueTerminal(None, right)
         EqualExpression.__init__(self, None, lterm, rterm)
 
-
+    def eval(self, context, **kwargs):
+        left_value = self.left.eval(context)
+        try:
+            right_value = self.right.eval(context, type=type(left_value))
+        except TypeCoercionError:
+            # If type coercion fails, the result is always False
+            self.value = False
+            return self.value
+        
+        # Type coercion successful, perform value comparison
+        self.value = self.OP(left_value, right_value)
+        context.eval(self.ast, self, self.value)
+        return self.value
+    
+    def get_refs(self):
+        result = []
+        if isinstance(self.left, ReferenceTerminal):
+            result.append(self.left.get_ref())
+        if isinstance(self.right, ReferenceTerminal):
+            result.append(self.right.get_ref())
+        return result
+    
 # in format KEY : OPERATOR CLASS
 OPERATORS = {
     'and' : AndExpression,
@@ -590,7 +860,11 @@
     '>=' : GreaterThanEqualExpression,
     'requires' : RequireExpression,
     'excludes' : ExcludeExpression,
-    '-' : NegExpression
+    '-' : MinusExpression,
+    '+' : PlusExpression,
+    '*' : MultiplyExpression,
+    '/' : DivideExpression,
+    '=' : SetExpression
     }
 
 def add_operator(key, operator_class=None, baseclass=RequireExpression):
@@ -613,6 +887,29 @@
 
 class ParseException(Exception): pass
 
+def is_str_literal(value):
+    """
+    return true if the value is a string literal. A string that begins and ends with single or douple quotes.
+    @param value: the value to investigate
+    @return: Boolean
+    """
+    if  isinstance(value, (str, unicode)):
+        if re.match("[\"\'].*[\"\']", value):
+            return True
+    return False
+
+def get_str_literal(value):
+    """
+    return the string literal value
+    @param value: the value to convert
+    @return: string or unicode based on the input value
+    """
+    if  isinstance(value, (str, unicode)):
+        m =  re.match("[\"\'](.*)[\"\']", value)
+        if m:
+            return m.group(1)
+    return None
+
 class ASTInterpreter(object):
     def __init__(self, infix_expression=None, context=None):
         """ Takes infix expression as string """
@@ -629,6 +926,7 @@
         self.errors = {}
         self.postfix_array = []
         self.parse_tree = []
+        self.expression_list = []
         self.expression = infix_expression
 
     def __unicode__(self):
@@ -652,11 +950,11 @@
 
     def _infix_to_postfix(self):
         """
-        Shunting yard algorithm used to convert infix presentation to postfix.
+        Shunting yard algorithm used to convert infix presentation to postxfix.
         """
         if not self.expression:
             raise ParseException('Expression is None')
-        tokens = get_tokens(self.expression) # [token for token in self.expression.split()]
+        tokens = get_tokens(self.expression)
         stack = []
         # logger.debug('TOKENS: %s' % tokens)
         for token in tokens:
@@ -721,6 +1019,7 @@
     def _create_parse_tree(self):
         self.parse_tree = []
         for token in self.postfix_array:
+            is_ref = ASTInterpreter.is_ref(token)
             if token in OPERATORS:
                 # logger.debug('OP: %s' % (token))
                 expression_class = OPERATORS[token]
@@ -735,9 +1034,15 @@
 
                 # logger.debug('The operation: %s' % expression)
                 self.parse_tree.append(expression)
+                self.expression_list.append(expression)
+            elif not is_ref:
+                expression = ValueTerminal(self, token)
+                self.parse_tree.append(expression)
+                self.expression_list.append(expression)
             else:
-                expression = TerminalExpression(self, token)
+                expression = ReferenceTerminal(self, token)
                 self.parse_tree.append(expression)
+                self.expression_list.append(expression)
 
         #logger.debug('THE STACK: %s' % self.parse_tree)
         #for s in self.parse_tree:
@@ -745,22 +1050,41 @@
 
         return self.parse_tree
 
-    def eval(self):
+    def eval(self, context=None, **kwargs):
         """ Evals the AST
         If empty expression is given, None is returned
         """
         for expression in self.parse_tree:
-            self.value = expression.eval(self.context)
+            self.value = expression.eval(context or self.context, **kwargs)
         return self.value
 
     @staticmethod
     def extract_refs(expression):
         tokens = get_tokens(expression)
-        refs = []
-        for token in tokens:
-            if not token.lower() in OPERATORS and token != LEFT_PARENTHESIS and token != RIGHT_PARENTHESIS:
-                refs.append(token.strip('%s%s' % (LEFT_PARENTHESIS, RIGHT_PARENTHESIS)))
-        return refs
+        return [ASTInterpreter.clean_ref(t) for t in tokens if t.lower() not in OPERATORS and\
+                    t not in (LEFT_PARENTHESIS, RIGHT_PARENTHESIS) and\
+                    ASTInterpreter.is_ref(t)]
+
+    @staticmethod
+    def extract_non_operators(expression):
+        tokens = get_tokens(expression)
+        return [ASTInterpreter.clean_ref(t) for t in tokens if t.lower() not in OPERATORS and\
+                    t not in (LEFT_PARENTHESIS, RIGHT_PARENTHESIS)]
+
+    @staticmethod
+    def clean_ref(ref):
+        return ref.replace('$', '').replace('{', '').replace('}', '')
+
+    @staticmethod
+    def create_ref(ref):
+        return '${%s}' % ref
+
+    @staticmethod
+    def is_ref(val):
+        mo = REF_REGEX.match(val)
+        if mo and len(mo.groups()) > 0 and mo.group() == val:
+            return True
+        return False
 
 ##################################################################
 # Create and configure the main level logger
--- a/configurationengine/source/cone/public/tests/Import.pk	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/public/tests/Import.pk	Tue Aug 10 14:29:28 2010 +0300
@@ -1,110 +1,110 @@
-ccopy_reg
-_reconstructor
-p0
-(ccone.storage.stringstorage
-StringStorage
-p1
-c__builtin__
-object
-p2
-Ntp3
-Rp4
-(dp5
-S'_order'
-p6
-(lp7
-S'test1'
-p8
-aS'test2'
-p9
-aS'test3'
-p10
-asS'container'
-p11
-I01
-sS'_children'
-p12
-(dp13
-g8
-g0
-(ccone.storage.stringstorage
-_StringStorageObject
-p14
-g2
-Ntp15
-Rp16
-(dp17
-S'_parent'
-p18
-g4
-sg6
-(lp19
-sg12
-(dp20
-sS'path'
-p21
-S'test1.txt'
-p22
-sS'data'
-p23
-S'Testing reading.\n'
-p24
-sS'_name'
-p25
-g8
-sbsg10
-g0
-(g14
-g2
-Ntp26
-Rp27
-(dp28
-g18
-g4
-sg6
-(lp29
-sg12
-(dp30
-sg21
-S'test3.txt'
-p31
-sg23
-g24
-sg25
-g10
-sbsg9
-g0
-(g14
-g2
-Ntp32
-Rp33
-(dp34
-g18
-g4
-sg6
-(lp35
-sg12
-(dp36
-sg21
-S'test2.txt'
-p37
-sg23
-g24
-sg25
-g9
-sbssS'curpath'
-p38
-S''
-p39
-sS'rootpath'
-p40
-S'temp/unload.pk'
-p41
-sg25
-S'C:\\DocumentsandSettings\\teerytko\\workspace\\cone_trunk\\source\\cone\\public\\tests\\Import_pk'
-p42
-sg18
-NsS'ref'
-p43
-g42
+ccopy_reg
+_reconstructor
+p0
+(ccone.storage.stringstorage
+StringStorage
+p1
+c__builtin__
+object
+p2
+Ntp3
+Rp4
+(dp5
+S'_order'
+p6
+(lp7
+S'test1'
+p8
+aS'test2'
+p9
+aS'test3'
+p10
+asS'container'
+p11
+I01
+sS'_children'
+p12
+(dp13
+g8
+g0
+(ccone.storage.stringstorage
+_StringStorageObject
+p14
+g2
+Ntp15
+Rp16
+(dp17
+S'_parent'
+p18
+g4
+sg6
+(lp19
+sg12
+(dp20
+sS'path'
+p21
+S'test1.txt'
+p22
+sS'data'
+p23
+S'Testing reading.\n'
+p24
+sS'_name'
+p25
+g8
+sbsg10
+g0
+(g14
+g2
+Ntp26
+Rp27
+(dp28
+g18
+g4
+sg6
+(lp29
+sg12
+(dp30
+sg21
+S'test3.txt'
+p31
+sg23
+g24
+sg25
+g10
+sbsg9
+g0
+(g14
+g2
+Ntp32
+Rp33
+(dp34
+g18
+g4
+sg6
+(lp35
+sg12
+(dp36
+sg21
+S'test2.txt'
+p37
+sg23
+g24
+sg25
+g9
+sbssS'curpath'
+p38
+S''
+p39
+sS'rootpath'
+p40
+S'temp/unload.pk'
+p41
+sg25
+S'Import_pk'
+p42
+sg18
+NsS'ref'
+p43
+g42
 sb.
\ No newline at end of file
--- a/configurationengine/source/cone/public/tests/__init__.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/public/tests/__init__.py	Tue Aug 10 14:29:28 2010 +0300
@@ -13,34 +13,3 @@
 #
 # Description: 
 #
-
-import unittest, os, sys
-
-ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
-SOURCE_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../../..'))
-if SOURCE_ROOT not in sys.path:
-    sys.path.append(SOURCE_ROOT)
-
-# Find all unittest_*.py files in this folder
-import re
-__all__ = filter(lambda name: re.match(r'^unittest_.*\.py$', name) != None, os.listdir(ROOT_PATH))
-# Strip .py endings
-__all__ = map(lambda name: name[:-3], __all__)
-
-def collect_suite():  
-    sys.path.insert(0, ROOT_PATH)
-    try:
-        suite = unittest.TestSuite()
-        for test_module in __all__:
-            # Load the test module dynamically and add it to the test suite
-            module = __import__(test_module)
-            suite.addTests(unittest.TestLoader().loadTestsFromModule(module))
-        return suite
-    finally:
-        del sys.path[0]
-
-def runtests():
-    unittest.TextTestRunner(verbosity=2).run(collect_suite())
-
-if __name__ == '__main__':
-    runtests()
--- a/configurationengine/source/cone/public/tests/runtests.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/public/tests/runtests.py	Tue Aug 10 14:29:28 2010 +0300
@@ -14,6 +14,6 @@
 # Description: 
 #
 
-import __init__
-
-__init__.runtests()
+if __name__ == '__main__':
+    import nose
+    nose.core.run(argv=['collector','--include=unittest', '--verbosity=3'])
--- a/configurationengine/source/cone/public/tests/test_defaults.cfg	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/public/tests/test_defaults.cfg	Tue Aug 10 14:29:28 2010 +0300
@@ -1,6 +1,6 @@
 
 [DEFAULT]
-output_root=output
+output_root=
 output_subdir=
 plugin_output=
 output=%(output_root)s/%(output_subdir)s/%(plugin_output)s
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/tests/testdata/layer1/implml/test.implml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,11 @@
+<?xml version="1.0"?>
+<container xmlns="http://www.symbianfoundation.org/xml/implml/1">
+    <mock xmlns="http://www.test.com/xml/1"/>
+    <container>
+        <mock xmlns="http://www.test.com/xml/1"/>
+    </container>
+    <container xmlns="http://www.symbianfoundation.org/xml/implml/1">
+        <phase name="post"/>
+        <mock xmlns="http://www.test.com/xml/1"/>
+    </container>
+</container>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/tests/testdata/view_tests/customisation/confml/data.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/2" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/2#//confml2">
+	<confml:data>
+	</confml:data>
+</confml:configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/tests/testdata/view_tests/customisation/confml/my_standard_view.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<confml:configuration xmlns:confml="http://www.s60.com/xml/confml/2" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+  <confml:view id="my_view" name="My view">
+    <confml:desc>This is my test view.</confml:desc>
+    <confml:group name="Examples" id="group_examples">
+      <confml:desc>Different example settings.</confml:desc>
+      <confml:group name="Group Strings" id="g_strings">
+      <confml:desc>Different string settings.</confml:desc>
+        <confml:setting ref="example-feature/ExampleString1">
+            <confml:desc>Overrided description for ExampleString1.</confml:desc>
+        </confml:setting>
+        <confml:setting ref="example-feature/ExampleString2" name="My webpage">
+        <xs:minLength value="10"/>
+        <xs:maxLength value="60"/>
+        <xs:pattern value="(http(|s)://([\w-]+\.)+[\w-]+(:[0-9]{1,5})?(/[\w- ./?%&amp;=]*)?|)"/>
+        <xs:length value="15"/>
+        </confml:setting>
+      </confml:group>
+      <confml:group name="Group Ints" id="g_ints">
+        <confml:icon xlink:href="broken_image.png"/>
+      <confml:desc>Different int settings.</confml:desc>
+        <confml:setting ref="example-feature/ExampleInt1">
+          <confml:option name="Always Ask" value="0"/>
+          <confml:option name="Automatic" value="1"/>
+          <confml:option name="Autom. in home network" value="2"/>
+          <confml:option name="Disabled" value="3"/>
+          <xs:minExclusive value="0"/>
+          <xs:maxExclusive value="4"/>
+        </confml:setting>
+        <confml:setting ref="example-feature/ExampleInt2">
+            <xs:maxInclusive value="99"/>
+            <xs:minInclusive value="0"/>
+          <confml:option name="Unlimited time" value="0"/>
+        </confml:setting>
+        <confml:setting ref="example-feature/ExampleFilename" name="Filename">
+          <confml:property name="width" unit="pixel" value="134"/>
+          <confml:property name="height" unit="pixel" value="33"/>
+        </confml:setting>
+      </confml:group>
+    </confml:group>
+    <confml:group name="Mailboxes">
+        <confml:icon xlink:href="mails.png"/>
+    <confml:desc>Mailbox group - with no id!!!</confml:desc>
+       <confml:setting ref="mailbox1/set_int1" readOnly='true'/>
+       <confml:setting ref="mailbox1/set_int2"/>
+       <confml:setting ref="mailbox1/set_int3"/>
+       <confml:setting ref="mailbox1/set_int4"/>
+       <confml:setting ref="mailbox2/set_int1"/>
+       <confml:setting ref="mailbox2/set_int2"/>
+       <confml:setting ref="mailbox2/set_int3"/>
+       <confml:setting ref="mailbox2/set_int4"/>
+       <confml:setting ref="mailbox3/set_int1"/>
+       <confml:setting ref="mailbox3/set_int2"/>
+       <confml:setting ref="mailbox3/set_int3"/>
+       <confml:setting ref="mailbox3/set_int4"/>
+       <confml:setting ref="mailbox4/set_int1"/>
+       <confml:setting ref="mailbox4/set_int2"/>
+       <confml:setting ref="mailbox4/set_int3"/>
+       <confml:setting ref="mailbox4/set_int4"/>
+       <confml:setting ref="mailbox5/set_int1"/>
+       <confml:setting ref="mailbox5/set_int2"/>
+       <confml:setting ref="mailbox5/set_int3"/>
+       <confml:setting ref="mailbox5/set_int4"/>
+       <confml:setting ref="mailbox6/set_int1"/>
+       <confml:setting ref="mailbox6/set_int2"/>
+       <confml:setting ref="mailbox6/set_int3"/>
+       <confml:setting ref="mailbox6/set_int4"/>
+    </confml:group>
+    <confml:group name="Sequences" id="group_sequence">
+        <confml:desc>Sequence test in view, full, splitted, full with asterisks</confml:desc>
+        <confml:setting ref="german-car-fea/CarSequence"/>
+        <confml:setting ref="japan-car-fea/CarSequence/CarName" readOnly='true'/>
+        <confml:setting ref="italy-car-fea/CarSequence/*"/>
+    </confml:group>
+
+  </confml:view>
+</confml:configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/tests/testdata/view_tests/customisation/root_standard.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<configuration name="customisation__root_standard_confml" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
+	<xi:include href="confml/my_standard_view.confml" />
+	<xi:include href="confml/data.confml" />
+</configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/tests/testdata/view_tests/unit-test/confml/mailboxes.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/2"
+	xmlns:xi="http://www.w3.org/2001/XInclude"
+	xmlns:xs="http://www.w3.org/2001/XMLSchema"
+	version="1.0"
+	name="Mailboxes for unit tests"
+	>
+
+    	<feature name="Mailbox1" ref="mailbox1">
+		<desc>Mailbox1 description</desc>
+	    <setting name="Int1" type="int" ref="set_int1" required="true" constraint=". &gt;= set_int2">
+    		<desc>Integer 1, must be equal or bigger than #2</desc>
+	    </setting>
+	    <setting name="Int2" type="int" ref="set_int2" required="true" constraint=". &lt;= set_int1">
+	    	<desc>Integer 2, must be equal or smaller than #1</desc>
+	    </setting>
+	    <setting name="Int3" type="int" ref="set_int3" required="true" relevant ="set_int1 = 4">
+	    	<desc>Integer 3, relevant only if int1 is 4</desc>
+	    </setting>
+	    <setting name="Int4" type="int" ref="set_int4" required="true" constraint=". = set_int3" relevant="set_int2 = 2">
+	    	<desc>Integer 4, relevant only if int2 is 3, must be same as int3</desc>
+	    </setting>
+	</feature>
+    	<feature name="Mailbox2" ref="mailbox2">
+		<desc>Mailbox1 description</desc>
+	    <setting name="Int1" type="int" ref="set_int1" required="true" constraint=". &gt;= set_int2">
+    		<desc>Integer 1, must be equal or bigger than #2</desc>
+	    </setting>
+	    <setting name="Int2" type="int" ref="set_int2" required="true" constraint=". &lt;= set_int1">
+	    	<desc>Integer 2, must be equal or smaller than #1</desc>
+	    </setting>
+	    <setting name="Int3" type="int" ref="set_int3" required="true" relevant ="set_int1 = 4">
+	    	<desc>Integer 3, relevant only if int1 is 4</desc>
+	    </setting>
+	    <setting name="Int4" type="int" ref="set_int4" required="true" constraint=". = set_int3" relevant="set_int2 = 2">
+	    	<desc>Integer 4, relevant only if int2 is 3, must be same as int3</desc>
+	    </setting>
+	</feature>
+    	<feature name="Mailbox3" ref="mailbox3">
+		<desc>Mailbox1 description</desc>
+	    <setting name="Int1" type="int" ref="set_int1" required="true" constraint=". &gt;= set_int2">
+    		<desc>Integer 1, must be equal or bigger than #2</desc>
+	    </setting>
+	    <setting name="Int2" type="int" ref="set_int2" required="true" constraint=". &lt;= set_int1">
+	    	<desc>Integer 2, must be equal or smaller than #1</desc>
+	    </setting>
+	    <setting name="Int3" type="int" ref="set_int3" required="true" relevant ="set_int1 = 4">
+	    	<desc>Integer 3, relevant only if int1 is 4</desc>
+	    </setting>
+	    <setting name="Int4" type="int" ref="set_int4" required="true" constraint=". = set_int3" relevant="set_int2 = 2">
+	    	<desc>Integer 4, relevant only if int2 is 3, must be same as int3</desc>
+	    </setting>
+	</feature>
+    	<feature name="Mailbox4" ref="mailbox4">
+		<desc>Mailbox1 description</desc>
+	    <setting name="Int1" type="int" ref="set_int1" required="true" constraint=". &gt;= set_int2">
+    		<desc>Integer 1, must be equal or bigger than #2</desc>
+	    </setting>
+	    <setting name="Int2" type="int" ref="set_int2" required="true" constraint=". &lt;= set_int1">
+	    	<desc>Integer 2, must be equal or smaller than #1</desc>
+	    </setting>
+	    <setting name="Int3" type="int" ref="set_int3" required="true" relevant ="set_int1 = 4">
+	    	<desc>Integer 3, relevant only if int1 is 4</desc>
+	    </setting>
+	    <setting name="Int4" type="int" ref="set_int4" required="true" constraint=". = set_int3" relevant="set_int2 = 2">
+	    	<desc>Integer 4, relevant only if int2 is 3, must be same as int3</desc>
+	    </setting>
+	</feature>
+    	<feature name="Mailbox5" ref="mailbox5">
+		<desc>Mailbox1 description</desc>
+	    <setting name="Int1" type="int" ref="set_int1" required="true" constraint=". &gt;= set_int2">
+    		<desc>Integer 1, must be equal or bigger than #2</desc>
+	    </setting>
+	    <setting name="Int2" type="int" ref="set_int2" required="true" constraint=". &lt;= set_int1">
+	    	<desc>Integer 2, must be equal or smaller than #1</desc>
+	    </setting>
+	    <setting name="Int3" type="int" ref="set_int3" required="true" relevant ="set_int1 = 4">
+	    	<desc>Integer 3, relevant only if int1 is 4</desc>
+	    </setting>
+	    <setting name="Int4" type="int" ref="set_int4" required="true" constraint=". = set_int3" relevant="set_int2 = 2">
+	    	<desc>Integer 4, relevant only if int2 is 3, must be same as int3</desc>
+	    </setting>
+	</feature>
+    	<feature name="Mailbox6" ref="mailbox6">
+		<desc>Mailbox1 description</desc>
+	    <setting name="Int1" type="int" ref="set_int1" required="true" constraint=". &gt;= set_int2">
+    		<desc>Integer 1, must be equal or bigger than #2</desc>
+	    </setting>
+	    <setting name="Int2" type="int" ref="set_int2" required="true" constraint=". &lt;= set_int1">
+	    	<desc>Integer 2, must be equal or smaller than #1</desc>
+	    </setting>
+	    <setting name="Int3" type="int" ref="set_int3" required="true" relevant ="set_int1 = 4">
+	    	<desc>Integer 3, relevant only if int1 is 4</desc>
+	    </setting>
+	    <setting name="Int4" type="int" ref="set_int4" required="true" constraint=". = set_int3" relevant="set_int2 = 2">
+	    	<desc>Integer 4, relevant only if int2 is 3, must be same as int3</desc>
+	    </setting>
+	</feature>
+</configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/tests/testdata/view_tests/unit-test/confml/options_test.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/2"
+	       xmlns:xi="http://www.w3.org/2001/XInclude"
+	       xmlns:xs="http://www.w3.org/2001/XMLSchema"
+	       version="1.0">
+      <feature ref="Optiontest" name="Options Tests" >
+            <setting ref="sequence_test" name="Sequence of options" type="sequence" required="true">
+                <setting ref="selection_test" name="Selection field" type="selection"> 
+                    <option name="String 1" value="string1" />
+                    <option name="String 2" value="string2" />
+                    <option name="String 3" value="string3" />
+                </setting>
+                <setting ref="string_test" name="String field" type="string" required="false"> 
+                    <option name="String 1" value="string1" />
+                    <option name="String 2" value="string2" />
+                    <option name="String 3" value="string3" />
+                </setting>
+                <setting ref="int_test" name="Integer field" type="int" required="true"> 
+                    <option name="Integer 1" value="0123" />
+                    <option name="Integer 2" value="4567" />
+                    <option name="Integer 3" value="7890" />
+                </setting>
+            </setting>
+    </feature>   
+  <data>
+    <Optiontest>
+    </Optiontest>
+  </data>
+</configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/tests/testdata/view_tests/unit-test/confml/unit-test.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,368 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/2"
+	xmlns:xi="http://www.w3.org/2001/XInclude"
+	xmlns:xs="http://www.w3.org/2001/XMLSchema"
+	version="1.0"
+	name="Another example configuration for unit tests"
+	>
+
+	<feature name="Constraints and relevants" ref="constraints-int-fea">
+		<desc>Some int constraints testing</desc>
+		
+	    <setting name="Int1" type="int" ref="set_int1" required="true" constraint=". &gt;= set_int2">
+    		<desc>Integer 1, must be equal or bigger than #2</desc>
+	    </setting>
+	    <setting name="Int2" type="int" ref="set_int2" required="true" constraint=". &lt;= set_int1">
+	    	<desc>Integer 2, must be equal or smaller than #1</desc>
+	    </setting>
+	    <setting name="Int3" type="int" ref="set_int3" required="true" relevant ="set_int1 = 4">
+	    	<desc>Integer 3, relevant only if int1 is 4</desc>
+	    </setting>
+	    <setting name="Int4" type="int" ref="set_int4" required="true" constraint=". = set_int3" relevant="set_int2 = 2">
+	    	<desc>Integer 4, relevant only if int2 is 3, must be same as int3</desc>
+	    </setting>
+	</feature>
+
+	<feature name="German cars" ref="german-car-fea">
+		<desc>Some german cars</desc>
+	    <setting name="German car Sequence" type="sequence" ref="CarSequence" maxOccurs="10" mapKey="CarName" mapValue="CarNum">
+		<desc>Example sequence containing one string and one int</desc>
+		
+		    <setting name="Car string in sequence" type="string" ref="CarName" required="true">
+			<desc>Car string in sequence description</desc>
+		    </setting>
+		    <setting name="Car int in sequence" type="int" ref="CarNum" required="true">
+			<desc>Car int in sequence description</desc>
+		    </setting>
+		
+	      </setting>
+	</feature>
+
+	<feature name="Japanese cars" ref="japan-car-fea">
+		<desc>Some japan cars</desc>
+	    <setting name="Japan car Sequence" type="sequence" ref="CarSequence" minOccurs="1" maxOccurs="11" mapKey="CarName" mapValue="CarNum">
+		<desc>Example sequence containing one string and one int</desc>
+		
+		    <setting name="Car string in sequence" type="string" ref="CarName" required="true">
+			<desc>Car string in sequence description</desc>
+		    </setting>
+		    <setting name="Car int in sequence" type="int" ref="CarNum" required="true">
+			<desc>Car int in sequence description</desc>
+		    </setting>
+		
+	      </setting>
+	</feature>
+
+	<feature name="Italian cars" ref="italy-car-fea">
+		<desc>Some italy cars</desc>
+	    <setting name="italy car Sequence" type="sequence" ref="CarSequence" minOccurs="2" maxOccurs="12" mapKey="CarName" mapValue="CarNum">
+		<desc>Example sequence containing one string and one int</desc>
+		
+		    <setting name="Car string in sequence" type="string" ref="CarName" required="true">
+			<desc>Car string in sequence description</desc>
+		    </setting>
+		    <setting name="Car int in sequence" type="int" ref="CarNum" required="true">
+			<desc>Car int in sequence description</desc>
+		    </setting>
+		
+	      </setting>
+	</feature>
+
+	<feature name="Bikes" ref="bike-feature">
+		<desc>Some bikes</desc>
+	    <setting name="Bike Sequence" type="sequence" ref="BikeSequence" minOccurs="2" maxOccurs="10" mapKey="BikeName" mapValue="BikeNum">
+		<desc>Example sequence containing one string and one int</desc>
+		
+		    <setting name="Bike string in sequence" type="string" ref="BikeName" required="true">
+			<desc>Bike string in sequence description</desc>
+		    </setting>
+		    <setting name="Bike int in sequence" type="int" ref="BikeNum" required="true">
+			<desc>Bike int in sequence description</desc>
+		    </setting>
+		
+	      </setting>
+	</feature>
+
+	<feature name="This is example feature (group) name" ref="example-feature">
+		<desc>This is example feature group description</desc>
+		
+		<setting name="Example String1" id="example1_id" required="true" type="string" ref="ExampleString1">
+			<desc>Example string description. Min length 10, max 50.</desc>
+			<xs:minLength value="10" />
+			<xs:maxLength value="50" />
+		</setting>
+		<setting name="Example Int1" required="true" type="int" ref="ExampleInt1">
+			<desc>Example number description. Value must be between 2000-2100 (inclusive)</desc>
+			<xs:minInclusive value="2000" />
+			<xs:maxInclusive value="2100" />
+		</setting>
+		
+		<setting name="Example String2 with options" required="false" type="string" ref="ExampleString2">
+			<desc>Example string description 2. Not required field. Length 5 characters.</desc>
+			<xs:length value="5"/>
+		    <option name="Oulu-Pori" value="507" />
+		    <option name="Oulu-Tampere" value="488" />
+		    <option name="Oulu-Helsinki" value="609" />
+		    <option name="Oulu-Kuusamo" value="216" />
+		    <option name="Oulu-Tornio" value="132" />
+		    <option name="Oulu-Kilpisjärvi" value="589" />
+		    <option name="Oulu-Utsjoki" value="671" />
+		</setting>
+		<setting name="Example Int2 with options" required="true" type="int" ref="ExampleInt2">
+			<desc>Example number description 2. Value must be between 0-799 (exclusive 800)</desc>
+			<xs:minInclusive value="0" /> 
+			<xs:maxExclusive value="800" /> 
+		    <option name="Option 1" value="1" />
+		    <option name="Option 2" value="2" />
+		    <option name="option 3" value="3" />
+		</setting>
+
+		<setting name="Example Int3" id="example2_id" required="true" type="int" ref="ExampleInt3">
+			<desc>Example number description 3. Value must be between 10-20.</desc>
+			<xs:minExclusive value="9" />
+			<xs:maxInclusive value="20" />
+		</setting>
+		
+  		<setting name="Example Filename" type="file" ref="ExampleFilename" required="true">
+       		<desc>Example file. Target read only, pattern .*\.png</desc>
+       		<property name="maxHeight" value="40" /> 
+		    <property name="maxWidth" value="120" />
+		    <localPath />
+		    <targetPath readOnly="true" /> 
+		    <xs:pattern value="(.*\.png)" /> 
+  		</setting>
+
+  		<setting name="Example Folder" type="folder" ref="ExampleFolder" required="true">
+       		<desc>Example folder.</desc>
+       		<localPath /> 
+		    <targetPath readOnly="true" /> 
+  		</setting>
+
+		<setting name="Example Real" required="false" type="real" ref="ExampleReal">
+			<desc>Example real description. Not required field.</desc>
+		</setting>
+
+	    <setting name="Example Selection" type="selection" ref="ExampleSelection" required="true">
+		<desc>Example selection numbers from 1 to 5</desc>
+		<option name="Number 1" value="1" />
+		<option name="Number 2" value="2" />
+		<option name="Number 3" value="3" />
+		<option name="Number 4" value="4" />
+		<option name="Number 5" value="5" />
+		<option name="New Number" value="12" />
+	    </setting>
+
+	    <setting name="Example MultiSelection" type="multiSelection" ref="ExampleMultiSelection" required="true">
+		<desc>Example multi selection characters from A to E</desc>
+		<option name="Char A" value="A A" />
+		<option name="Char B" value="B B" />
+		<option name="Char C" value="C C" />
+		<option name="Char D" value="D D" />
+		<option name="Char E" value="E E" />
+	    </setting>
+		
+	    <setting name="Example Boolean" type="boolean" ref="ExampleBoolean" required="true">
+		<desc>Example boolean</desc>
+	    </setting>
+	      
+	    <setting name="Example Sequence" type="sequence" ref="ExampleSequence" required="false" minOccurs="2" maxOccurs="10">
+		<desc>Example sequence containing one string and one int</desc>
+		
+		    <setting name="Example string in sequence" type="string" ref="ExampleStringInSequence" required="true">
+			<desc>Example string in sequence description</desc>
+		    </setting>
+		    <setting name="Example int in sequence" type="int" ref="ExampleIntInSequence" required="true">
+			<desc>Example int in sequence description</desc>
+		    </setting>
+		
+	      </setting>
+
+	      <setting name="Example Date" type="date" ref="ExampleDate" required="true">
+		<desc>Example date description</desc>
+	      </setting>
+	      
+	      <setting name="Example Time" type="time" ref="ExampleTime" required="true">
+		<desc>Example time description</desc>
+	      </setting>
+	      
+	      <setting name="Example DateTime" type="dateTime" ref="ExampleDateTime" required="true">
+		<desc>Example date/time description</desc>
+	      </setting>
+
+	      <setting name="Example Duration" type="duration" ref="ExampleDuration" required="true">
+		<desc>Example duration description, 2 days, 5 hours</desc>
+	      </setting>
+		
+	</feature>
+
+	<feature name="Options map group" ref="example2-feature">
+		<desc>This is another example feature group for testing different map options</desc>
+
+	    <setting name="Example Selection to options only (MB)" type="selection" ref="ExampleSelectionToOptions" required="true">
+		<desc>Example selection values (options)</desc>
+		<option name="Option-Volkswagen (1)" value="1" />
+		<option name="Option-Mercedes Bentz (2)" value="2" />
+		<option name="Option-Citroen :) (3)" value="3" />
+		<option name="Option-Daihatsu (4)" value="4" />
+		<option name="Option-Ford (5)" value="5" />
+		<option name="Option-Opel (6)" value="6" />
+	    </setting>
+
+	    <setting name="Selection, one map, german (Bmw)" type="selection" ref="ExampleSelectionToGermanCarsMap" required="true">
+		<desc>Example selection to one map, German cars</desc>
+        <option map="german-car-fea/CarSequence" />
+	    </setting>
+
+	    <setting name="Selection, one map, italian (Ferrari)" type="selection" ref="ExampleSelectionToItalianCarsMap" required="true">
+		<desc>Example selection to one map, Italian cars</desc>
+        <option map="italy-car-fea/CarSequence" />
+	    </setting>
+
+	    <setting name="Selection, one map, japanese (Toyota)" type="selection" ref="ExampleSelectionToJapaneseCarsMap" required="true">
+		<desc>Example selection to one map, Japanese cars</desc>
+        <option map="japan-car-fea/CarSequence" />
+	    </setting>
+
+	    <setting name="Selection, three maps, all cars (Mitsu)" type="selection" ref="ExampleSelectionToAllCarsMap" required="true">
+		<desc>Example selection to three maps, German, Italian and Japanese cars</desc>
+        <option map="german-car-fea/CarSequence" />
+        <option map="italy-car-fea/CarSequence" />
+        <option map="japan-car-fea/CarSequence" />
+	    </setting>
+
+	    <setting name="Selection, four maps and extra options (Opel)" type="selection" ref="ExampleSelectionToMap" required="true">
+		<desc>Example selection to four maps, bikes, all cars and some option values also</desc>
+        <option map="german-car-fea/CarSequence" />
+		<option name="Option-Volkswagen (1)" value="1" />
+		<option name="Option-Mercedes Bentz (2)" value="2" />
+		<option name="Option-Citroen :) (3)" value="3" />
+        <option map="bike-feature/BikeSequence" />
+        <option map="japan-car-fea/CarSequence" />
+		<option name="Option-Daihatsu (4)" value="4" />
+		<option name="Option-Ford (5)" value="5" />
+		<option name="Option-Opel (6)" value="6" />
+        <option map="italy-car-fea/CarSequence" />
+	    </setting>
+
+	    <setting name="Example MultiSelection to map (Merida and Helkama)" type="multiSelection" ref="ExampleMultiSelectionToMap" required="true">
+		<desc>Example multi selection values from x to y and map to bikes</desc>
+		<option name="Crescent (1)" value="1" />
+		<option name="Insera (2)" value="2" />
+        <option map="bike-feature/BikeSequence" />
+		<option name="Merida (3)" value="3" />
+	    </setting>
+
+	</feature>
+	
+	<data>
+            <constraints-int-fea>
+                <set_int1>4</set_int1>
+                <set_int2>2</set_int2>
+                <set_int3>3</set_int3>
+                <set_int4>3</set_int4>
+            </constraints-int-fea>
+
+            <german-car-fea>
+                <CarSequence>
+                    <CarName>Audi</CarName>
+                    <CarNum>111</CarNum>
+                </CarSequence>
+                <CarSequence>
+                    <CarName>Bmw</CarName>
+                    <CarNum>222</CarNum>
+                </CarSequence>
+            </german-car-fea>
+
+            <japan-car-fea>
+                <CarSequence>
+                    <CarName>Subaru</CarName>
+                    <CarNum>555</CarNum>
+                </CarSequence>
+                <CarSequence>
+                    <CarName>Mitsubishi</CarName>
+                    <CarNum>666</CarNum>
+                </CarSequence>
+                <CarSequence>
+                    <CarName>Toyota</CarName>
+                    <CarNum>777</CarNum>
+                </CarSequence>
+            </japan-car-fea>
+
+            <italy-car-fea>
+                <CarSequence>
+                    <CarName>Ferrari</CarName>
+                    <CarNum>888</CarNum>
+                </CarSequence>
+                <CarSequence>
+                    <CarName>Fiat</CarName>
+                    <CarNum>999</CarNum>
+                </CarSequence>
+            </italy-car-fea>
+
+            <bike-feature>
+                <BikeSequence>
+                    <BikeName>Tunturi</BikeName>
+                    <BikeNum>28</BikeNum>
+                </BikeSequence>
+                <BikeSequence>
+                    <BikeName>Helkama</BikeName>
+                    <BikeNum>26</BikeNum>
+                </BikeSequence>
+            </bike-feature>
+
+	        <example-feature>
+	           <ExampleString1>The Year (Current)</ExampleString1>
+	           <ExampleInt1>2009</ExampleInt1>
+	           <ExampleString2>Hello</ExampleString2>
+	           <ExampleInt2>555</ExampleInt2>
+	           <ExampleInt3>13</ExampleInt3>
+	           <ExampleReal>3.14</ExampleReal>
+		   <ExampleFilename>
+		       <localPath>somefile.png</localPath>
+		       <targetPath>BUILD:///data</targetPath>
+		   </ExampleFilename>
+		   <ExampleFolder>
+		       <localPath>UI/Application data</localPath>
+		       <targetPath>BUILD:///data/UI</targetPath>
+		   </ExampleFolder>
+		   <ExampleSelection>3</ExampleSelection>
+		   <ExampleMultiSelection>"B B" "C C" "E E"</ExampleMultiSelection>
+		   <ExampleBoolean>true</ExampleBoolean>
+		   <ExampleSequence>
+		       <ExampleStringInSequence>Some century</ExampleStringInSequence>
+		       <ExampleIntInSequence>1900</ExampleIntInSequence>
+		   </ExampleSequence>
+		   <ExampleSequence>
+		       <ExampleStringInSequence>Some century X</ExampleStringInSequence>
+		       <ExampleIntInSequence>2101</ExampleIntInSequence>
+		   </ExampleSequence>
+		   
+		   <ExampleSequence>
+		       <ExampleStringInSequence>Django!</ExampleStringInSequence>
+		       <ExampleIntInSequence>1</ExampleIntInSequence>
+		   </ExampleSequence>
+
+		   <ExampleSequence>
+		       <ExampleStringInSequence>Fox</ExampleStringInSequence>
+		       <ExampleIntInSequence>3</ExampleIntInSequence>
+		   </ExampleSequence>
+		   
+		   <ExampleDate>2009-01-19Z</ExampleDate>
+		   <ExampleTime>09:15:00</ExampleTime>
+		   <ExampleDateTime>2009-01-19T09:15:00Z</ExampleDateTime>
+		   <ExampleDuration>P2DT2H</ExampleDuration>
+
+	        </example-feature>
+
+	        <example2-feature>
+            <ExampleSelectionToOptions>2</ExampleSelectionToOptions>
+            <ExampleSelectionToGermanCarsMap>222</ExampleSelectionToGermanCarsMap>
+            <ExampleSelectionToItalianCarsMap>888</ExampleSelectionToItalianCarsMap>
+            <ExampleSelectionToJapaneseCarsMap>777</ExampleSelectionToJapaneseCarsMap>
+            <ExampleSelectionToAllCarsMap>666</ExampleSelectionToAllCarsMap>
+
+            <ExampleSelectionToMap>6</ExampleSelectionToMap>
+            <ExampleMultiSelectionToMap>"3" "26"</ExampleMultiSelectionToMap>
+	        </example2-feature>
+	</data>
+</configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/tests/testdata/view_tests/unit-test/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,5 @@
+<configuration name="unit_test__root_confml" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+  <xi:include href="confml/unit-test.confml" />
+  <xi:include href="confml/options_test.confml" />
+  <xi:include href="confml/mailboxes.confml" />
+</configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/tests/testdata/view_tests/view_tests-cpf.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,19 @@
+<configuration name="view_tests-cpf_root_confml" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+  <xi:include href="unit-test/root.confml" />
+  <xi:include href="customisation/root_standard.confml" />
+<meta xmlns:cv="http://www.nokia.com/xml/cpf-id/1">
+    <version>234</version>
+  <release>031.001</release>
+  <platform>S60 / 3.2</platform>
+  <product>tiger</product>
+  <date>2009-11-17</date>
+  <cv:configuration-property name="coreplat_name" value="ncp71" />
+  <cv:configuration-property name="coreplat_version" value="71" />
+  <cv:configuration-property name="s60_version" value="32" />
+  <cv:configuration-property name="sos_version" value="9.3" />
+  <cv:configuration-property name="product_name" value="tiger" />
+  <cv:configuration-property name="product_type" value="tiger-576" />
+  <cv:configuration-property name="sw_version" value="031.001" />
+  <cv:configuration-property name="based_on_ctr" value="0589266" />
+  </meta>
+</configuration>
--- a/configurationengine/source/cone/public/tests/unittest_base.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/public/tests/unittest_base.py	Tue Aug 10 14:29:28 2010 +0300
@@ -18,11 +18,8 @@
 Test the configuration
 """
 import unittest
-import string
-import sys,os
-import __init__
 
-from cone.public import api,exceptions,utils, container
+from cone.public import api, container
 
 class TestBase(unittest.TestCase):    
     # @test 
@@ -35,6 +32,11 @@
         self.assertTrue(base)
         self.assertEquals(base.namespace,"")
 
+    def test_get_configuration(self):
+        base= api.Base("foo")
+        self.assertEquals(base.get_configuration(),None)
+        self.assertEquals(base.get_configuration_path(),None)
+
     def test_properties(self):
         base= api.Base("foo")
         self.assertTrue(base)
@@ -52,7 +54,7 @@
         self.assertEquals(base.bar.fqr, 'foo.bar')
         self.assertEquals(base.bar.get_fullfqr(), 'foo.bar')
 
-    def test_create_hiearchy_with_container(self):
+    def test_create_hiearchy_with_container_test_path(self):
         cont= api.Base("", container=True)
         base= api.Base("foo")
         base._add(api.Base("bar1"))
@@ -65,6 +67,20 @@
         self.assertEquals(cont.foo.bar1.namespace, 'foo')
         self.assertEquals(cont.foo.bar2.bar21.namespace, 'foo.bar2')
         self.assertEquals(cont.foo.bar2.bar21.fqr, 'foo.bar2.bar21')
+        self.assertEquals(cont.foo.bar2.bar21.path(cont.foo.bar2), 'bar21')
+        self.assertEquals(cont.foo.bar2.bar21.path(cont.foo), 'bar2.bar21')
+        self.assertEquals(cont.foo.bar2.bar21.path(cont), 'foo.bar2.bar21')
+
+    def test_create_hiearchy_with_container_test_parent_path(self):
+        cont= api.Base("", container=True)
+        base= api.Base("foo")
+        base._add(api.Base("bar1"))
+        base._add(api.Base("bar2"))
+        base.bar2._add(api.Base("bar21"))
+        cont._add(base)
+        self.assertEquals(cont.foo.bar2.bar21.parent_path(cont.foo.bar2), '')
+        self.assertEquals(cont.foo.bar2.bar21.parent_path(cont.foo), 'bar2')
+        self.assertEquals(cont.foo.bar2.bar21.parent_path(cont), 'foo.bar2')
 
     def test_create_hiearchy_with_container_and_hidden_elem(self):
         cont= api.Base("", container=True)
@@ -99,5 +115,4 @@
         self.assertEquals(cont.foo.bar1[0].bar21.get_fullfqr(), 'foo.bar1[0].bar21')
 
 if __name__ == '__main__':
-      unittest.main()
-      
+    unittest.main()
--- a/configurationengine/source/cone/public/tests/unittest_configuration.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/public/tests/unittest_configuration.py	Tue Aug 10 14:29:28 2010 +0300
@@ -12,19 +12,20 @@
 # Contributors:
 #
 # Description: 
-#
+#    
 
 """
 Test the configuration
 """
 import unittest
-import string
-import sys,os
-import __init__
+import os
+import pickle 
 
-from cone.public import api,exceptions,utils
+from cone.public import api,exceptions
 from cone.storage import persistentdictionary
-from cone.confml import persistentconfml
+from testautomation.utils import remove_if_exists
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
 
 class TestConfiguration(unittest.TestCase):    
     def setUp(self):
@@ -35,6 +36,29 @@
         conf = api.Configuration("testmee.confml")
         self.assertTrue(conf)
 
+    def test_configuration_reduce_ex(self):
+        prj = api.Project(api.Storage('.'))
+        conf = api.Configuration("testmee.confml")
+        prj.add_configuration(conf)
+        tpl = conf.__reduce_ex__(2)
+        self.assertEquals(tpl[2]['_storeint'],prj)
+        self.assertEquals(tpl[2]['path'],'testmee.confml')
+        
+    def test_configuration_pickle(self):
+        remove_if_exists(os.path.join(ROOT_PATH,'temp'))
+        prj = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'temp'), 'w'))
+        conf = api.Configuration("testmee.confml")
+        prj.add_configuration(conf, True)
+        prj.save()
+        dfile  = open(os.path.join(ROOT_PATH,'temp/out.dat'), 'w')
+        pickle.dump(conf, dfile)
+        dfile.close()
+        dfile  = open(os.path.join(ROOT_PATH,'temp/out.dat'))
+        conf2 = pickle.load(dfile)
+        self.assertEquals(conf2.path,'testmee.confml')
+        self.assertEquals(conf2.name,'testmee_confml')
+
+
     def test_get_root_configuration(self):
         conf = api.Configuration("testmee.confml")
         self.assertEquals(conf.get_root_configuration(),conf)
@@ -64,6 +88,16 @@
         self.assertEquals(conf1.ref,conf2.ref)
         self.assertEquals(conf1.namespace,conf2.namespace)
  
+    def test_get_configuration_and_path(self):
+        conf1 = api.Configuration("testmee.confml")
+        fea = conf1.create_feature('test1')
+        conf1.create_feature('test2')
+        subfea = fea.create_feature('child1')
+        self.assertEquals(fea.get_configuration(), conf1)
+        self.assertEquals(fea.get_configuration_path(), 'testmee.confml')
+        self.assertEquals(subfea.get_configuration(), conf1)
+        self.assertEquals(subfea.get_configuration_path(), 'testmee.confml')
+        
     def test_clone_single_configuration(self):
         conf1 = api.Configuration("testmee.confml")
         conf1.add_feature(api.Feature('test1'))
@@ -104,28 +138,28 @@
     def test_add(self):
         conf = api.Configuration("data/simple.confml")
         layer = api.Configuration("laa")
-        conf._add(layer)
+        conf.add_configuration(layer)
         self.assertEquals(conf.list_configurations()[0],"laa")    
 
     def test_add_and_access_via_member(self):
         conf = api.Configuration("data/simple.confml")
         layer = api.Configuration("laa")
-        conf._add(layer)
-        self.assertEquals(conf.laa._name,"laa")    
+        conf.add_configuration(layer)
+        self.assertEquals(conf.laa.name,"laa")    
 
     def test_add_and_add_another_config_under(self):
         conf = api.Configuration("data/simple.confml")
         layer = api.Configuration("laa")
-        conf._add(layer)
-        conf.laa._add(api.Configuration("foo"))
-        self.assertEquals(conf.laa.foo._name,"foo")    
+        conf.add_configuration(layer)
+        conf.laa.add_configuration(api.Configuration("foo"))
+        self.assertEquals(conf.laa.foo.name,"foo")    
 
     def test_add_several_configurations(self):
         conf = api.Configuration("data/simple.confml")
         layer = api.Configuration("laa")
-        conf._add(layer)
-        conf._add(api.Configuration("foo"))
-        conf._add(api.Configuration("faa"))
+        conf.add_configuration(layer)
+        conf.add_configuration(api.Configuration("foo"))
+        conf.add_configuration(api.Configuration("faa"))
         self.assertEquals(conf.list_configurations()[0],"laa")    
         self.assertEquals(conf.list_configurations()[1],"foo")    
         self.assertEquals(conf.list_configurations()[2],"faa")    
@@ -133,10 +167,10 @@
     def test_add_several_and_remove_one_layer(self):
         conf = api.Configuration("data/simple.confml")
         layer = api.Configuration("laa")
-        conf._add(layer)
-        conf._add(api.Configuration("foo"))
-        conf._add(api.Configuration("faa"))
-        conf._remove("foo")
+        conf.add_configuration(layer)
+        conf.add_configuration(api.Configuration("foo"))
+        conf.add_configuration(api.Configuration("faa"))
+        conf.remove_configuration("foo")
         
         self.assertEquals(conf.list_configurations()[0],"laa")    
         self.assertEquals(conf.list_configurations()[1],"faa")    
@@ -144,101 +178,108 @@
     def test_add_several_and_remove_last_layer(self):
         conf = api.Configuration("data/simple.confml")
         layer = api.Configuration("laa")
-        conf._add(layer)
-        conf._add(api.Configuration("foo"))
-        conf._add(api.Configuration("faa"))
-        conf._remove("faa")
+        conf.add_configuration(layer)
+        conf.add_configuration(api.Configuration("foo"))
+        conf.add_configuration(api.Configuration("faa"))
+        conf.remove_configuration("faa")
         self.assertEquals(conf.list_configurations()[0],"laa")    
         self.assertEquals(conf.list_configurations()[1],"foo")    
 
     def test_add_several_and_remove_all_configurations(self):
         conf = api.Configuration("data/simple.confml")
         layer = api.Configuration("laa")
-        conf._add(layer)
-        conf._add(api.Configuration("foo"))
-        conf._add(api.Configuration("faa"))
+        conf.add_configuration(layer)
+        conf.add_configuration(api.Configuration("foo"))
+        conf.add_configuration(api.Configuration("faa"))
         for layername in conf.list_configurations():
-            conf._remove(layername)
+            conf.remove_configuration(layername)
             
         self.assertTrue(len(conf.list_configurations())==0)        
 
     def test_add_several_and_try_to_remove_not_existing(self):
         conf = api.Configuration("data/simple.confml")
         layer = api.Configuration("laa")
-        conf._add(layer)
-        conf._add(api.Configuration("foo"))
-        conf._add(api.Configuration("faa"))
+        conf.add_configuration(layer)
+        conf.add_configuration(api.Configuration("foo"))
+        conf.add_configuration(api.Configuration("faa"))
         try:
-            conf._remove("notthere")
+            conf.remove_configuration("notthere")
             self.fail("removing of nonexisting layer succeeds!")
         except exceptions.NotFound:
             pass
 
-    def test_add_view_simple(self):
+    def test_create_view_simple(self):
         conf = api.Configuration("data/simple.confml")
-        conf.add_view("view1")
+        conf.create_view("view1")
         view = conf.get_view("view1")
-        self.assertEquals(view._list(),[])
+        self.assertEquals(view.list_groups(),[])
         
-    def test_add_views_and_list_views(self):
+    def test_create_views_and_list_views(self):
         conf = api.Configuration("data/simple.confml")
-        conf.add_view("view1")
-        conf.add_view("view2")
+        conf.create_view("view1")
+        conf.create_view("view2")
         self.assertEquals(conf.list_views(),['view1','view2'])
 
-    def test_add_views_and_remove_one(self):
+    def test_create_views_and_remove_one(self):
         conf = api.Configuration("data/simple.confml")
-        conf.add_view("view1")
-        conf.add_view("view2")
-        conf.add_view("view3")
+        conf.create_view("view1")
+        conf.create_view("view2")
+        conf.create_view("view3")
         conf.remove_view('view2')
         self.assertEquals(conf.list_views(),['view1','view3'])
 
-    def test_add_views_and_remove_invalid(self):
+    def test_create_views_and_remove_invalid(self):
         conf = api.Configuration("data/simple.confml")
-        conf.add_view("view1")
-        conf.add_view("view2")
-        conf.add_view("view3")
+        conf.create_view("view1")
+        conf.create_view("view2")
+        conf.create_view("view3")
         try:
             conf.remove_view('invalid')
             self.fail('Removing invalid view succeeds!')
         except exceptions.NotFound:
             pass
         
-    def test_add_views_and_remove_all(self):
+    def test_create_views_and_remove_all(self):
         conf = api.Configuration("data/simple.confml")
-        conf.add_view("view1")
-        conf.add_view("view2")
-        conf.add_view("view3")
+        conf.create_view("view1")
+        conf.create_view("view2")
+        conf.create_view("view3")
         for view in conf.list_views():
             conf.remove_view(view)
         self.assertEquals(conf.list_views(),[])
 
-    def test_add_view_with_data(self):
+    def test_create_view_with_data(self):
         conf = api.Configuration("data/simple.confml")
-        conf.add_view("view1")
+        conf.create_view("view1")
         view = conf.get_view("view1")
-        view._add(api.Group("group1"))
-        view._add(api.Group("group2"))
-        view._add(api._FeatureProxy("feature1"))
-        view.group1._add(api.Group("group21"))
-        view.group1.group21._add(api._FeatureProxy("feature211"))
-        view.group1.group21._add(api._FeatureProxy("feature212"))
-        view.feature1._add(api._FeatureProxy("feature11"))
+        view.add_group(api.Group("group1"))
+        view.add_group(api.Group("group2"))
+        view.create_featurelink("feature1")
+        view.group1.add_group(api.Group("group21"))
+        view.group1.group21.create_featurelink("feature211")
+        view.group1.group21.create_featurelink("feature212")
         
         self.assertEquals(sorted(view._list_traverse()),
                           sorted(['group1', 
-                                          'group2', 
-                                          'feature1', 
-                                          'group1.group21', 
-                                          'group1.group21.feature211', 
-                                          'group1.group21.feature212', 
-                                          'feature1.feature11']))
+                                  'group1.group21', 
+                                  'group1.group21.link_feature211', 
+                                  'group1.group21.link_feature212', 
+                                  'group2', 
+                                  'link_feature1']))
 
     def test_get_default_view(self):
         conf = api.Configuration("data/simple.confml")
         dview = conf.get_default_view()
-        self.assertEquals(dview.ref,'_default_view')
+        self.assertEquals(dview.ref,'?default_view')
+
+    def test_create_configuration_and_features(self):
+        conf = api.Configuration("data/simple.confml")
+        fea = conf.create_feature("test")
+        self.assertEquals(conf.get_feature('test'), fea)
+        fea = conf.create_feature("test1", name="test name")
+        self.assertEquals(conf.get_feature('test1').name, 'test name')
+        fea.create_feature("subfea", name="subfea name")
+        self.assertEquals(conf.list_all_features(), ['test','test1','test1.subfea'])
 
     def test_get_default_view_and_data_to_it(self):
         conf = api.Configuration("data/simple.confml")
@@ -329,14 +370,34 @@
 #        conf.add_feature(api.Feature("feature1"))
 #        self.assertEquals(conf.list_all_features(),['com.nokia.feature1'])
 #        self.assertEquals(conf.feature1, conf.get_default_view().com.nokia.feature1._obj)
+    def test_get_path_for_parent(self):
+        conf = api.Configuration("test.confml")
+        conf.create_configuration("foo/root.confml")
+        conf.get_configuration("foo/root.confml").create_configuration("confml/jee.confml")
+        self.assertEquals(conf.get_path_for_parent(None), "test.confml")
+        self.assertEquals(conf.get_configuration("foo/root.confml").get_path_for_parent(None), "foo/root.confml")
+        foo = conf.get_configuration("foo/root.confml")
+        jee = foo.get_configuration("confml/jee.confml")
+        self.assertEquals(foo.get_path_for_parent(conf), "foo/root.confml")
+        self.assertEquals(jee.get_path_for_parent(conf), "foo/confml/jee.confml")
+        self.assertEquals(jee.get_path_for_parent(foo._obj), "confml/jee.confml")
+
 
     def test_add_subconfiguration(self):
         conf = api.Configuration("test",namespace="com.nokia")
         conf.create_configuration("foo/root.confml")
         conf.create_configuration("platforms/s60.confml")
+        dconf = api.Configuration('confml/data.confml')
+        sconf = conf.get_configuration('foo/root.confml')
+        sconf.add_configuration(dconf)
         self.assertEquals(conf.list_configurations(),['foo/root.confml',
                                                       'platforms/s60.confml',])
-
+        self.assertEquals(conf.list_all_configurations(),['foo/root.confml',
+                                                          'foo/confml/data.confml',
+                                                          'platforms/s60.confml'])
+        self.assertEquals(conf.get_configuration('foo/root.confml').list_all_configurations(),['confml/data.confml'])
+        
+        
     def test_remove_configuration(self):
         conf = api.Configuration("test.confml",namespace="com.nokia")
         conf.create_configuration("foo/root.confml")
@@ -482,7 +543,7 @@
         conf.add_feature(api.Feature('feature11'),'feature1')
         conf.add_feature(api.Feature('feature12'),'feature1')
         
-        conf.add_view("rootfeas")
+        conf.create_view("rootfeas")
         view = conf.get_view('rootfeas')
         for fearef in conf.list_features():
             fea = conf.get_feature(fearef)
@@ -504,16 +565,22 @@
         conf.add_feature(api.Feature('feature4'))
         conf.add_feature(api.Feature('feature11'),'feature1')
         conf.add_feature(api.Feature('feature12'),'feature1')
-        conf.add_view('fea1')
+        conf.create_view('fea1')
         view1 = conf.get_view('fea1')
-        view1.add_group('thegruppe1')
+        view1.create_group('thegruppe1')
         view1.get_group('thegruppe1').add(api.FeatureLink('feature1.feature11'))
         view1.add(api.FeatureLink('feature1.*'))
         view1.populate()
-        self.assertEquals(view1.list_all_features(),['thegruppe1.feature11','feature11','feature12'])
-        fpr = view1.get_feature('thegruppe1.feature11')
+        self.assertEquals(view1.list_all_features(),
+                          ['thegruppe1.proxy_feature1_feature11',
+                           'proxy_feature1_feature11',
+                           'proxy_feature1_feature12'])
+        fpr = view1.get_feature('thegruppe1.proxy_feature1_feature11')
         self.assertEquals(fpr._obj.fqr,conf.get_default_view().get_feature('feature1.feature11').fqr) 
-        self.assertEquals(view1.list_all_features(), ['thegruppe1.feature11','feature11','feature12'])
+        self.assertEquals(view1.list_all_features(),
+                          ['thegruppe1.proxy_feature1_feature11',
+                           'proxy_feature1_feature11',
+                           'proxy_feature1_feature12'])
 
     def test_add_features_and_create_all_view_with_links(self):
         conf = api.Configuration("foo/foo.confml")
@@ -523,12 +590,18 @@
         conf.add_feature(api.Feature('feature4'))
         conf.add_feature(api.Feature('feature11'),'feature1')
         conf.add_feature(api.Feature('feature12'),'feature1')
-        conf.add_view("all")
+        conf.create_view("all")
         view1 = conf.get_view('all')
         view1.add(api.FeatureLink('**'))
         view1.populate()
-        self.assertEquals(view1.list_all_features(),['feature1', 'feature11', 'feature12', 'feature2', 'feature3', 'feature4'])
-        fpr = view1.get_feature('feature11')
+        self.assertEquals(view1.list_all_features(),
+                          ['proxy_feature1',
+                           'proxy_feature1_feature11',
+                           'proxy_feature1_feature12',
+                           'proxy_feature2',
+                           'proxy_feature3',
+                           'proxy_feature4'])
+        fpr = view1.get_feature('proxy_feature1_feature11')
         self.assertEquals(fpr._obj.fqr,conf.get_default_view().get_feature('feature1.feature11').fqr) 
 
     def test_add_a_configuration_and_remove_it(self):
@@ -586,6 +659,76 @@
         self.assertEquals(conf.data.feature1.feature12.get_value(),"test")
         conf.remove_data('feature1.feature12')
         self.assertEquals(conf.list_datas(), ['feature1'])
+    
+    def test_add_data_to_configuration_from_list(self):
+        def check(data_objs, policy, expected):
+            conf = api.Configuration("foo/foo.confml")
+            conf.add_data(api.Data(ref='base1', value="foo"))
+            conf.add_data(api.Data(ref='foo', value="foobar"))
+            conf.add_data(api.Data(ref='base2', value="bar"))
+            
+            if policy is None:
+                conf.add_data(data_objs)
+            else:
+                conf.add_data(data_objs, policy=policy)
+            
+            actual = []
+            for d in conf._traverse(type=api.Data):
+                actual.append((d.fqr, d.value))
+            self.assertEquals(actual, expected)
+        
+        # Adding an empty list should do nothing
+        check(data_objs = [],
+              policy    = None,
+              expected  = [('base1', 'foo'),
+                           ('foo', 'foobar'),
+                           ('base2', 'bar')])
+        
+        # Default policy (replace)
+        check(data_objs = [api.Data(ref="foo", value="1"),
+                           api.Data(ref="foo", value="2"),
+                           api.Data(ref="foo", value="3"),],
+              policy    = None,
+              expected  = [('base1', 'foo'),
+                           ('foo', '1'),
+                           ('foo', '2'),
+                           ('foo', '3'),
+                           ('base2', 'bar')])
+        
+        # Replace explicitly
+        check(data_objs = [api.Data(ref="foo", value="1"),
+                           api.Data(ref="foo", value="2"),
+                           api.Data(ref="foo", value="3"),],
+              policy    = api.container.REPLACE,
+              expected  = [('base1', 'foo'),
+                           ('foo', '1'),
+                           ('foo', '2'),
+                           ('foo', '3'),
+                           ('base2', 'bar')])
+        
+        # Append
+        check(data_objs = [api.Data(ref="foo", value="1"),
+                           api.Data(ref="foo", value="2"),
+                           api.Data(ref="foo", value="3"),],
+              policy    = api.container.APPEND,
+              expected  = [('base1', 'foo'),
+                           ('foo', 'foobar'),
+                           ('foo', '1'),
+                           ('foo', '2'),
+                           ('foo', '3'),
+                           ('base2', 'bar')])
+        
+        # Prepend
+        check(data_objs = [api.Data(ref="foo", value="1"),
+                           api.Data(ref="foo", value="2"),
+                           api.Data(ref="foo", value="3"),],
+              policy    = api.container.PREPEND,
+              expected  = [('base1', 'foo'),
+                           ('foo', '1'),
+                           ('foo', '2'),
+                           ('foo', '3'),
+                           ('foo', 'foobar'),
+                           ('base2', 'bar')])
 
     def test_set_data_to_configuration(self):
         conf = api.Configuration("foo/foo.confml")
@@ -672,13 +815,12 @@
         fea = conf.get_feature('feature1')
         fea.set_template(['test1','test2','test3'])
         self.assertEquals(fea.get_template(),['test1', 'test2', 'test3'])
-        fea.set_template(['test1','test3'])
-        self.assertEquals(fea.get_template(),['test1','test3','test3'])
-        try:
-            fea.set_template(['test1',None,'test3',None])
-            self.fail("Able to add more data then allowed")
-        except IndexError:
-            pass
+        fea.set_template(['Test1','Test2','Test3'])
+        self.assertEquals(fea.get_template(),['Test1','Test2','Test3'])
+        
+        self.assertRaises(ValueError, fea.set_template, [])
+        self.assertRaises(ValueError, fea.set_template, ['foo', 'bar'])
+        self.assertRaises(ValueError, fea.set_template, ['foo', 'bar', 'foo', 'bar'])
 
     def test_create_features_with_rfs_data(self):
         conf = api.Configuration("foo/foo.confml")
@@ -707,8 +849,8 @@
     def test_dumps_add_features(self):
         root = api.Configuration("root",namespace="com.nokia")
         conf = root.create_configuration("test.confml")
-        conf.add_feature(api.Feature("feature1"))
-        conf.add_feature(api.Feature("feature2"))
+        conf.add_feature(api.Feature("feature1", name="feature1"))
+        conf.add_feature(api.Feature("feature2", name="feature2"))
         dumped = persistentdictionary.DictWriter().dumps(conf)
         dict =dumped['Configuration']['dict']
         self.assertEquals(dict['path'],'test.confml')
@@ -720,7 +862,6 @@
 
     def test_dumps_root_configuration(self):
         root = api.Configuration("root",namespace="com.nokia")
-        conf = root.create_configuration("test.confml")
         conf = root.create_configuration("foo/root.confml")
         conf.add_feature(api.Feature("feature1"))
         conf.add_feature(api.Feature("feature2"))
@@ -734,10 +875,10 @@
     def test_dumps_feature_hierarchy(self):
         root = api.Configuration("root",namespace="com.nokia")
         conf = root.create_configuration("test.confml")
-        conf.add_feature(api.Feature("feature1"))
-        conf.add_feature(api.Feature("feature2"))
-        conf.feature1.add_feature(api.Feature("feature11"))
-        conf.feature1.add_feature(api.Feature("feature12"))
+        conf.add_feature(api.Feature("feature1", name="feature1"))
+        conf.add_feature(api.Feature("feature2", name="feature2"))
+        conf.feature1.add_feature(api.Feature("feature11", name="feature11"))
+        conf.feature1.add_feature(api.Feature("feature12", name="feature12"))
         dumped = persistentdictionary.DictWriter().dumps(conf)
         dict =dumped['Configuration']['dict']
         self.assertEquals(dict['path'],'test.confml')
@@ -792,9 +933,9 @@
 
     def test_dumps_and_loads_configuration_hierarchy(self):
         root = api.Configuration("root.confml")
-        root.add_configuration(api.Configuration("layer1.confml"))
-        layer = api.Configuration("foo/layer2.confml")
-        conf = api.Configuration("foo/test.confml")
+        root.add_configuration(api.Configuration("layer1"))
+        layer = api.Configuration("layer2")
+        conf = api.Configuration("test")
         conf.add_feature(api.Feature("feature1"))
         conf.add_feature(api.Feature("feature2"))
         conf.feature1.add_feature(api.Feature("feature11"))
@@ -809,8 +950,8 @@
 
     def test_dumps_and_loads_configuration_hierarchy_with_data(self):
         root = api.Configuration("root.confml")
-        layer = api.Configuration("foo/layer1.confml")
-        conf = api.Configuration("foo/test.confml")
+        layer = api.Configuration("layer1")
+        conf = api.Configuration("test")
         conf.add_feature(api.Feature("feature1"))
         conf.add_feature(api.Feature("feature2"))
         conf.feature1.add_feature(api.Feature("feature11"))
@@ -819,7 +960,7 @@
         conf.feature2.set_value(2)
         layer.add_configuration(conf)
         root.add_configuration(layer)
-        root.add_configuration(api.Configuration("layer2.confml"))
+        root.add_configuration(api.Configuration("layer2"))
         root.get_default_view().feature1.feature11.set_value("testing11")
         root.get_default_view().feature1.set_value("test1")
         dumped = persistentdictionary.DictWriter().dumps(root)
@@ -831,21 +972,54 @@
         self.assertEquals(root2.get_default_view().feature1.feature11.get_value(), "testing11")
 
         self.assertEquals([data.find_parent(type=api.Configuration).get_path() for data in root2.get_all_datas()],
-                          ['foo/test.confml', 'foo/test.confml', 'layer2.confml','layer2.confml'])
+                          ['test', 'test', 'layer2','layer2'])
 
     def test_access_via_configuration_proxy(self):
         conf = api.Configuration("root.confml")
         conf.add_feature(api.Feature("feature1"))
         proxy = api.ConfigurationProxy("root.confml")
-        proxy.set('_obj',conf)
+        proxy._set_obj(conf)
         self.assertEquals(proxy.get_ref(), 'root_confml')
         self.assertEquals(proxy.get_path(), 'root.confml')
         self.assertEquals(conf.feature1.get_ref(), 'feature1')
         self.assertEquals(proxy.feature1.get_ref(), 'feature1')
         
 
+class TestConfigurationInclude(unittest.TestCase):    
+    class StoreTestInt(object):
+        def load(self, ref):
+            return api.Configuration(ref)
+
+        def dump(self, obj, ref):
+            pass
+    
+    def get_store_interface(self):
+        return TestConfigurationInclude.StoreTestInt()
+    
+    def _test_include(self):
+        inc = api.Include("foo/bar.txt", self.get_store_interface())
+        objs =inc._objects()
+        self.assertEquals(len(objs),1)
+        self.assertEquals(objs[0].path,"foo/bar.txt")  
+        
+    def test_include_clone(self):
+        inc = api.Include("foo/bar.txt", store_interface=self.get_store_interface())
+        ci = inc._clone()
+        self.assertEquals(inc.ref, ci.ref)
+        self.assertEquals(inc.get_path(), ci.get_path())
+        
+#    def test_configuration_with_include(self):
+#        conf = api.Configuration("foo.confml")
+#        # Set the get_store_interface function to test stub method 
+#        conf.get_store_interface = self.get_store_interface
+#        conf.include_configuration("foo/test.confml")
+#        subconfs = conf.list_configurations()
+#        self.assertEquals(len(subconfs),1)
+#        self.assertTrue(isinstance(subconfs[0], api.Configuration))  
+#        self.assertEquals(subconfs[0].path,"foo/test.confml")  
+        
 if __name__ == '__main__':
-      unittest.main()
+    unittest.main()
       
 """
 {'Configuration': {'dict': {'path': 'root.confml', 'ref': 'root', 'namespace': '', 'desc': ''}, 'children': [{'Configuration': {'dict': {'path': 'foo/layer1.confml', 'ref': 'foo_layer1', 'namespace': '', 'desc': ''}, 'children': [{'Configuration': {'dict': {'path': 'foo/test.confml', 'ref': 'foo_test', 'namespace': '', 'desc': ''}, 'children': [{'Feature': {'dict': {'ref': 'feature1'}, 'children': [{'Feature': {'dict': {'ref': 'feature11'}}}, {'Feature': {'dict': {'ref': 'feature12'}}}]}}, {'Feature': {'dict': {'ref': 'feature2'}}}, {'DataContainer': {'dict': {'ref': 'data'}, 'children': [{'Data': {'dict': {'ref': 'feature1', 'value': 1}}}, {'Data': {'dict': {'ref': 'feature2', 'value': 2}}}]}}]}}]}}, {'Configuration': {'dict': {'path': 'layer2.confml', 'ref': 'layer2', 'namespace': '', 'desc': ''}}}]}}
--- a/configurationengine/source/cone/public/tests/unittest_container.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/public/tests/unittest_container.py	Tue Aug 10 14:29:28 2010 +0300
@@ -23,7 +23,6 @@
 import unittest
 import string
 import sys,os,re
-import __init__
 
 from cone.public import utils, container, exceptions
 
@@ -138,7 +137,7 @@
         self.assertEquals(cont.startswith("test"),True)
         
 
-def graph(obj):
+def graph(obj, filters=None):
     if obj._parent:
         return ["%s -> %s" % (obj._parent._name, obj._name)]
     return []
@@ -151,7 +150,7 @@
     def test_add_incorrect_type(self):
         cont = container.ObjectContainer()
         try: 
-            cont._add(container.ObjectProxy())
+            cont._add(container.DataContainer())
             self.fail("Adding incorrect class type to container succeeds?")
         except exceptions.IncorrectClassError,e:
             pass
@@ -164,14 +163,60 @@
         cont._add(container.ObjectContainer("foo"))
         self.assertEquals(cont._list(),['test','foo'])
         self.assertEquals(cont.test,obj)
+    
+    def test_add_children_from_list_with_different_policies(self):
+        def check(policy, expected):
+            cont = container.ObjectContainer("root")
+            cont._add(container.ObjectContainer("test1"))
+            cont._add(container.ObjectContainer("foo"))
+            cont._add(container.ObjectContainer("test2"))
+            
+            objs = [container.ObjectContainer("foo"),
+                    container.ObjectContainer("foo"),
+                    container.ObjectContainer("foo")]
+            for i, obj in enumerate(objs): obj.test_attr = i
+            
+            cont._add(objs, policy)
+            
+            actual = [(o._name, getattr(o, 'test_attr', None)) for o in cont._objects()]
+            self.assertEquals(actual, expected)
+        
+        check(container.REPLACE,
+              [('test1', None),
+               ('foo', 0),
+               ('foo', 1),
+               ('foo', 2),
+               ('test2', None),])
+        
+        check(container.APPEND,
+              [('test1', None),
+               ('foo', None),
+               ('foo', 0),
+               ('foo', 1),
+               ('foo', 2),
+               ('test2', None),])
+        
+        check(container.PREPEND,
+              [('test1', None),
+               ('foo', 0),
+               ('foo', 1),
+               ('foo', 2),
+               ('foo', None),
+               ('test2', None),])
+        
 
     def test_add_internal_child(self):
         cont = container.ObjectContainer("root")
         obj = container.ObjectContainer("?test")
         cont._add(obj)
         cont._add(container.ObjectContainer("foo"))
-        self.assertEquals(cont._list(),['foo'])
+        cont._add(container.ObjectContainer("bar"))
+        self.assertEquals(cont._list(),['foo', 'bar'])
         self.assertEquals(cont._get('?test'),obj)
+        self.assertEquals(cont._list(),['foo', 'bar'])
+        cont._remove('?test')
+        self.assertRaises(exceptions.NotFound,cont._get,'?test')
+        self.assertEquals(cont._list(),['foo','bar'])
         
 
     def test_add_child_to_path(self):
@@ -241,6 +286,17 @@
         except exceptions.AlreadyExists, e:
             pass
 
+    def test__traverse_depth(self):
+        cont = container.ObjectContainer("cont")
+        obj1 = container.ObjectContainer("test1")
+        obj2 = container.ObjectContainer("test2")
+        cont._add_to_path("com.nokia", obj1)
+        cont._add_to_path("com.nokia", obj2)
+        self.assertEquals(len(cont._traverse()), 4)
+        self.assertEquals(len(cont._traverse(depth=1)), 1)
+        self.assertEquals(len(cont._traverse(depth=2)), 2)
+        self.assertEquals(len(cont._traverse(depth=3)), 4)
+        
     def test_add_child_to_existing_path_append(self):
         cont = container.ObjectContainer("test")
         obj = container.ObjectContainer("test")
@@ -512,6 +568,9 @@
         ret = cont._traverse(name="^t.*$")
         self.assertEquals(len(ret),1)
         self.assertEquals(ret[0]._path(),"default.com.nokia.test")
+#        ret = cont._traverse(type=TestC)
+#        self.assertEquals(len(ret),1)
+
 
     def test_add_children_and_traverse_filter_name_many(self):
         cont = container.ObjectProxyContainer(None,"default")
@@ -569,6 +628,58 @@
         self.assertEquals(proxy2.list_resources(''),['test1.txt', 'test2.txt', 'test3.txt'])
         os.unlink("unload.pk")
 
+class TestLoadContainer(unittest.TestCase):
+    def test_create_load_container(self):
+        cont = container.LoadContainer(importpk, container.LoadInterface())
+        cont._load()
+        self.assertEquals(len(cont._objects()), 1)
+
+    def test_create_load_link__unload(self):
+        cont = container.LoadContainer(importpk, container.LoadInterface())
+        cont._load()
+        self.assertEquals(len(cont._objects()), 1)
+        cont._unload()
+        self.assertEquals(cont._container, None)
+
+    def test_create_load_link__get_objects(self):
+        cont = container.LoadContainer(importpk, container.LoadInterface())
+        self.assertEquals(len(cont._objects()), 1)
+
+    def test_create_load_link__traverse(self):
+        cont = container.LoadContainer(importpk, container.LoadInterface())
+        self.assertEquals(len(cont._traverse()), 4)
+        print cont._traverse()
+
+    def test_create_load_link__list(self):
+        cont = container.LoadContainer(importpk, container.LoadInterface())
+        self.assertEquals(os.path.basename(cont._list()[0]), 'Import_pk')
+
+class TestLoadContainerWrite(unittest.TestCase):
+    def test_create_load_container__add_data(self):
+        cont = container.LoadContainer(importpk)
+        cont._add(container.ObjectContainer("Test"))
+        self.assertEquals(len(cont._objects()), 1)
+
+    def test_create_load_container__add_data_unload(self):
+        cont = container.LoadContainer(importpk)
+        cont._add(container.ObjectContainer("Test"))
+        self.assertEquals(len(cont._objects()), 1)
+        cont._unload()
+
+class TestLoadLink(unittest.TestCase):
+    def test_create_load_link(self):
+        link = container.LoadLink(importpk, container.LoadInterface())
+        objs = link._load()
+        self.assertEquals(len(objs), 1)
+
+    def test_create_load_link_and_populate(self):
+        cont = container.ObjectContainer("Test")
+        link = container.LoadLink(importpk, container.LoadInterface())
+        cont._add(link)
+        link.populate()
+        self.assertEquals(len(cont._objects()), 2)
+
 if __name__ == '__main__':
     unittest.main()
       
+
--- a/configurationengine/source/cone/public/tests/unittest_data.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/public/tests/unittest_data.py	Tue Aug 10 14:29:28 2010 +0300
@@ -20,7 +20,6 @@
 import unittest
 import string
 import sys,os
-import __init__
 
 from cone.public import api,exceptions,utils, container
 
@@ -36,13 +35,6 @@
         data = api.Data(fqr="foo.bar", value=123, attr='data')
         self.assertEquals(data.attr,'data')
 
-    def test_create_data_with_map(self):
-        data = api.Data(ref="StringToString", map="StringToStringSequenceFeature/SequenceSetting[@key='Key 1']")
-        self.assertEqual(data.get_map(),"StringToStringSequenceFeature/SequenceSetting[@key='Key 1']")
-        self.assertEqual(data.get_map_ref(),"StringToStringSequenceFeature/SequenceSetting")
-        self.assertEqual(data.get_map_key_value(),"Key 1")
-        self.assertTrue(data)
-
     def test_create_data_getters(self):
         data = api.Data(ref="foo", value=123)
         self.assertEquals(data.fqr, "foo")
--- a/configurationengine/source/cone/public/tests/unittest_feature.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/public/tests/unittest_feature.py	Tue Aug 10 14:29:28 2010 +0300
@@ -18,11 +18,8 @@
 Test the configuration
 """
 import unittest
-import string
-import sys,os
-import __init__
 
-from cone.public import api,exceptions,utils
+from cone.public import api, exceptions
 
 
 class TestFeature(unittest.TestCase):    
@@ -95,7 +92,47 @@
         self.assertEquals(feaproxy.bar.fqr,"foo.bar")
         self.assertEquals(feaproxy.bar.name,"bar man")
         
+    def test_create_feature_proxy_with_options(self):
+        fea= api.Feature("foo", name="foo bar")
+        fea.add_option(api.Option('opt1', '1'))
+        
+        opts = {}
+        opts['opt2'] = api.Option('opt2', '2')
+        
+        feaproxy = api._FeatureProxy("foo",fea, options=opts)
+        self.assertTrue(feaproxy.get_ref(),"foo")
+        self.assertEquals(feaproxy.namespace,"")
+        self.assertEquals(feaproxy.fqr,"foo")
+        self.assertEquals(feaproxy.name,"foo bar")
+        feaproxy.add_feature(api.Feature("bar", name="bar man"))
+        self.assertTrue(feaproxy.bar.get_ref(),"bar")
+        self.assertEquals(feaproxy.bar.namespace,"foo")
+        self.assertEquals(feaproxy.bar.fqr,"foo.bar")
+        self.assertEquals(feaproxy.bar.name,"bar man")
+        opts2 = {}
+        opts2['opt2'] = api.Option('opt2', '2')
+        opts2['opt1'] = api.Option('opt1', '1')
+        self.assertEquals(feaproxy.list_options(), ['value_1', 'value_2'])
+        self.assertEquals(feaproxy.get_option('value_2').get_value(), '2')
+        self.assertEquals(feaproxy.get_option('value_1').get_value(), '1')
+        
+    def test_create_feature_proxy_has_attribute(self):
+        fea= api.Feature("foo", name="foo bar")
+        feaproxy = api._FeatureProxy("foo",fea)
+        self.assertEquals(feaproxy.name, "foo bar")
+        self.assertEquals(feaproxy.has_attribute('name'), False)
+        feaproxy.name = "test"
+        self.assertEquals(feaproxy.has_attribute('name'), True)
+        self.assertEquals(feaproxy.name, "test")
 
+    def test_feature_proxy_get_proxied_obj(self):
+        fea= api.Feature("foo", name="foo bar")
+        feaproxy = api._FeatureProxy("foo",fea)
+        proxied = feaproxy.get_proxied_obj()
+        self.assertFalse(proxied == None)
+        self.assertEquals(fea, proxied)
+        self.assertEquals(feaproxy.get_proxied_obj(), feaproxy._obj)
+        
     def test_create_feature_data(self):
         dataobj = api.Data(ref="foo", value=132)
         self.assertTrue(dataobj.fqr,"foo")
@@ -181,15 +218,22 @@
     
     def test_create_sequence_feature(self):
         fea = api.FeatureSequence('test')
-        fea.add_feature(api.Feature('child1',type='int'))
-        fea.add_feature(api.Feature('child2'))
-        fea.add_feature(api.Feature('child3'))
+        fea.create_feature('child1',type='int')
+        fea.create_feature('child2', name="test")
+        fea.create_feature('child3')
         self.assertEquals(fea.get_type(), 'sequence')
         self.assertEquals(fea.list_features(), ['child1','child2','child3'])
+        self.assertEquals(fea.get_feature('child1').type, 'int')
+        self.assertEquals(fea.get_feature('child2').type, None)
+        self.assertEquals(fea.get_feature('child2').name, 'test')
 
     def test_feature_get_dict(self):
         fea= api.Feature("foo", type='int')
-        self.assertEquals(fea._dict(), {'ref': 'foo','type': 'int', 'name': 'foo'})
+        self.assertEquals(fea._dict(), {'ref': 'foo',
+                                        'type': 'int',
+                                        'name': None,
+                                        'relevant': None,
+                                        'constraint': None })
 
     def test_clone_single_feature(self):
         fea= api.Feature("foo", type='int')
@@ -199,7 +243,7 @@
     def test_clone_feature_with_subfeatures(self):
         fea= api.Feature("foo")
         fea.add_feature(api.Feature("child1",type='string'))
-        fea.add_feature(api.Feature("child2",type='int'))
+        fea.create_feature("child2",type='int')
         fea.child1.add_feature(api.Feature("child12",type='int'))
         fea2 = fea._clone()
         self.comparefeatures(fea,fea2)
@@ -257,6 +301,9 @@
         fea.add_feature(api.Feature('child2'))
         fea.add_feature(api.Feature('child3'))
         self.assertEquals(fea.list_features(),['child1','child2','child3'])
+        self.assertEquals(fea.get_column_features()[0].ref,'child1')
+        self.assertEquals(fea.get_column_features()[1].ref,'child2')
+        self.assertEquals(fea.get_column_features()[2].ref,'child3')
 
     def test_create_configuration_with_sequence_and_get_default_view(self):
         fea= api.FeatureSequence("foo")
@@ -330,6 +377,54 @@
                                                ['7','8','9']
                                                ])
 
+    def test_create_configuration_with_sequence_and_get_column_value(self):
+        fea= api.FeatureSequence("foo")
+        c1 = fea.create_feature('child1')
+        c11 = c1.create_feature('child11')
+        c2 = fea.create_feature('child2')
+        c3 = fea.create_feature('child3')
+        config = api.Configuration('foo.confml')
+        config.add_feature(fea)
+        dview = config.get_default_view()
+        foofea = dview.get_feature('foo')
+        # Test adding a data row with array
+        foofea.value = [[['1'],'2','3'],[['4'],'5','6'],[['7'],'8','9']]
+        self.assertEquals(api.get_column_value(foofea, 'child1'), [['1'],['4'],['7']])
+        self.assertEquals(foofea.child1.value, [['1'],['4'],['7']])
+        self.assertEquals(foofea.child1.child11.value, ['1','4','7'])
+        self.assertEquals(foofea.child2.value, ['2','5','8'])
+        self.assertEquals(foofea.value, [[['1'],'2','3'],
+                                         [['4'],'5','6'],
+                                         [['7'],'8','9']])
+
+    def test_create_configuration_with_sequence_and_set_value_via_column(self):
+        fea= api.FeatureSequence("foo")
+        fea.add_feature(api.Feature('child1'))
+        fea.add_feature(api.Feature('child2'))
+        fea.add_feature(api.Feature('child3'))
+        config = api.Configuration('foo.confml')
+        config.add_feature(fea)
+        dview = config.get_default_view()
+        foofea = dview.get_feature('foo')
+        # Test adding a data row with array
+        foofea.value = [['1','2','3'],['4','5','6'],['7','8','9']]
+        self.assertEquals(foofea.get_value(), [['1','2','3'],
+                                               ['4','5','6'],
+                                               ['7','8','9']
+                                               ])
+
+        api.set_column_value(foofea, 'child1', ['0','0','0'])
+        self.assertEquals(foofea.get_value(), [['0','2','3'],
+                                               ['0','5','6'],
+                                               ['0','8','9']
+                                               ])
+        self.assertRaises(exceptions.ConeException, api.set_column_value, foofea, 'child2', 'over')
+        self.assertRaises(exceptions.ConeException, api.set_column_value, foofea, 'child2', ['0','0','0', 'over'])
+        foofea.child3.value = ['0','0','0'] 
+        self.assertEquals(foofea.get_value(), [['0','2','0'],
+                                               ['0','5','0'],
+                                               ['0','8','0']
+                                               ])
 
     def test_create_configuration_with_sequence_and_add_sequence_value_directly(self):
         fea= api.FeatureSequence("foo")
@@ -350,6 +445,87 @@
                                                ['4','5','6'],
                                                ['7','8','9']
                                                ])
+        
+        # Check the data element values
+        data_elem_values = [(d.fqr, d.value) for d in config._traverse(type=api.Data)]
+        self.assertEquals(data_elem_values,
+            [('foo', None),
+             ('foo.child1', '1'),
+             ('foo.child2', '2'),
+             ('foo.child3', '3'),
+             ('foo', None),
+             ('foo.child1', '4'),
+             ('foo.child2', '5'),
+             ('foo.child3', '6'),
+             ('foo', None),
+             ('foo.child1', '7'),
+             ('foo.child2', '8'),
+             ('foo.child3', '9'),])
+    
+    def test_set_sequence_to_empty(self):
+        fea= api.FeatureSequence("foo")
+        fea.add_feature(api.Feature('child1'))
+        fea.add_feature(api.Feature('child2'))
+        fea.add_feature(api.Feature('child3'))
+        config = api.Configuration('foo.confml')
+        config.add_feature(fea)
+        dview = config.get_default_view()
+        foofea = dview.get_feature('foo')
+        # Test adding a data row with array
+        foofea.set_value([['1','2','3'],
+                          ['4','5','6'],
+                          ['7','8','9']])
+        self.assertEquals(len(foofea.get_data()), 3)
+        self.assertEquals(foofea.get_value(), [['1','2','3'],
+                                               ['4','5','6'],
+                                               ['7','8','9']])
+        self.assertEquals(foofea.child1.get_value(), ['1','4','7'])
+        self.assertEquals(foofea.child2.get_value(), ['2','5','8'])
+        self.assertEquals(foofea.child3.get_value(), ['3','6','9'])
+        
+        # Set empty and check that the single empty data item is created
+        foofea.set_value([])
+        data_elem_values = [(d.fqr, d.value) for d in config._traverse(type=api.Data)]
+        self.assertEquals(data_elem_values, [('foo', None)])
+        
+        # Check that get_value() still works correctly
+        self.assertEquals(foofea.get_value(), [])
+        self.assertEquals(foofea.child1.get_value(), [])
+        self.assertEquals(foofea.child2.get_value(), [])
+        self.assertEquals(foofea.child3.get_value(), [])
+        self.assertEquals(foofea.get_original_value(), [])
+        self.assertEquals(foofea.child1.get_original_value(), [])
+        self.assertEquals(foofea.child2.get_original_value(), [])
+        self.assertEquals(foofea.child3.get_original_value(), [])
+        
+        # Check that column-level set_value() reports errors correctly
+        self.assertRaises(exceptions.ConeException, foofea.child1.set_value, ['10', '11'])
+        self.assertRaises(exceptions.ConeException, foofea.child1.set_value, ['10'])
+        foofea.child1.set_value([])
+        
+        # Check that calling add_sequence() after set_value([]) works correctly
+        foofea.add_sequence(['1', '2', '3'])
+        self.assertEquals(foofea.get_value(), [['1', '2', '3']])
+        self.assertEquals(foofea.child1.get_value(), ['1'])
+        self.assertEquals(foofea.get_original_value(), [['1', '2', '3']])
+        data_elem_values = [(d.fqr, d.value) for d in config._traverse(type=api.Data)]
+        self.assertEquals(data_elem_values,
+            [('foo', None),
+             ('foo.child1', '1'),
+             ('foo.child2', '2'),
+             ('foo.child3', '3'),])
+        
+        # Check that explicitly setting all Nones works
+        foofea.set_value([[None, None, None]])
+        self.assertEquals(foofea.get_value(), [[None, None, None]])
+        self.assertEquals(foofea.child1.get_value(), [None])
+        self.assertEquals(foofea.get_original_value(), [[None, None, None]])
+        data_elem_values = [(d.fqr, d.value) for d in config._traverse(type=api.Data)]
+        self.assertEquals(data_elem_values,
+            [('foo', None),
+             ('foo.child1', None),
+             ('foo.child2', None),
+             ('foo.child3', None),])
 
     def test_create_configuration_and_access_feature_value_with_property(self):
         config = api.Configuration('foo.confml')
@@ -424,7 +600,6 @@
         self.assertEquals(foofea.value, [])
 
     def test_create_feature_seq_get_sequence_parent(self):
-        config = api.Configuration('foo.confml')
         fea= api.FeatureSequence("foo")
         fea.add_feature(api.Feature('child1'))
         fea.add_feature(api.Feature('child11'),'child1')
@@ -452,8 +627,8 @@
         dview = config.get_default_view()
         seqfea = dview.get_feature("SequenceSetting")
 
-        self.assertEquals(seqfea.get_map_key().name,"KeySubSetting")
-        self.assertEquals(seqfea.get_map_value().name,"ValueSubSetting")
+        self.assertEquals(seqfea.mapKey, "KeySubSetting")
+        self.assertEquals(seqfea.mapValue, "ValueSubSetting")
         #add item 1
         data = api.Data(ref='SequenceSetting')
         data._add(api.Data(ref='KeySubSetting',value='Default'))
@@ -468,8 +643,154 @@
         
         self.assertEquals(len(seqfea.get_data()), 2)
         
-        self.assertEquals(seqfea.get_map_key_value('Default'),'Default value')
-        self.assertEquals(seqfea.get_map_key_value('Key 1'),'Value 1')
+    def test_get_set_template_single_data_level(self):
+        # Create a sequence feature with only a single level of sub-features
+        # (i.e. no sub-sub-features)
+        config = api.Configuration('foo.confml')
+        seq = api.FeatureSequence("seq")
+        seq.add_feature(api.Feature('child1'))
+        seq.add_feature(api.Feature('child2'))
+        seq.add_feature(api.Feature('child3'))
+        config.add_feature(seq)
+        
+        # Add a template for the sequence with the data elements under it
+        # in a different order than what the features were defined in
+        template_data = api.Data(ref='seq', template=True)
+        template_data.add(api.Data(ref='child2', value='foo2'))
+        template_data.add(api.Data(ref='child3', value='foo3'))
+        template_data.add(api.Data(ref='child1', value='foo1'))
+        config.add_data(template_data)
+        
+        # Get the template data (should be in order)
+        dview = config.get_default_view()
+        seq = dview.get_feature('seq')
+        self.assertEquals(seq.get_template(), ['foo1', 'foo2', 'foo3'])
+        
+        seq.set_template(['x1', 'x2', 'x3'])
+        self.assertEquals(seq.get_template(), ['x1', 'x2', 'x3'])
+        
+        seq.set_template(None)
+        self.assertEquals(seq.get_template(), None)
+        
+        # Test attempting to set invalid template data
+        self.assertRaises(TypeError, seq.set_template, 'foo')
+        self.assertRaises(ValueError, seq.set_template, [])
+        self.assertRaises(ValueError, seq.set_template, ['foo', 'bar'])
+        self.assertRaises(ValueError, seq.set_template, [['foo', 'x'], 'bar'])
+    
+    def test_get_set_template_two_data_levels(self):
+        # Create a sequence feature with two levels of sub-features
+        config = api.Configuration('foo.confml')
+        seq = api.FeatureSequence("seq")
+        seq.add_feature(api.Feature('a1'))
+        seq.add_feature(api.Feature('b1'), 'a1')
+        seq.add_feature(api.Feature('b2'), 'a1')
+        seq.add_feature(api.Feature('a2'))
+        seq.add_feature(api.Feature('a3'))
+        config.add_feature(seq)
+        
+        # Add a template for the sequence with the data elements under it
+        # in a different order than what the features were defined in
+        template_data = api.Data(ref='seq', template=True)
+        template_data.add(api.Data(ref='a3', value='t: a3'))
+        data_a1 = api.Data(ref='a1')
+        data_a1.add(api.Data(ref='b2', value='t: a1.b2'))
+        data_a1.add(api.Data(ref='b1', value='t: a1.b1'))
+        template_data.add(data_a1)
+        template_data.add(api.Data(ref='a2', value='t: a2'))
+        config.add_data(template_data)
+        
+        template_data = api.Data(ref='seq')
+        template_data.add(api.Data(ref='a3', value='t: a3'))
+        data_a1 = api.Data(ref='a1')
+        data_a1.add(api.Data(ref='b2', value='t: a1.b2'))
+        data_a1.add(api.Data(ref='b1', value='t: a1.b1'))
+        template_data.add(data_a1)
+        template_data.add(api.Data(ref='a2', value='t: a2'))
+        config.add_data(template_data, api.FeatureSequence.POLICY_APPEND)
+        
+        # Get the template data (should be in order)
+        dview = config.get_default_view()
+        seq = dview.get_feature('seq')
+        self.assertEquals(seq.value, [[['t: a1.b1', 't: a1.b2'], 't: a2', 't: a3']])
+        self.assertEquals(seq.get_template(), [['t: a1.b1', 't: a1.b2'], 't: a2', 't: a3'])
+        
+        # Set the template and get it again
+        seq.set_template([['t: a1.b1 (x)', 't: a1.b2 (x)'], 't: a2 (x)', 't: a3 (x)'])
+        self.assertEquals(seq.get_template(), [['t: a1.b1 (x)', 't: a1.b2 (x)'], 't: a2 (x)', 't: a3 (x)'])
+    
+    def test_sequence_add_data_and_set_template(self):
+        # Create a simple configuration with a sequence feature
+        config = api.Configuration('foo.confml')
+        fea = api.Feature('fea')
+        config.add_feature(fea)
+        seq = api.FeatureSequence("seq")
+        fea.add_feature(seq)
+        seq.add_feature(api.Feature('child1'))
+        seq.add_feature(api.Feature('child2'))
+        
+        sequence = config.get_default_view().get_feature('fea.seq')
+        
+        # Check that initially the sequence is empty
+        self.assertEquals(sequence.get_template(), None)
+        self.assertEquals(sequence.value, [])
+        
+        # Add some data and check again
+        sequence.add_sequence(['row1', 'foo'])
+        sequence.add_sequence(['row2', 'foo']) 
+        self.assertEquals(sequence.get_template(), None)
+        self.assertEquals(sequence.value, [['row1', 'foo'],
+                                           ['row2', 'foo']])
+
+        # Setting the template should not affect the data
+        sequence.set_template(['t1', 't2'])
+        self.assertEquals(sequence.get_template(), ['t1', 't2'])
+        self.assertEquals(sequence.value, [['row1', 'foo'],
+                                           ['row2', 'foo']])
+        
+        sequence.set_template(['T1', 'T2'])
+        sequence.add_sequence(['row3', 'foo'])
+        self.assertEquals(sequence.get_template(), ['T1', 'T2'])
+        self.assertEquals(sequence.value, [['row1', 'foo'],
+                                           ['row2', 'foo'],
+                                           ['row3', 'foo']])
+    
+    def test_set_value_method_for_sequence(self):
+        config = api.Configuration('foo.confml')
+        fea = api.Feature('Some')
+        config.add_feature(fea)
+        seq = api.FeatureSequence("Sequence")
+        fea.add_feature(seq)
+        seq.add_feature(api.Feature('Feature'))
+        
+        seq = config.get_default_view().get_feature('Some.Sequence')
+        value = [['foo'], ['bar']]
+        seq.set_value(value)
+        
+        self.assertEquals(seq.value, [['foo'], ['bar']])
+        self.assertEquals(seq.Feature.value, ['foo', 'bar'])
+    
+    def test_simple_name_id_mapping(self):
+        config = api.Configuration('foo.confml')
+        seq = api.FeatureSequence('seq', mapKey='sub1', mapValue='sub1')
+        seq.add_feature(api.Feature('sub1'))
+        seq.add_feature(api.Feature('sub2'))
+        config.add_feature(seq)
+        config.add_feature(api.Feature('target'))
+        
+        config.add_data(api.Data(fqr='seq.sub1', value='foo'))
+        config.add_data(api.Data(fqr='seq.sub2', value='bar'))
+        config.add_data(api.Data(fqr='target', map="seq[@key='foo']"))
+        
+        fea = config.get_default_view().get_feature('target')
+        self.assertEquals(fea.value, 'foo')
+        self.assertEquals(fea.get_value(), 'foo')
+        self.assertEquals(fea.get_original_value(), 'foo')
+        
+        seq.mapValue = 'sub2'
+        self.assertEquals(fea.value, 'bar')
+        self.assertEquals(fea.get_value(), 'bar')
+        self.assertEquals(fea.get_original_value(), 'bar')
+        
 if __name__ == '__main__':
-      unittest.main()
-      
+    unittest.main()
--- a/configurationengine/source/cone/public/tests/unittest_layer.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/public/tests/unittest_layer.py	Tue Aug 10 14:29:28 2010 +0300
@@ -18,58 +18,105 @@
 Test the configuration
 """
 import unittest
-import string
-import sys,os
-import __init__
+
+
+from cone.public import api
+from cone.storage import stringstorage
+
+class TestFolder(unittest.TestCase):    
+    storage_class = stringstorage.StringStorage
+    def setUp(self):
+        self.store = self.storage_class.open("temp/layertest.pk","w")
+
+    def test_create_folder(self):
+        folder = api.Folder(self.store, "subfolder")
+        self.assertTrue(folder)
+
+    def test_get_path(self):
+        folder = api.Folder(self.store, "foo")
+        self.assertEquals(folder.get_current_path(),"foo")
+
+    def test_open_resource(self):
+        folder = api.Folder(self.store, "foo")
+        res = folder.open_resource("confml/test.confml","w")
+        res.write("foo.conf")
+        res.close()
+        self.assertEquals(folder.list_resources("", recurse=True),["confml/test.confml"])
+        self.assertEquals(self.store.list_resources("", recurse=True),["foo/confml/test.confml"])
 
-from cone.public import api,exceptions,utils
-from cone.storage import stringstorage
+    def test_open_non_existing_resource(self):
+        folder = api.Folder(self.store, "foo")
+        try:
+            folder.open_resource("confml/test.confml","r")
+        except Exception:
+            pass
+        self.assertEquals(folder.storage.curpath, '')
+
+    def test_create_two_layers_and_open_resource(self):
+        foo_folder = api.Folder(self.store, "foo")
+        bar_folder = api.Folder(self.store, "bar")
+        res = foo_folder.open_resource("confml/test.confml","w")
+        res.write("foo.conf")
+        res.close()
+        res = foo_folder.open_resource("root.confml","w")
+        res.close()
+        res = bar_folder.open_resource("confml/root.confml","w")
+        res.write("foo.conf")
+        res.close()
+        self.assertEquals(foo_folder.list_resources("", recurse=True),[ 'root.confml', 
+                                                                       'confml/test.confml'])
+        self.assertEquals(self.store.list_resources("", recurse=True),['bar/confml/root.confml', 
+                                                                       'foo/root.confml', 
+                                                                       'foo/confml/test.confml'])        
+        foo_folder.delete_resource("confml/test.confml")
+        self.assertEquals(foo_folder.list_resources("", recurse=True),["root.confml"])
+        self.assertEquals(self.store.list_resources("", recurse=True),["bar/confml/root.confml",
+                                                                       "foo/root.confml"])
+
 
 class TestLayer(unittest.TestCase):    
     storage_class = stringstorage.StringStorage
+    def setUp(self):
+        self.store = self.storage_class.open("temp/layertest.pk","w")
 
     def test_create_layer(self):
-        store = self.storage_class.open("temp/layertest.pk","w")
-        layer = api.Layer(store, "foo")
+        layer = api.Layer(self.store, "foo")
         self.assertTrue(layer)
 
 #    def test_create_layer_with_kwargs(self):
-#        store = self.storage_class.open("temp/layertest.pk","w")
-#        layer = api.Layer(store, "foo",confml_path="foobar", implml_path="")
+#        self.store = self.storage_class.open("temp/layertest.pk","w")
+#        layer = api.Layer(self.store, "foo",confml_path="foobar", implml_path="")
 #        self.assertTrue(layer)
 #        self.assertEquals(layer.confml_folder.get_current_path(),"foo/foobar")
 #        self.assertEquals(layer.implml_folder.get_current_path(),"foo")
-#        layer = api.Layer(store, "foo",confml_path="f", implml_path="test", content_path="data", doc_path="foo")
+#        layer = api.Layer(self.store, "foo",confml_path="f", implml_path="test", content_path="data", doc_path="foo")
 #        self.assertEquals(layer.confml_folder.get_current_path(),"foo/f")
 #        self.assertEquals(layer.implml_folder.get_current_path(),"foo/test")
 #        self.assertEquals(layer.content_folder.get_current_path(),"foo/data")
 #        self.assertEquals(layer.doc_folder.get_current_path(),"foo/foo")
-#        layer = api.Layer(store, "foo")
+#        layer = api.Layer(self.store, "foo")
 #        self.assertEquals(layer.confml_folder.get_current_path(),"foo/confml")
 #        self.assertEquals(layer.implml_folder.get_current_path(),"foo/implml")
 #        self.assertEquals(layer.content_folder.get_current_path(),"foo/content")
 #        self.assertEquals(layer.doc_folder.get_current_path(),"foo/doc")
 
     def test_get_path(self):
-        store = self.storage_class.open("temp/layertest.pk","w")
-        layer = api.Layer(store, "foo")
+        layer = api.Layer(self.store, "foo")
         self.assertTrue(layer)
         self.assertEquals(layer.get_current_path(),"foo")
 
     def test_open_resource(self):
-        store = self.storage_class.open("temp/layertest.pk","w")
-        layer = api.Layer(store, "foo")
+        layer = api.Layer(self.store, "foo")
         self.assertTrue(layer)
         res = layer.open_resource("confml/test.confml","w")
         res.write("foo.conf")
         res.close()
-        self.assertEquals(layer.list_resources("", True),["confml/test.confml"])
-        self.assertEquals(store.list_resources("", True),["foo/confml/test.confml"])
+        self.assertEquals(layer.list_resources("", recurse=True),["confml/test.confml"])
+        self.assertEquals(self.store.list_resources("", recurse=True),["foo/confml/test.confml"])
 
     def test_create_two_layers_and_open_resource(self):
-        store = self.storage_class.open("temp/layertest.pk","w")
-        foo_layer = api.Layer(store, "foo")
-        bar_layer = api.Layer(store, "bar")
+        foo_layer = api.Layer(self.store, "foo")
+        bar_layer = api.Layer(self.store, "bar")
         res = foo_layer.open_resource("confml/test.confml","w")
         res.write("foo.conf")
         res.close()
@@ -78,15 +125,14 @@
         res = bar_layer.open_resource("confml/root.confml","w")
         res.write("foo.conf")
         res.close()
-        self.assertEquals(foo_layer.list_resources("", True),['confml/test.confml', 'root.confml'])
-        self.assertEquals(store.list_resources("", True),['bar/confml/root.confml','foo/confml/test.confml','foo/root.confml'])        
+        self.assertEquals(foo_layer.list_resources("", recurse=True),['root.confml', 'confml/test.confml'])
+        self.assertEquals(self.store.list_resources("", recurse=True),['bar/confml/root.confml', 'foo/root.confml', 'foo/confml/test.confml'])        
         foo_layer.delete_resource("confml/test.confml")
-        self.assertEquals(foo_layer.list_resources("", True),["root.confml"])
-        self.assertEquals(store.list_resources("", True),["bar/confml/root.confml","foo/root.confml"])
+        self.assertEquals(foo_layer.list_resources("", recurse=True),["root.confml"])
+        self.assertEquals(self.store.list_resources("", recurse=True),["bar/confml/root.confml","foo/root.confml"])
 
     def test_list_confml(self):
-        store = self.storage_class.open("temp/layertest.pk","w")
-        layer = api.Layer(store, "foo")
+        layer = api.Layer(self.store, "foo")
         res = layer.open_resource("confml/test.confml","w")
         res.write("foo.conf")
         res.close()
@@ -99,8 +145,7 @@
         self.assertEquals(layer.list_confml(),['confml/foo.confml', 'confml/test.confml'])
 
     def test_list_implml(self):
-        store = self.storage_class.open("temp/layertest.pk","w")
-        layer = api.Layer(store, "foo")
+        layer = api.Layer(self.store, "foo")
         res = layer.open_resource("implml/stuff/test.confml","w")
         res.write("foo.conf")
         res.close()
@@ -113,8 +158,7 @@
         self.assertEquals(layer.list_implml(),['implml/stuff/test.confml'])
 
     def test_list_content(self):
-        store = self.storage_class.open("temp/layertest.pk","w")
-        layer = api.Layer(store, "foo")
+        layer = api.Layer(self.store, "foo")
         res = layer.open_resource("content/bar/test.txt","w")
         res.write("foo.conf")
         res.close()
@@ -124,11 +168,10 @@
         res = layer.open_resource("root.confml","w")
         res.write("foo.conf")
         res.close()
-        self.assertEquals(layer.list_content(),['content/bar/test.txt', 'content/foo.confml'])
+        self.assertEquals(layer.list_content(),[ 'content/foo.confml', 'content/bar/test.txt'])
 
     def test_list_doc(self):
-        store = self.storage_class.open("temp/layertest.pk","w")
-        layer = api.Layer(store, "foo")
+        layer = api.Layer(self.store, "foo")
         res = layer.open_resource("doc/bar/test.txt","w")
         res.write("foo.conf")
         res.close()
@@ -138,11 +181,10 @@
         res = layer.open_resource("root.confml","w")
         res.write("foo.conf")
         res.close()
-        self.assertEquals(layer.list_doc(),['doc/bar/test.txt', 'doc/foo.confml'])
+        self.assertEquals(layer.list_doc(),['doc/foo.confml', 'doc/bar/test.txt' ])
 
     def test_list_layer_resources(self):
-        store = self.storage_class.open("temp/layertest.pk","w")
-        layer = api.Layer(store, "foo")
+        layer = api.Layer(self.store, "foo")
         res = layer.open_resource("doc/bar/test.txt","w")
         res.write("foo.conf")
         res.close()
@@ -164,8 +206,7 @@
                                                         'doc/bar/test.txt'])
 
     def test_list_layer_with_sublayer(self):
-        store = self.storage_class.open("temp/layertest.pk","w")
-        layer = api.Layer(store, "foo", layers=[api.Layer(store, "bar")])
+        layer = api.Layer(self.store, "foo", layers=[api.Layer(self.store, "bar")])
         res = layer.open_resource("doc/bar/test.txt","w")
         res.write("foo.conf")
         res.close()
@@ -203,36 +244,79 @@
         self.assertEquals(layer.list_content(),['content/data/abc.txt', 'bar/content/barcode.txt'])
         self.assertEquals(layer.list_doc(),['doc/bar/test.txt'])
 
+    def test_list_all_related(self):
+        layer = api.Layer(self.store, "foo")
+        res = layer.open_resource("doc/bar/test.txt","w")
+        res.write("foo.conf")
+        res.close()
+        res = layer.open_resource("confml/foo.confml","w")
+        res.write("foo.conf")
+        res.close()
+        res = layer.open_resource("confml/bar.confml","w")
+        res.write("foo.conf")
+        res.close()
+        res = layer.open_resource("content/data/abc.txt","w")
+        res.write("foo.conf")
+        res.close()
+        res = layer.open_resource("foo.txt","w")
+        res.write("foo.conf")
+        res.close()
+        
+        self.assertEquals(layer.list_all_related(),['content/data/abc.txt', 'doc/bar/test.txt'])
+
+    def test_list_all_related_with_filter(self):
+        store = self.storage_class.open("temp/layertest.pk","w")
+        layer = api.Layer(self.store, "foo")
+        res = layer.open_resource("doc/bar/test.txt","w")
+        res.write("foo.conf")
+        res.close()
+        res = layer.open_resource("confml/foo.confml","w")
+        res.write("foo.conf")
+        res.close()
+        res = layer.open_resource("confml/bar.confml","w")
+        res.write("foo.conf")
+        res.close()
+        res = layer.open_resource("content/data/abc.txt","w")
+        res.write("foo.conf")
+        res.close()
+        res = layer.open_resource("foo.txt","w")
+        res.write("foo.conf")
+        res.close()
+        
+        self.assertEquals(layer.list_all_related(exclude_filters={'content':'.*\.txt'}), ['doc/bar/test.txt'])
+        self.assertEquals(layer.list_all_related(exclude_filters={'doc':'.*\.txt'}), ['content/data/abc.txt'])
+
+
+
+
 class TestCompositeLayer(unittest.TestCase):    
     storage_class = stringstorage.StringStorage
+    def setUp(self):
+        self.store = self.storage_class.open("temp/layertest.pk","w")
 
     def test_create_compositelayer(self):
-        store = self.storage_class.open("temp/layertestcomposite.pk","w")
-        clayer = api.CompositeLayer()
+        clayer = api.CompositeLayer(self.store)
         self.assertTrue(clayer)
 
     def test_create_with_layer(self):
-        store = self.storage_class.open("temp/layertestcomposite.pk","w")
-        clayer = api.CompositeLayer("sub",layers=[api.Layer(store,"test"), api.Layer(store,"foo/bar")])
+        clayer = api.CompositeLayer("sub",layers=[api.Layer(self.store,"test"), api.Layer(self.store,"foo/bar")])
         self.assertEquals(clayer.list_layers(),['test', 'foo/bar'])
 
     def test_create_with_layer_and_add(self):
-        store = self.storage_class.open("temp/layertestcomposite.pk","w")
-        clayer = api.CompositeLayer(layers=[api.Layer(store,"test"), api.Layer(store,"foo/bar")])
+        self.store = self.storage_class.open("temp/layertestcomposite.pk","w")
+        clayer = api.CompositeLayer(self.store, layers=[api.Layer(self.store,"test"), api.Layer(self.store,"foo/bar")])
         self.assertEquals(clayer.list_layers(),['test', 'foo/bar'])
-        clayer.add_layer(api.Layer(store,"res"))
+        clayer.add_layer(api.Layer(self.store,"res"))
         self.assertEquals(clayer.list_layers(),['test', 'foo/bar', 'res'])
 
     def test_get_layer(self):
-        store = self.storage_class.open("temp/layertestcomposite.pk","w")
-        clayer = api.CompositeLayer(layers=[api.Layer(store,"test"), api.Layer(store,"foo/bar")])
+        clayer = api.CompositeLayer(self.store, layers=[api.Layer(self.store,"test"), api.Layer(self.store,"foo/bar")])
         self.assertEquals(clayer.list_layers(),['test', 'foo/bar'])
         layer = clayer.get_layer('foo/bar')
         self.assertEquals(layer.get_current_path(),'foo/bar')
 
     def test_create_layers_with_resources_and_list_with_composite(self):
-        store = self.storage_class.open("temp/layertest.pk","w")
-        foolayer = api.Layer(store, "foo")
+        foolayer = api.Layer(self.store, "foo")
         res = foolayer.open_resource("doc/bar/test.txt","w")
         res.write("foo.conf")
         res.close()
@@ -248,7 +332,7 @@
         res = foolayer.open_resource("foo.txt","w")
         res.write("foo.conf")
         res.close()
-        barlayer = api.Layer(store, "bar")
+        barlayer = api.Layer(self.store, "bar")
         res = barlayer.open_resource("doc/bar/test.txt","w")
         res.write("foo.conf")
         res.close()
--- a/configurationengine/source/cone/public/tests/unittest_mapping.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/public/tests/unittest_mapping.py	Tue Aug 10 14:29:28 2010 +0300
@@ -20,7 +20,6 @@
 import sys
 import os
 import shutil
-import __init__
 
 from cone.public import api, exceptions, mapping
 
--- a/configurationengine/source/cone/public/tests/unittest_options.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/public/tests/unittest_options.py	Tue Aug 10 14:29:28 2010 +0300
@@ -18,12 +18,8 @@
 Test sets
 """
 import unittest
-import sets
-import sys
-import os
-import __init__
 
-from cone.public import api,exceptions,utils
+from cone.public import api,exceptions
 
 
 class TestOption(unittest.TestCase):
--- a/configurationengine/source/cone/public/tests/unittest_persistence.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/public/tests/unittest_persistence.py	Tue Aug 10 14:29:28 2010 +0300
@@ -20,7 +20,6 @@
 import unittest
 import string
 import sys,os
-import __init__
 
 from cone.public import persistence, exceptions
 
--- a/configurationengine/source/cone/public/tests/unittest_plugin_api.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/public/tests/unittest_plugin_api.py	Tue Aug 10 14:29:28 2010 +0300
@@ -16,8 +16,7 @@
 
 import unittest
 import os
-import logging
-import __init__
+
 from cone.public import *
 from cone.public import _plugin_reader
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
@@ -128,7 +127,7 @@
 """.encode('utf-8')
 
 SINGLE_IMPL_2 = """<?xml version="1.0" encoding="UTF-8"?>
-<joujou xmlns="http://www.test.com/xml/2"/>
+<impl xmlns="http://www.test.com/xml/2"/>
 """.encode('utf-8')
 
 SINGLE_IMPL_3 = """<?xml version="1.0" encoding="UTF-8"?>
@@ -137,25 +136,6 @@
 </impl>
 """.encode('utf-8')
 
-IGNORED_NAMESPACE_IMPL_1 = """<?xml version="1.0" encoding="UTF-8"?>
-<common:container xmlns:common="http://www.symbianfoundation.org/xml/implml/1">
-    <impl xmlns="http://www.test.com/xml/3">
-        <elem x="1"/>
-    </impl>
-    
-    <ignored xmlns:ignored="http://www.test.com/xml/ignored/3">
-        <elem test="foo"/>
-    </ignored>
-</common:container>
-""".encode('utf-8')
-
-IGNORED_NAMESPACE_IMPL_2 = """<?xml version="1.0" encoding="UTF-8"?>
-<impl xmlns="http://www.test.com/xml/3" xmlns:ignored="http://www.test.com/xml/ignored/3">
-    <elem x="1"/>
-    <ignored:some_elem/>
-</impl>
-""".encode('utf-8')
-
 NO_IMPL = """<?xml version="1.0" encoding="UTF-8"?>
 <impl>
 </impl>
@@ -195,12 +175,37 @@
     
     def get_default_view(self):
         return MockView(self.features)
+    
+    def layered_implml(self):
+        result = container.DataContainer()
+        for res in self.resources.iterkeys():
+            result.add_value(res, res)
+        return result
+
+class SimpleImpl(plugin.ImplBase):
+    def __init__(self, ref, configuration):
+        super(SimpleImpl, self).__init__(ref, configuration)
+        self.generate_invoked = False
+        self.outputfile = ''
+    
+    def generate(self, context=None):
+        if context:
+            if self.outputfile:
+                f = context.create_file(self.outputfile, implementation=self)
+                f.close()
+                
+        self.generate_invoked = True
 
 class MockImpl(plugin.ImplBase):
+    IMPL_TYPE_ID = 'mock'
+    
     def __init__(self, data):
         self.data = data
         self.generate_invoked = False
-    
+        self.outputfile = ''
+        self.refs = None
+        self.ref = ''
+        
     @classmethod
     def create(cls, resource_ref, configuration, data):
         impl = cls(data)
@@ -230,6 +235,14 @@
         else:
             return False
 
+    def get_refs(self):
+        """
+        Return a list of all ConfML setting references that affect this
+        implementation. May also return None if references are not relevant
+        for the implementation.
+        """
+        return self.refs
+
 class MockReaderBase(plugin.ReaderBase):
     @classmethod
     def read_impl(cls, resource_ref, configuration, root_elem):
@@ -240,12 +253,18 @@
 
 class MockReader1(MockReaderBase):
     NAMESPACE = "http://www.test.com/xml/1"
+    NAMESPACE_ID = "mock1"
+    ROOT_ELEMENT_NAME = "impl"
     FILE_EXTENSIONS = ['mock1ml']
 class MockReader2(MockReaderBase):
     NAMESPACE = "http://www.test.com/xml/2"
+    NAMESPACE_ID = "mock2"
+    ROOT_ELEMENT_NAME = "impl"
     FILE_EXTENSIONS = ['mock2ml']
 class MockReader3(MockReaderBase):
     NAMESPACE = "http://www.test.com/xml/3"
+    NAMESPACE_ID = "mock3"
+    ROOT_ELEMENT_NAME = "impl"
     IGNORED_NAMESPACES = ["http://www.test.com/xml/ignored/3"]
     FILE_EXTENSIONS = ['mock3ml', 'test3ml']
 
@@ -266,12 +285,209 @@
     'layer1/implml/single2.mock2ml'         : SINGLE_IMPL_2,
     'layer1/implml/single3.mock3ml'         : SINGLE_IMPL_3,
     'layer1/implml/single3.test3ml'         : SINGLE_IMPL_3,
-    'layer1/implml/ignored_ns_1.mock3ml'    : IGNORED_NAMESPACE_IMPL_1,
-    'layer1/implml/ignored_ns_2.mock3ml'    : IGNORED_NAMESPACE_IMPL_2,
     'layer1/implml/multi1.dummyml'          : MULTI_IMPL_1,
     'layer1/implml/dummy'                   : MULTI_IMPL_1,
 })
 
+
+class TestPluginGenerationContext(unittest.TestCase):
+    def test_generation_context_handle_terminal(self):
+        config = api.Configuration()
+        context = plugin.GenerationContext(configuration=config)
+        self.assertRaises(exceptions.NotFound, context.handle_terminal, 'feature')
+        config.create_feature('feature')
+        # rebuild default view
+        config._remove('?default_view')
+        self.assertEquals(context.handle_terminal('feature'), None)
+            
+
+    def test_generation_create_file(self):
+        config = api.Configuration()
+        context = plugin.GenerationContext(configuration=config, 
+                                           output=os.path.join(ROOT_PATH, 'temp'),
+                                           phase="normal")
+        mi = MockImpl({})
+        outfile = context.create_file('foobar/test.txt', implementation=mi)
+        outfile.write("Test output file creation")
+        outfile.close()
+        expected = utils.resourceref.norm(os.path.join(context.output, 'foobar/test.txt'))
+        self.assertEquals(len(context.generation_output), 1)
+        self.assertEquals(context.generation_output[0].name, expected)
+        self.assertEquals(context.generation_output[0].implementation, mi)
+        self.assertEquals(context.generation_output[0].phase, "normal")
+        self.assertTrue(os.path.exists(expected))
+        os.unlink(expected)
+
+        absfile = utils.resourceref.norm(os.path.join(ROOT_PATH, 'temp/foobar/abspath.txt'))
+        outfile = context.create_file(absfile, implementation=mi)
+        outfile.write("Test output file creation")
+        outfile.close()
+        self.assertEquals(len(context.generation_output), 2)
+        self.assertEquals(context.generation_output[1].name, absfile)
+        self.assertEquals(context.generation_output[1].implementation, mi)
+        self.assertEquals(context.generation_output[1].phase, "normal")
+        self.assertTrue(os.path.exists(absfile))
+        os.unlink(absfile)
+        
+    def test_generation_add_output(self):
+        config = api.Configuration()
+        context = plugin.GenerationContext(configuration=config, 
+                                           output=os.path.join(ROOT_PATH, 'temp'),
+                                           phase="normal")
+        mi = MockImpl({})
+        context.add_file('add.txt', implementation=mi)
+
+        self.assertEquals(len(context.generation_output), 1)
+        self.assertEquals(context.generation_output[0].name, utils.resourceref.norm(os.path.join(context.output, 'add.txt')))
+        self.assertEquals(context.generation_output[0].implementation, mi)
+        self.assertEquals(context.generation_output[0].phase, "normal")
+        
+        external_output = utils.resourceref.norm(os.path.join(ROOT_PATH, 'temp', 'external/foobar.txt'))
+        context.add_file(external_output, implementation=mi)
+        self.assertEquals(len(context.generation_output), 2)
+        self.assertEquals(context.generation_output[1].name, external_output)
+        self.assertEquals(context.generation_output[1].implementation, mi)
+        self.assertEquals(context.generation_output[1].phase, "normal")
+
+    def test_generation_get_output(self):
+        config = api.Configuration()
+        context = plugin.GenerationContext(configuration=config, 
+                                           output=os.path.join(ROOT_PATH, 'temp'),
+                                           phase="normal")
+        mi = MockImpl({})
+        context.add_file('add1.txt', implementation=mi)
+        context.add_file('foo/add2.txt', implementation=None)
+
+        self.assertEquals(len(context.get_output()), 2)
+        self.assertEquals(context.get_output()[1].filename, 'add2.txt')
+        self.assertEquals(context.get_output()[1].abspath, os.path.normpath(os.path.join(context.output,'foo/add2.txt')))
+        self.assertEquals(context.get_output()[1].relpath, os.path.normpath('foo/add2.txt'))
+        self.assertEquals(len(context.get_output(implml_type='mock')), 1)
+        self.assertEquals(context.get_output(implml_type='mock')[0].filename, 'add1.txt')
+
+    def test_generation_get_refs_no_output(self):
+        config = api.Configuration()
+        context = plugin.GenerationContext(configuration=config, 
+                                           output=os.path.join(ROOT_PATH, 'temp'),
+                                           phase="normal")
+        self.assertEquals(context.get_refs_with_no_output(),[]) 
+        self.assertEquals(context.get_refs_with_no_output(['']),['']) 
+
+        context.changed_refs = ['foo.bar', 
+                                'foo.two',
+                                'foo.three']
+        
+        self.assertEquals(context.get_refs_with_no_output(),['foo.bar', 
+                                                             'foo.three',
+                                                             'foo.two']) 
+        mi = MockImpl({})
+        mi.refs = ['foo.bar','nonno.noo','foo.three']
+        context.add_file('add1.txt', implementation=mi)
+        context.add_file('foo/add2.txt', implementation=None)
+        
+        self.assertEquals(context.get_refs_with_no_output(),['foo.two']) 
+        context.changed_refs = ['foo.bar', 
+                                'foo.three']
+        self.assertEquals(context.get_refs_with_no_output(),[]) 
+        mi.refs = []
+        self.assertEquals(context.get_refs_with_no_output(),['foo.bar', 
+                                                             'foo.three']) 
+        mi.refs = None
+        self.assertEquals(context.get_refs_with_no_output(),['foo.bar', 
+                                                             'foo.three']) 
+
+    def test_merged_context_get_changed_refs_intersect(self):
+        config = api.Configuration()
+        context1 = plugin.GenerationContext(configuration=config, 
+                                           output=os.path.join(ROOT_PATH, 'temp'),
+                                           phase="normal")
+        context2 = plugin.GenerationContext(configuration=config, 
+                                           output=os.path.join(ROOT_PATH, 'temp'),
+                                           phase="normal")
+
+        context1.changed_refs = ['foo.bar', 
+                                'foo.two',
+                                'foo.three']
+        context2.changed_refs = ['foo.bar', 
+                                'foo.two1']
+        outs = plugin.MergedContext([context1,context2])
+        self.assertEquals(sorted(outs.get_changed_refs(operation='union')), 
+                          sorted(['foo.two1',
+                                  'foo.bar',
+                                  'foo.two',
+                                  'foo.three']))
+        self.assertEquals(outs.get_changed_refs(operation='intersection'), ['foo.bar'])
+        self.assertEquals(sorted(outs.get_changed_refs(operation='difference')), sorted(['foo.three',
+                                                                                         'foo.two']))
+        self.assertEquals(sorted(outs.get_changed_refs(operation='symmetric_difference')), sorted(['foo.two1', 
+                                                                                          'foo.three', 
+                                                                                          'foo.two']))
+
+    def test_generation_get_refs_no_output_with_two_contexts(self):
+        config = api.Configuration()
+        context1 = plugin.GenerationContext(configuration=config, 
+                                           output=os.path.join(ROOT_PATH, 'temp'),
+                                           phase="normal")
+        context2 = plugin.GenerationContext(configuration=config, 
+                                           output=os.path.join(ROOT_PATH, 'temp'),
+                                           phase="normal")
+
+        context1.changed_refs = ['foo.bar', 
+                                'foo.two',
+                                'foo.three']
+        context2.changed_refs = ['foo.bar1', 
+                                'foo.two1']
+        
+        
+        mi1 = MockImpl({})
+        mi1.refs = ['foo.bar','nonno.noo','foo.three']
+        mi2 = MockImpl({})
+        mi2.refs = ['foo.bar1']
+        context1.add_file('add1.txt', implementation=mi1)
+        context1.add_file('foo/add2.txt', implementation=None)
+        context2.add_file('add2.txt', implementation=mi2)
+        outs = plugin.MergedContext([context1,context2])
+        self.assertEquals(outs.get_refs_with_no_output(), ['foo.two', 'foo.two1'])
+        self.assertEquals(outs.get_refs_with_no_output(['foo.two']), ['foo.two'])
+        self.assertEquals(outs.get_refs_with_no_output(['foo.bar']), [])
+
+    def test_generation_get_refs_with_no_implementation(self):
+        config = api.Configuration()
+        context1 = plugin.GenerationContext(configuration=config, 
+                                           output=os.path.join(ROOT_PATH, 'temp'),
+                                           phase="normal")
+        context2 = plugin.GenerationContext(configuration=config, 
+                                           output=os.path.join(ROOT_PATH, 'temp'),
+                                           phase="normal")
+
+        context1.changed_refs = ['foo.bar', 
+                                'foo.two',
+                                'foo.three']
+        context2.changed_refs = ['foo.bar1', 
+                                'foo.two1']
+        
+        
+        mi1 = MockImpl({})
+        mi1.ref = 'mi1'
+        mi1.refs = ['foo.bar','nonno.noo','foo.three']
+        mi2 = MockImpl({})
+        mi2.ref = 'mi2'
+        mi2.refs = ['foo.bar1']
+        context1.impl_set.add(mi1)
+        context2.impl_set.add(mi2)
+        outs = plugin.MergedContext([context1,context2])
+        self.assertEquals(outs.get_refs_with_no_implementation(), ['foo.two', 'foo.two1'])
+        self.assertEquals(outs.get_refs_with_no_implementation(['foo.bar']), [])
+        self.assertEquals(outs.get_refs_with_no_implementation(['foo.two', 'foo.bar1']), ['foo.two'])
+
+
+    def test_context_data_grep_log(self):
+        context = plugin.GenerationContext()
+        context.log = ['foo bar',
+                     'foo faa',
+                     'jee jee jehu']
+        self.assertEquals(context.grep_log('jee'), [(2,'jee jee jehu')])
+
 class TestPluginImplBase(unittest.TestCase):
     def setUp(self):
         pass
@@ -293,7 +509,24 @@
         self.assertEquals(impl.has_tag({'foo': ['foo']}, policy='AND'), False)
         self.assertEquals(impl.has_tag({'target': ['foo'], 'foo':['bar']}, policy='AND'), False)
         self.assertEquals(impl.has_tag({'target': ['foo'], 'foo':['bar']}, policy='OR'), True)
-    
+
+    def test_implbase_output(self):
+        str = api.Storage(utils.relpath(ROOT_PATH))
+        config = api.Configuration('foo')
+        config.storage = str
+        impl = plugin.ImplBase('foo.implml', config)
+        self.assertEquals(impl.output, '')
+        impl.plugin_output = 'test'
+        self.assertEquals(impl.output, 'test')
+        impl.set_output_root('foobar')
+        self.assertEquals(impl.output, 'foobar/test')
+        impl.set_output_root('/foobar')
+        self.assertEquals(impl.output, '/foobar/test')
+
+        self.assertEquals(impl.path, 'foo.implml')
+        self.assertEquals(impl.abspath, os.path.abspath(os.path.join(ROOT_PATH,'foo.implml')))
+
+
     def test_implbase_tags_with_refs(self):
         config = MockConfiguration({}, features = {
             'Foo.Bar'           : 'foobar',
@@ -353,106 +586,134 @@
         self.assertTrue(impl.has_ref(['Yay', 'Foo.Bar.Baz', 'Fhtagn']))
         self.assertTrue(impl.has_ref(['Yay', 'Xyz', 'Fhtagn']))
         
-    def test_impl_container_eval_context_with_tags(self):
-        container = plugin.ImplBase("norm", None)
-        context = plugin.GenerationContext()
-        self.assertTrue(container._eval_context(context))
-        container.set_tags({'target':['rofs2','core']})
-        context.tags = {'target': ['rofs2'], 'foobar': ['test']}
-        self.assertTrue(container._eval_context(context))
-        context.tags_policy = "AND"
-        self.assertFalse(container._eval_context(context))
-        container.set_tags({})
-        self.assertFalse(container._eval_context(context))
-        context.tags = {'target': ['rofs2']}
-        self.assertFalse(container._eval_context(context))
-        context.tags = {}
-        self.assertTrue(container._eval_context(context))
 
-class TestPluginImplSet(unittest.TestCase):
+class TestPlugin(plugin.ImplBase):
+    def __init__(self, ref):
+        super(TestPlugin, self).__init__(ref, None)
+        self.refs = None
     
+    def get_refs(self):
+        return self.refs
+
+class TestPluginImplSet(unittest.TestCase):    
     def test_add_implementation_and_list(self):
-        container = plugin.ImplSet()
+        iset= plugin.ImplSet()
         imp1  = plugin.ImplBase("implml/test.content",None)
         imp2a = plugin.ImplBase("implml/copy.content",None)
         imp2b = plugin.ImplBase("implml/copy.content",None)
-        container.add_implementation(imp1)
-        container.add_implementation(imp2a)
-        container.add_implementation(imp2b)
-        self.assertEquals(sorted(container.list_implementation()),
+        iset.add_implementation(imp1)
+        iset.add_implementation(imp2a)
+        iset.add_implementation(imp2b)
+        self.assertEquals(sorted(iset.list_implementation()),
                           sorted(['implml/test.content',
                                   'implml/copy.content']))
 
+    def test_add_implementation_and_generate(self):
+        iset = plugin.ImplSet()
+        imp1  = SimpleImpl("implml/test1.content", None)
+        imp1.outputfile = 'test/foo.txt'
+        imp2a = SimpleImpl("implml/test2.content", None)
+        imp2b = SimpleImpl("implml/test3.content", None)
+        iset.add_implementation(imp1)
+        iset.add_implementation(imp2a)
+        iset.add_implementation(imp2b)
+        context = plugin.GenerationContext(output="temp")
+        iset.generate(context)
+        self.assertEquals(sorted(context.executed_impls), sorted([imp1, imp2a, imp2b])) 
+        self.assertEquals(context.generation_output[0].name, 'temp/test/foo.txt')
+        self.assertTrue(os.path.exists(context.generation_output[0].name))
+        self.assertEquals(context.generation_output[0].implementation,imp1)
+
+
+    def test__generate_with_exception(self):
+        def generate_exception(*args):
+            raise Exception("test exception %s" % args)
+            
+        iset = plugin.ImplSet()
+        imp1  = SimpleImpl("implml/test1.content", None)
+        imp1.outputfile = 'test/foo.txt'
+        imp2a = SimpleImpl("implml/test2.content", None)
+        imp2a.generate = generate_exception
+        iset.add_implementation(imp1)
+        iset.add_implementation(imp2a)
+        context = plugin.GenerationContext(output="temp")
+        iset.generate(context)
+        self.assertEquals(sorted(context.executed_impls), sorted([imp1, imp2a])) 
+        self.assertEquals(context.generation_output[1].type, 'exception')
+        self.assertEquals(context.generation_output[1].name, 'exception from implml/test2.content')
+        self.assertEquals(context.generation_output[1].implementation, imp2a)
+
     def test_add_implementation_and_get_implementations_by_file(self):
-        container = plugin.ImplSet()
+        iset = plugin.ImplSet()
         imp1  = plugin.ImplBase("implml/test.content",None)
         imp2a = plugin.ImplBase("implml/copy.content",None)
         imp2b = plugin.ImplBase("implml/copy.content",None)
-        container.add_implementation(imp1)
-        container.add_implementation(imp2a)
-        container.add_implementation(imp2b)
-        self.assertEquals(container.get_implementations_by_file("implml/test.content"), [imp1])
-        self.assertEquals(sorted(container.get_implementations_by_file("implml/copy.content")),
+        iset.add_implementation(imp1)
+        iset.add_implementation(imp2a)
+        iset.add_implementation(imp2b)
+        self.assertEquals(iset.get_implementations_by_file("implml/test.content"), [imp1])
+        self.assertEquals(sorted(iset.get_implementations_by_file("implml/copy.content")),
                           sorted([imp2a, imp2b]))
 
     def test_add_implementation_and_remove_implementation(self):
-        container = plugin.ImplSet()
+        iset = plugin.ImplSet()
         imp1  = plugin.ImplBase("implml/test.content",None)
         imp2a = plugin.ImplBase("implml/copy.content",None)
         imp2b = plugin.ImplBase("implml/copy.content",None)
-        container.add_implementation(imp1)
-        container.add_implementation(imp2a)
-        container.add_implementation(imp2b)
-        container.remove_implementation("implml/test.content")
-        self.assertEquals(len(container.list_implementation()),1)
-        self.assertEquals(container.list_implementation()[0],"implml/copy.content")
+        iset.add_implementation(imp1)
+        iset.add_implementation(imp2a)
+        iset.add_implementation(imp2b)
+        iset.remove_implementation("implml/test.content")
+        self.assertEquals(len(iset.list_implementation()),1)
+        self.assertEquals(iset.list_implementation()[0],"implml/copy.content")
 
     def test_add_implementation_and_remove_all(self):
-        container = plugin.ImplSet()
+        iset = plugin.ImplSet()
         imp1  = plugin.ImplBase("implml/test.content",None)
         imp2a = plugin.ImplBase("implml/copy.content",None)
         imp2b = plugin.ImplBase("implml/copy.content",None)
         imp3  = plugin.ImplBase("implml/foo.content",None)
-        container.add_implementation(imp1)
-        container.add_implementation(imp2a)
-        container.add_implementation(imp2b)
-        container.add_implementation(imp3)
-        for implref in container.list_implementation():
-            container.remove_implementation(implref)
-        self.assertEquals(len(container.list_implementation()),0)
+        iset.add_implementation(imp1)
+        iset.add_implementation(imp2a)
+        iset.add_implementation(imp2b)
+        iset.add_implementation(imp3)
+        for implref in iset.list_implementation():
+            iset.remove_implementation(implref)
+        self.assertEquals(len(iset.list_implementation()),0)
 
     def test_create_impl_set(self):
         plugin.create_impl_set('',None);
         pass
 
     def test_add_implementation_find_with_tags(self):
-        class TestPlugin(plugin.ImplBase):
-            pass
-        container = plugin.ImplSet()
-        imp1 = TestPlugin("implml/test.content",None)
-        imp2 = TestPlugin("implml/copy.content",None)
-        imp3 = TestPlugin("implml/foo.content",None)
+        def impl_list(impl_iterable):
+            return sorted(list(impl_iterable), key=lambda impl: impl.ref)
+        
+        iset = plugin.ImplSet()
+        imp1 = TestPlugin("implml/test.content")
+        imp2 = TestPlugin("implml/copy.content")
+        imp3 = TestPlugin("implml/foo.content")
         imp1.set_tags({'target': ['core','rofs2','rofs3']})
         imp2.set_tags({'target': ['rofs3','uda']})
         imp3.set_tags({'target': ['mmc','uda']})
-        container.add_implementation(imp1)
-        container.add_implementation(imp2)
-        container.add_implementation(imp3)
-        self.assertEquals(list(container.filter_implementations(tags={'target' : ['rofs3']})),
-                          [imp1,imp2])
-        self.assertEquals(list(container.filter_implementations(tags={'target' : ['uda']})),
-                          [imp2,imp3])
-        self.assertEquals(list(container.filter_implementations(tags={'target' : ['mmc','uda']}, policy='AND')),
-                          [imp3])
-        self.assertEquals(list(container.filter_implementations(tags={'target' : ['mmc','uda']}, policy='OR')),
-                          [imp2, imp3])
-        cont = container.filter_implementations(tags={'target' : ['core']}) | container.filter_implementations(tags={'target' : ['mmc']}) 
+        iset.add_implementation(imp1)
+        iset.add_implementation(imp2)
+        iset.add_implementation(imp3)
+        self.assertEquals(impl_list(iset.filter_implementations(tags={'target' : ['rofs3']})),
+                          impl_list([imp1,imp2]))
+        self.assertEquals(impl_list(iset.filter_implementations(tags={'target' : ['uda']})),
+                          impl_list([imp2,imp3]))
+        self.assertEquals(impl_list(iset.filter_implementations(tags={'target' : ['mmc','uda']}, policy='AND')),
+                          impl_list([imp3]))
+        self.assertEquals(impl_list(iset.filter_implementations(tags={'target' : ['mmc','uda']}, policy='OR')),
+                          impl_list([imp2, imp3]))
+        cont = iset.filter_implementations(tags={'target' : ['core']}) | iset.filter_implementations(tags={'target' : ['mmc']}) 
         self.assertEquals(len(cont),2)
-        self.assertEquals(list(cont), [imp1,imp3])
+        self.assertEquals(impl_list(cont), impl_list([imp1,imp3]))
 
-        cont = container.filter_implementations(tags={'target' : ['rofs3']}) & container.filter_implementations(tags={'target' : ['uda']}) 
+        cont = iset.filter_implementations(tags={'target' : ['rofs3']}) & iset.filter_implementations(tags={'target' : ['uda']}) 
         self.assertEquals(len(cont),1)
-        self.assertEquals(list(cont), [imp2])
+        self.assertEquals(impl_list(cont), impl_list([imp2]))
     
     def test_pre_impl_filter(self):
         resources = [
@@ -483,6 +744,40 @@
         expected = map(lambda path: path.replace('/', '\\'), expected)
         self.assertEquals(expected, plugin.pre_filter_impls(resources))
 
+    def test_get_implemented_refs(self):
+            
+        iset = plugin.ImplSet()
+        imp1 = TestPlugin('imp1')
+        imp2 = TestPlugin('imp2')
+        imp3 = TestPlugin('imp3')
+        iset.add_implementation(imp1)
+        iset.add_implementation(imp2)
+        iset.add_implementation(imp3)
+        imp1.refs = ['fea.child1', 'fea.child2']
+        imp2.refs = ['fea.setting1']
+        imp3.refs = ['foo.bar']
+        self.assertEquals(sorted(iset.get_implemented_refs()), sorted(['fea.child1', 
+                                                                       'fea.child2',
+                                                                       'fea.setting1',
+                                                                       'foo.bar']))
+
+    def test_get_implementations_with_ref(self):
+            
+        iset = plugin.ImplSet()
+        imp1 = TestPlugin('implml1')
+        imp2 = TestPlugin('implml2')
+        imp3 = TestPlugin('implml3')
+        imp4 = TestPlugin('implml3')
+        iset.add_implementation(imp1)
+        iset.add_implementation(imp2)
+        iset.add_implementation(imp3)
+        iset.add_implementation(imp4)
+        imp1.refs = ['fea.child1', 'fea.child2']
+        imp2.refs = ['foo.bar', 'fea.setting1']
+        imp3.refs = ['foo.bar']
+        self.assertEquals(iset.get_implementations_with_ref('fea.child1'), [imp1])
+        self.assertEquals(iset.get_implementations_with_ref('fea.setting1'), [imp2])
+        self.assertEquals(iset.get_implementations_with_ref('foo.bar'), [imp2, imp3])
 
 class TestPluginImplSetCopy(unittest.TestCase):
     class TestImpl(plugin.ImplBase):
@@ -509,12 +804,12 @@
         return plugin.create_impl_set(impl_files, mock_config)
     
 
-    def test_get_test_impl_container(self):
-        container = self._get_impl_container()
+    def test_get_test_impl_iset(self):
+        iset = self._get_impl_container()
         # There are 5 ImplML files
-        self.assertEquals(len(container.list_implementation()), 5)
+        self.assertEquals(len(iset.list_implementation()), 5)
         # ...but two of them contain 3 implementations each
-        self.assertEquals(len(container), 5)
+        self.assertEquals(len(iset), 5)
     
     def _get_phase_test_impl_container(self):
         return plugin.ImplSet([
@@ -525,13 +820,13 @@
             self.PostImpl('foo.post', None),
         ])
     
-    def test_get_phase_test_impl_container(self):
-        container = self._get_phase_test_impl_container()
-        self.assertEquals(5, len(container))
-        self.assertEquals(len(container.list_implementation()), 5)
+    def test_get_phase_test_impl_iset(self):
+        iset = self._get_phase_test_impl_container()
+        self.assertEquals(5, len(iset))
+        self.assertEquals(len(iset.list_implementation()), 5)
         
         def check(filename, phase):
-            impls = container.get_implementations_by_file(filename)
+            impls = iset.get_implementations_by_file(filename)
             self.assertEquals(1, len(impls))
             impl = impls[0]
             self.assertEquals(impl.ref, filename)
@@ -542,31 +837,31 @@
         check('test.post', 'post')
         check('foo.post', 'post')
         
-        return container
+        return iset
     
     def test_create_impl_set(self):
-        container = self._get_impl_container()
+        iset = self._get_impl_container()
         # There are 5 ImplML files
-        self.assertEquals(len(container.list_implementation()), 5)
+        self.assertEquals(len(iset.list_implementation()), 5)
         # ...but two of them contain 3 implementations each
-        self.assertEquals(len(container), 5)
+        self.assertEquals(len(iset), 5)
     
     def test_invocation_phases(self):
-        container = self._get_phase_test_impl_container()
-        phases = container.invocation_phases()
+        iset = self._get_phase_test_impl_container()
+        phases = iset.invocation_phases()
         self.assertEquals(phases,['pre','normal','post'])
  
     def test_copy(self):
-        container = self._get_impl_container()
-        newcontainer = container.copy()
-        self.assertTrue(newcontainer is not container)
+        iset = self._get_impl_container()
+        newcontainer = iset.copy()
+        self.assertTrue(newcontainer is not iset)
         self.assertEquals(len(newcontainer), 5)
 
     def test_execute_generate(self):
-        container = self._get_impl_container()
-        container.execute(container, 'generate')
+        iset = self._get_impl_container()
+        iset.execute(iset, 'generate')
         actual_impls = []
-        for impl in container:
+        for impl in iset:
             if isinstance(impl, plugin.ImplContainer):
                 actual_impls += impl.get_all_implementations()
             else:
@@ -575,14 +870,14 @@
             self.assertTrue(impl.generate_invoked)
 
     def test_impl_container_generate(self):
-        container = self._get_impl_container()
+        iset = self._get_impl_container()
         context = plugin.GenerationContext()
         context.history = ""
         context.objects = []
-        container.generate(context)
+        iset.generate(context)
         self.assertEquals(len(context.objects), 9)
         actual_impls = []
-        for impl in container:
+        for impl in iset:
             if isinstance(impl, plugin.ImplContainer):
                 actual_impls += impl.get_all_implementations()
             else:
@@ -591,27 +886,27 @@
             self.assertTrue(impl.generate_invoked)
 
     def test_filter_all(self):
-        container = self._get_impl_container()
-        impl_list = container.filter_implementations()
+        iset = self._get_impl_container()
+        impl_list = iset.filter_implementations()
         self.assertEquals(len(impl_list), 5)
 
     def test_filter_for_pre_phase(self):
-        container = self._get_phase_test_impl_container()
-        impl_list = list(container.filter_implementations(phase='pre'))
+        iset = self._get_phase_test_impl_container()
+        impl_list = list(iset.filter_implementations(phase='pre'))
         self.assertEquals(len(impl_list), 1)
         self.assertEquals(impl_list[0].invocation_phase(), 'pre')
         self.assertEquals(impl_list[0].ref, 'foo.pre')
 
     def test_filter_for_normal_phase(self):
-        container = self._get_phase_test_impl_container()
-        impl_list = list(container.filter_implementations(phase='normal'))
+        iset = self._get_phase_test_impl_container()
+        impl_list = list(iset.filter_implementations(phase='normal'))
         self.assertEquals(len(impl_list), 2)
         self.assertEquals(impl_list[0].invocation_phase(), 'normal')
         self.assertEquals(impl_list[1].invocation_phase(), 'normal')
 
     def test_filter_for_post_phase(self):
-        container = self._get_phase_test_impl_container()
-        impl_list = list(container.filter_implementations(phase='post'))
+        iset = self._get_phase_test_impl_container()
+        impl_list = list(iset.filter_implementations(phase='post'))
         self.assertEquals(len(impl_list), 2)
         self.assertEquals(impl_list[0].invocation_phase(), 'post')
         self.assertEquals(impl_list[1].invocation_phase(), 'post')
@@ -628,11 +923,11 @@
     def test_plugin_settings(self):
         settings.SettingsFactory.cone_parser().read([os.path.join(ROOT_PATH,'test_defaults.cfg')])
         impl = TestPluginImplSettings.Test1Impl("",None)
-        self.assertEquals(impl.output_root, 'output')
+        self.assertEquals(impl.output_root, '')
         self.assertEquals(impl.output_subdir, '')
         impl.output_subdir = 'foobar'
         self.assertEquals(impl.get_tags(), {})
-        self.assertEquals(impl.output, 'output/foobar')
+        self.assertEquals(impl.output, 'foobar')
 
         impl = TestPluginImplSettings.Test2Impl("",None)
         self.assertEquals(impl.output_subdir, '')
@@ -740,12 +1035,6 @@
              MockImpl(['MockReader2', file, {'a': '1', 'b': '2'}]),],
             file)
         
-        file = 'layer1/implml/ignored_ns_1.mock3ml'
-        self.assert_read_impls_equal([MockImpl(['MockReader3', file, {'x': '1'}])], file)
-        
-        file = 'layer1/implml/ignored_ns_2.mock3ml'
-        self.assert_read_impls_equal([MockImpl(['MockReader3', file, {'x': '1'}])], file)
-        
         
         self.assert_read_impls_equal([], 'layer1/implml/unsupported1.implml')
         self.assert_read_impls_equal([], 'layer1/implml/unsupported2.implml')
@@ -788,9 +1077,6 @@
             
             MockImpl(['MockReader3', 'layer1/implml/single3.test3ml', {'x': '1'}]),
             
-            MockImpl(['MockReader3', 'layer1/implml/ignored_ns_1.mock3ml', {'x': '1'}]),
-            MockImpl(['MockReader3', 'layer1/implml/ignored_ns_2.mock3ml', {'x': '1'}]),
-            
             MockImpl(['MockReader1','layer1/implml/multi1.implml', {'y': '2', 'x': '1'}]),  
             MockImpl(['MockReader2', 'layer1/implml/multi1.implml', {'y': '20', 'x': '10'}]),
             MockImpl(['MockReader3', 'layer1/implml/multi1.implml', {'y': '200', 'x': '100'}, {'z': '300'}]),
@@ -878,8 +1164,8 @@
         self.assert_contains_feature(config, 'TempFeature.Seq.DefaultType', 'string', [])
         
         fea = config.get_default_view().get_feature('TempFeature.Seq')
-        fea.set_value([['test', '1', '2.0', 'true', 'foo']])
-        self.assertEquals(fea.get_value(), [['test', '1', '2.0', 'true', 'foo']])
+        fea.set_value([['test', 1, 2.0, True, 'foo']])
+        self.assertEquals(fea.get_value(), [['test', 1, 2.0, True, 'foo']])
     
     def _create_mock_impl(self, temp_var_defs):
         impl = Mock()
@@ -950,7 +1236,10 @@
         
         config = api.Configuration("test.confml")
         config.add_feature(api.Feature("Int"), "TempFeature")
-        self.assertRaises(exceptions.AlreadyExists, impls.create_temp_features, config)
+        #self.assertRaises(exceptions.AlreadyExists, impls.create_temp_features, config)
+        temp_feature_refs = impls.create_temp_features(config)
+        self.assertEquals(temp_feature_refs, ['TempFeature.String', 'TempFeature.Real', 'TempFeature.Boolean'])
+        
 
 class TestCommonImplmlDataReader(unittest.TestCase):
     
--- a/configurationengine/source/cone/public/tests/unittest_plugin_implcontainer.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/public/tests/unittest_plugin_implcontainer.py	Tue Aug 10 14:29:28 2010 +0300
@@ -17,8 +17,8 @@
 import unittest
 import os
 import logging
-import __init__
-from cone.public import *
+
+from cone.public import api, plugin, rules
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
 
 
@@ -28,19 +28,33 @@
         def __init__(self,ref,configuration):
             plugin.ImplBase.__init__(self,ref,configuration)
             self.generate_invoked = False
+            self.output_created = False
             self.refs = ["dummy1.too"]
-            self.output_files = []
+            self.output_files = ['foo/test.txt']
+            self.context = None
         def generate(self, context=None):
             self.generate_invoked = True
-            if context and hasattr(context, 'objects'):
-                context.objects.append(self)
-
+            if context:
+                for outfile in self.list_output_files():
+                    context.add_file(outfile, implementation=self)
+            
         def get_refs(self):
             return self.refs
 
         def list_output_files(self):
             return self.output_files
 
+        def get_outputs(self):
+            """
+            Return a list of GenerationOutput objets as a list. 
+            """
+            outputs = []
+            phase = None 
+            if self.context: phase = self.context.phase
+            for outfile in self.list_output_files():
+                outputs.append( plugin.GenerationOutput(outfile,self,type='file', phase=phase) )
+            return outputs
+    
     def test_impl_container_add(self):
         container = plugin.ImplContainer("norm", None)
         imp1  = plugin.ImplBase("implml/test.content",None)
@@ -62,8 +76,6 @@
         subcontainer.append(imp2b)
         container.append(subcontainer)
         self.assertEquals(container.get_all_implementations(),[imp1,imp2a,imp2b])
-        for sub in container:
-            print sub
         self.assertEquals(container.impls, [imp1,subcontainer])
         container[0] = subcontainer
         self.assertEquals(container.impls, [subcontainer,subcontainer])
@@ -71,6 +83,10 @@
         self.assertEquals(container.impls, [subcontainer])
 
     def test_impl_container_with_condition(self):
+        logger = logging.getLogger('cone')
+        ch = logging.StreamHandler()
+        ch.setLevel(logging.DEBUG)
+        logger.addHandler(ch)
         context = plugin.GenerationContext()
         context.configuration = api.Configuration()
         context.configuration.add_feature(api.Feature("test"))
@@ -95,7 +111,6 @@
         imp1.generate_invoked = False
         condition = rules.SimpleCondition("${test}", "false")
         container.condition = condition
-        container.append(imp1)
         container.generate(context)
         self.assertTrue(imp1.generate_invoked)
         imp1.generate_invoked = False
@@ -103,6 +118,16 @@
         container.generate(context)
         self.assertFalse(imp1.generate_invoked)
 
+        imp1.generate_invoked = False
+        condition = rules.SimpleCondition("${test.intsub}", "1")
+        container.condition = condition
+        container.append(imp1)
+        container.generate(context)
+        self.assertFalse(imp1.generate_invoked)
+        context.configuration.get_default_view().test.intsub.value = 1
+        container.generate(context)
+        self.assertTrue(imp1.generate_invoked)
+        
         
     def test_impl_container_generate(self):
         container = plugin.ImplContainer("norm", None)
@@ -127,21 +152,20 @@
         container.append(imp2a)
         container.append(imp2b)
         container.append(subcontainer)
-        self.assertEquals(container.get_tags(), {})
+        self.assertEquals(container.get_tags(), None)
+        self.assertEquals(container.get_child_tags(), {})
         container.set_tags({'test':['foobar']})
-        self.assertEquals(container.get_tags(), {'test':['foobar']})
+        self.assertEquals(container.get_tags(), None)
+        self.assertEquals(container.get_child_tags(), {})
         imp1.set_tags({'foo':['bar']})
-        self.assertEquals(container.get_tags(), {'test':['foobar'],
-                                                 'foo':['bar']})
-        imp2a.set_tags({'test':['bar'], 'one' :['more']})
+        self.assertEquals(container.get_child_tags(), {'foo':['bar']})
+        self.assertEquals(container.get_tags(), None)
+        imp2a.set_tags({'test':['bar'], 'foo' :['more']})
+        self.assertEquals(container.get_child_tags(), {'foo':['bar', 'more'], 'test': ['bar']})
         
-        self.assertEquals(container.get_tags(), {'test':['foobar', 'bar'],
-                                                 'foo':['bar'],
-                                                 'one' :['more']})
+        self.assertEquals(container.get_tags(), None)
         subcontainer.set_tags({'test':['bar1']})
-        self.assertEquals(container.get_tags(), {'test':['foobar', 'bar', 'bar1'],
-                                                 'foo':['bar'],
-                                                 'one' :['more']})
+        self.assertEquals(container.get_tags(), None)
 
     def test_impl_container_get_phase(self):
         container = plugin.ImplContainer("norm", None)
@@ -154,16 +178,16 @@
         subcontainer1.append(imp2a)
         subcontainer1.append(imp2b)
         subcontainer1.set_invocation_phase("normal")
-        self.assertEquals(container.invocation_phase(), ["normal"])
+        self.assertEquals(container.invocation_phase(), "normal")
         imp1.set_invocation_phase('pre')
-        self.assertEquals(container.invocation_phase(), ["normal"])
+        self.assertEquals(container.invocation_phase(), "normal")
         subcontainer2 = plugin.ImplContainer("norm", None)
         subimp = TestPluginImplContainer.ImplTest("implml/copy:24.content",None)
         subimp.set_invocation_phase('post')
         subcontainer2.append(subimp)
         subcontainer2.set_invocation_phase('post')
         container.append(subcontainer2)
-        self.assertEquals(container.invocation_phase(), ['post','normal'])
+        self.assertEquals(container.invocation_phase(), 'normal')
         
     def test_impl_container_get_refs(self):
         container = plugin.ImplContainer("norm", None)
@@ -173,10 +197,14 @@
         container.append(imp1)
         container.append(imp2a)
         container.append(imp2b)
-        self.assertEquals(container.get_refs(), ["dummy1.too"])
+        self.assertEquals(container.get_refs(), None)
+        self.assertEquals(container.get_child_refs(), ['dummy1.too'])
         imp2b.refs = ['dummy2.foo']
-        self.assertEquals(container.get_refs(), ["dummy1.too",
-                                                 "dummy2.foo",])
+        self.assertEquals(container.get_refs(), None)
+        self.assertEquals(container.get_child_refs(), ['dummy1.too', 'dummy2.foo'])
+        imp2b.refs = None
+        self.assertEquals(container.get_refs(), None)
+        self.assertEquals(container.get_child_refs(), ['dummy1.too'])
         
     def test_impl_container_list_output_files(self):
         container = plugin.ImplContainer("norm", None)
@@ -188,13 +216,35 @@
         subcontainer.append(imp1)
         subcontainer.append(imp2a)
         subcontainer.append(imp2b)
-        self.assertEquals(container.list_output_files(), [])
+        self.assertEquals(container.list_output_files(), ['foo/test.txt'])
         imp2b.output_files= ['output/dummy2.txt']
-        self.assertEquals(container.list_output_files(), ['output/dummy2.txt'])
+        self.assertEquals(container.list_output_files(), ['foo/test.txt', 'output/dummy2.txt'])
         imp1.output_files= ['output/foobar/hee.txt']
         self.assertEquals(container.list_output_files(), ['output/foobar/hee.txt',
+                                                          'foo/test.txt', 
                                                           'output/dummy2.txt'])
 
+    def test_impl_container_get_outputs(self):
+        container = plugin.ImplContainer("norm", None)
+        subcontainer = plugin.ImplContainer("norm", None)
+        imp1  = TestPluginImplContainer.ImplTest("implml/test.content",None)
+        imp2a = TestPluginImplContainer.ImplTest("implml/copy:21.content",None)
+        imp2b = TestPluginImplContainer.ImplTest("implml/copy:24.content",None)
+        container.append(subcontainer)
+        subcontainer.append(imp1)
+        subcontainer.append(imp2a)
+        subcontainer.append(imp2b)
+        self.assertEquals(len(container.get_outputs()), 3)
+        self.assertEquals(container.get_outputs()[0].name, 'foo/test.txt')
+        self.assertEquals(container.get_outputs()[1].name, 'foo/test.txt')
+        self.assertEquals(container.get_outputs()[2].name, 'foo/test.txt')
+        imp2b.output_files= ['foobar.txt','output/dummy2.txt']
+        self.assertEquals(len(container.get_outputs()),4)
+        self.assertEquals(container.get_outputs()[0].name, 'foo/test.txt')
+        self.assertEquals(container.get_outputs()[1].name, 'foo/test.txt')
+        self.assertEquals(container.get_outputs()[2].name, 'foobar.txt')
+
+
     def test_impl_container_set_output_root(self):
         container = plugin.ImplContainer("norm", None)
         subcontainer = plugin.ImplContainer("norm", None)
@@ -205,7 +255,7 @@
         subcontainer.append(imp1)
         subcontainer.append(imp2a)
         subcontainer.append(imp2b)
-        self.assertEquals(imp1.get_output_root(), 'output')
+        self.assertEquals(imp1.get_output_root(), '')
         container.set_output_root('foobar/test')
         self.assertEquals(imp1.get_output_root(), 'foobar/test')
 
@@ -238,13 +288,11 @@
         container.append(subcontainer)
         self.assertEquals(container.impls, [imp1,subcontainer])
         context = plugin.GenerationContext()
-        context.objects = []
         container.generate(context)
         self.assertTrue(imp1.generate_invoked)
         self.assertTrue(imp2a.generate_invoked)
         self.assertTrue(imp2a.generate_invoked)
-        self.assertEquals(len(context.objects), 3)
-        self.assertEquals(context.objects, [imp1,imp2a,imp2b])
+        self.assertEquals(sorted(context.executed_impls), sorted([imp1,imp2a,imp2b]))
 
     def test_impl_container_generate_with_generation_contexts_tags(self):
         container = plugin.ImplContainer("norm", None)
@@ -253,9 +301,10 @@
         subcontainer1.append(imp1)
         
         subcontainer2 = plugin.ImplContainer("implml/sub2.implml", None)
-        subcontainer2.set_tags({'target': ['rofs3','uda']})
         imp2a = TestPluginImplContainer.ImplTest("implml/copy:21.content",None)
+        imp2a.set_tags({'target': ['rofs3','uda']})
         imp2b = TestPluginImplContainer.ImplTest("implml/copy:24.content",None)
+        imp2b.set_tags({'target': ['rofs3','uda']})
         subcontainer2.append(imp2a)
         subcontainer2.append(imp2b)
         container.append(subcontainer1)
@@ -263,13 +312,11 @@
         
         context = plugin.GenerationContext()
         context.tags = {'target': ['rofs3'], 'foobar' :['test']}
-        context.objects = []
         container.generate(context)
         self.assertFalse(imp1.generate_invoked)
         self.assertTrue(imp2a.generate_invoked)
         self.assertTrue(imp2a.generate_invoked)
-        self.assertEquals(len(context.objects), 2)
-        self.assertEquals(context.objects, [imp2a,imp2b])
+        self.assertEquals(sorted(context.executed_impls), sorted([imp2a,imp2b]))
 
     def test_impl_container_generate_with_generation_phase(self):
         container = plugin.ImplContainer("norm", None)
@@ -278,21 +325,47 @@
         subcontainer1.append(imp1)
         
         subcontainer2 = plugin.ImplContainer("implml/sub2.implml", None)
-        subcontainer2.set_invocation_phase("post")
         imp2a = TestPluginImplContainer.ImplTest("implml/copy:21.content",None)
+        imp2a.set_invocation_phase("post")
         imp2b = TestPluginImplContainer.ImplTest("implml/copy:24.content",None)
+        imp2b.set_invocation_phase("post")
         subcontainer2.append(imp2a)
         subcontainer2.append(imp2b)
         container.append(subcontainer1)
         container.append(subcontainer2)
         
-        context = plugin.GenerationContext()
+        context = plugin.GenerationContext(output='')
         context.phase = "post"
-        context.objects = []
         container.generate(context)
         self.assertFalse(imp1.generate_invoked)
         self.assertTrue(imp2a.generate_invoked)
         self.assertTrue(imp2a.generate_invoked)
-        self.assertEquals(len(context.objects), 2)
-        self.assertEquals(context.objects, [imp2a,imp2b])
+        self.assertEquals(sorted(context.executed_impls), sorted([imp2a,imp2b]))
+        self.assertEquals(context.executed_impls[0].list_output_files(), ['foo/test.txt'])
+        self.assertEquals(len(context.generation_output), 2)
+        self.assertEquals(context.generation_output[0].name, 'foo/test.txt')
+        self.assertEquals(str(context.generation_output[0]), "GenerationOutput(foo/test.txt, ImplTest(ref='implml/copy:21.content', type=None, lineno=None))")
+        self.assertEquals(str(context.generation_output[1]), "GenerationOutput(foo/test.txt, ImplTest(ref='implml/copy:24.content', type=None, lineno=None))")
+        self.assertEquals(context.generation_output[0].implementation, imp2a)
+        
+    def test_impl_container_generate_dry_run(self):
+        container = plugin.ImplContainer("norm", None)
+        imp1  = TestPluginImplContainer.ImplTest("implml/test.content",None)
+        container.append(imp1)
+        subcontainer = plugin.ImplContainer("implml/sub.implml", None)
+        imp2a = TestPluginImplContainer.ImplTest("implml/copy:21.content",None)
+        imp2b = TestPluginImplContainer.ImplTest("implml/copy:24.content",None)
+        subcontainer.append(imp2a)
+        subcontainer.append(imp2b)
+        container.append(subcontainer)
+        self.assertEquals(container.impls, [imp1,subcontainer])
+        context = plugin.GenerationContext()
+        context.dry_run= True
+        container.generate(context)
+        self.assertFalse(imp1.generate_invoked)
+        self.assertFalse(imp2a.generate_invoked)
+        self.assertFalse(imp2a.generate_invoked)
+        self.assertEquals(sorted(context.executed_impls), sorted([imp1, imp2a,imp2b]))
+        self.assertEquals(context.executed_impls[0].list_output_files(), ['foo/test.txt'])
+        self.assertEquals(len(context.generation_output), 0)
         
\ No newline at end of file
--- a/configurationengine/source/cone/public/tests/unittest_plugin_reader.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/public/tests/unittest_plugin_reader.py	Tue Aug 10 14:29:28 2010 +0300
@@ -17,11 +17,60 @@
 import unittest
 import os
 import logging
-import __init__
+
 from cone.public import *
 from cone.public import _plugin_reader
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
 
+
+class MockImpl(plugin.ImplBase):
+    def __init__(self, data):
+        self.data = data
+        self.generate_invoked = False
+    
+    @classmethod
+    def create(cls, resource_ref, configuration, data):
+        impl = cls(data)
+        plugin.ImplBase.__init__(impl, resource_ref, configuration)
+        return impl
+    
+    def generate(self, context=None):
+        if context and hasattr(context,'objects'):
+            context.objects.append(self) 
+        self.generate_invoked = True
+    
+    def __repr__(self):
+        return "MockImpl(%r)" % self.data
+    
+    def __eq__(self, other):
+        if type(self) == type(other):
+            return self.data == other.data
+        else:
+            return False
+    
+    def __ne__(self, other):
+        return not (self == other)
+        
+    def __lt__(self, other):
+        if type(self) == type(other):
+            return self.data < other.data
+        else:
+            return False
+
+class MockReaderBase(plugin.ReaderBase):
+    @classmethod
+    def read_impl(cls, resource_ref, configuration, root_elem):
+        data = [cls.__name__, resource_ref]
+        for elem in root_elem.findall('{%s}elem' % cls.NAMESPACE):
+            data.append(elem.attrib)
+        return MockImpl.create(resource_ref, configuration, data)
+
+class MockReader(MockReaderBase):
+    NAMESPACE = "http://www.test.com/xml/1"
+    NAMESPACE_ID = "mock"
+    ROOT_ELEMENT_NAME = "impl"
+    FILE_EXTENSIONS = ['mockml']
+
 class ImplTest(plugin.ImplBase):
     def __init__(self,ref,configuration):
         plugin.ImplBase.__init__(self,ref,configuration)
@@ -47,11 +96,10 @@
 class TestCommonNamespaceHandling(unittest.TestCase):
     
     def setUp(self):
-        pass
-        
-        
+        plugin.ImplFactory.set_reader_classes_override([MockReader])
+    
     def tearDown(self):
-        pass
+        plugin.ImplFactory.set_reader_classes_override(None)
     
     def test_implcontainer_reader_get_condition(self):
         root = utils.etree.fromstring("<container/>")
@@ -81,6 +129,35 @@
             """
         container = plugin.ImplContainerReader.read_implementation(xml_data)
         self.assertTrue(isinstance(container, plugin.ImplContainer))
+    
+    def test_get_reader_for_namespace(self):
+        self.assertEquals(plugin.ReaderBase.get_reader_for_namespace('http://www.symbianfoundation.org/Foo'), None)
+        self.assertEquals(plugin.ReaderBase.get_reader_for_namespace('http://www.symbianfoundation.org/xml/implml/1'), 
+                          plugin.ImplContainerReader)
+
+    def test_read_container_via_common_readerbase(self):
+        prj = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'testdata')))
+        config = prj.create_configuration("test.confml", True)
+        container = plugin.read_impl_from_location('layer1/implml/test.implml', config, 4)
+        self.assertEquals(container.invocation_phase(), 'normal')
+        self.assertEquals(container.path, 'layer1/implml/test.implml')
+        self.assertEquals(container.lineno, 4)
+        self.assertEquals(container[0].invocation_phase(), 'normal')
+        self.assertEquals(container[0].path, 'layer1/implml/test.implml')
+        self.assertEquals(container[0].lineno, 5)
+
+
+    def test_read_containers_from_location(self):
+        prj = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'testdata')))
+        config = prj.create_configuration("test.confml", True)
+        
+        container = plugin.ImplContainerReader.read_impl_from_location('layer1/implml/test.implml', config, 4)
+        self.assertEquals(container.invocation_phase(), 'normal')
+        self.assertEquals(container.path, 'layer1/implml/test.implml')
+        self.assertEquals(container.lineno, 4)
+        self.assertEquals(container[0].invocation_phase(), 'normal')
+        self.assertEquals(container[0].path, 'layer1/implml/test.implml')
+        self.assertEquals(container[0].lineno, 5)
 
     def test_get_test_container_with_sub_containers(self):
         xml_data = """<?xml version="1.0"?>
@@ -98,35 +175,155 @@
     
     def test_containers_with_phases(self):
         xml_data = """<?xml version="1.0"?>
-            <implml:container xmlns:implml="http://www.symbianfoundation.org/xml/implml/1">
-              <implml:container />
-              <implml:container />
+            <container xmlns="http://www.symbianfoundation.org/xml/implml/1">
+              <mock xmlns="http://www.test.com/xml/1"/>
+              <container>
+                <mock xmlns="http://www.test.com/xml/1"/>
+              </container>
               <container xmlns="http://www.symbianfoundation.org/xml/implml/1">
                 <phase name="post"/>
+                <mock xmlns="http://www.test.com/xml/1"/>
               </container>
-            </implml:container>
+            </container>
             """
         container = plugin.ImplContainerReader.read_implementation(xml_data)
-        self.assertEquals(container.invocation_phase(), ['post','normal'])
-        self.assertEquals(container[2].invocation_phase(), ['post'])
+        self.assertEquals(container[0].invocation_phase(), 'normal')
+        self.assertEquals(container[1][0].invocation_phase(), 'normal')
+        self.assertEquals(container[2][0].invocation_phase(), 'post')
     
     def test_containers_with_tags(self):
         xml_data = """<?xml version="1.0"?>
             <container xmlns="http://www.symbianfoundation.org/xml/implml/1">
               <tag name="target" value="rofs2"/>
               <tag name="foobar" value="test"/>
-              <container />
-              <container />
+              
+              <container>
+                <mock xmlns="http://www.test.com/xml/1"/>
+              </container>
+              
               <container xmlns="http://www.symbianfoundation.org/xml/implml/1">
                 <tag name="target" value="rofs3"/>
-                <phase name="post"/>
+                <mock xmlns="http://www.test.com/xml/1"/>
               </container>
             </container>
             """
         container = plugin.ImplContainerReader.read_implementation(xml_data)
-        self.assertEquals(container[2].get_tags(), {'target': ['rofs3']})
-        self.assertEquals(container.get_tags(), {'target': ['rofs2','rofs3'],
-                                                 'foobar': ['test']})
+        self.assertEquals(container[0][0].get_tags(), {'target': ['rofs2'],
+                                                       'foobar': ['test']})
+        self.assertEquals(container[1][0].get_tags(), {'target': ['rofs3']})
+    
+    def test_read_container_impl_line_numbers(self):
+        xml_data = """<?xml version="1.0"?>
+            <container xmlns="http://www.symbianfoundation.org/xml/implml/1">
+                <container>
+                    <mock xmlns="http://www.test.com/xml/1"/>
+                </container>
+              
+                <container>
+                    <mock xmlns="http://www.test.com/xml/1"/>
+                    <container>
+                        <mock xmlns="http://www.test.com/xml/1"/>
+                        <mock xmlns="http://www.test.com/xml/1"/>
+                    </container>
+                </container>
+            </container>
+        """
+        container = plugin.ImplContainerReader.read_implementation(xml_data)
+        self.assertEquals(container[0].lineno, 3)
+        self.assertEquals(container[0][0].lineno, 4)
+        self.assertEquals(container[1].lineno, 7)
+        self.assertEquals(container[1][0].lineno, 8)
+        self.assertEquals(container[1][1].lineno, 9)
+        self.assertEquals(container[1][1][0].lineno, 10)
+        self.assertEquals(container[1][1][1].lineno, 11)
+    
+    def test_container_common_element_inheritance(self):
+        xml_data = """<?xml version="1.0"?>
+            <container xmlns="http://www.symbianfoundation.org/xml/implml/1">
+                
+                <!-- [0] -->
+                <mock xmlns="http://www.test.com/xml/1"/>
+                
+                <!-- [1] -->
+                <container>
+                    <tag name="target" value="rofs2"/>
+                    <tag name="target" value="rofs3"/>
+                    <tag name="foo" value="bar"/>
+                    <phase name="post"/>
+                    <settingRefsOverride>
+                        <settingRef value="Foo.Bar"/>
+                        <settingRef value="Foo.Baz"/>
+                    </settingRefsOverride>
+                    <outputRootDir value="/foo/root"/>
+                    <outputSubDir value="foosubdir"/>
+                    
+                    <!-- [1][0] -->
+                    <mock xmlns="http://www.test.com/xml/1"/>
+                    
+                    <!-- [1][1] -->
+                    <container>
+                        <!-- [1][1][0] -->
+                        <mock xmlns="http://www.test.com/xml/1"/>
+                        
+                        <!-- [1][1][1] -->
+                        <container>
+                            <!-- [1][1][1][0] -->
+                            <mock xmlns="http://www.test.com/xml/1"/>
+                        </container>
+                    </container>
+                    
+                    <!-- [1][2] -->
+                    <container>
+                        <tag name="target" value="core"/>
+                        <tag name="foo" value="baz"/>
+                        <phase name="pre"/>
+                        <settingRefsOverride refsIrrelevant="true"/>
+                        <outputRootDir value="/foo/root2"/>
+                        <outputSubDir value="foosubdir2"/>
+                        
+                        <!-- [1][2][0] -->
+                        <mock xmlns="http://www.test.com/xml/1"/>
+                        
+                        <!-- [1][2][1] -->
+                        <container>
+                            <!-- [1][2][1][0] -->
+                            <mock xmlns="http://www.test.com/xml/1"/>
+                        </container>
+                    </container>
+                </container>
+            </container>
+            """
+        container = plugin.ImplContainerReader.read_implementation(xml_data)
+        
+        # First impl, with all defaults
+        impl = container[0]
+        self.assertEquals(impl.get_tags(), {})
+        self.assertEquals(impl.invocation_phase(), 'normal')
+        self.assertEquals(impl.get_refs(), None)
+        self.assertEquals(impl.output, '')
+        
+        # The sub-container has things overridden, check that they
+        # are all inherited correctly downwards in the implementation
+        # tree
+        def assert_is_expected(impl):
+            self.assertEquals(impl.get_tags(), {'target': ['rofs2', 'rofs3'], 'foo': ['bar']})
+            self.assertEquals(impl.invocation_phase(), 'post')
+            self.assertEquals(impl.get_refs(), ['Foo.Bar', 'Foo.Baz'])
+            self.assertEquals(impl.output, '/foo/root/foosubdir')
+            self.assertEquals(impl.output_subdir, 'foosubdir')
+        assert_is_expected(container[1][0])
+        assert_is_expected(container[1][1][0])
+        assert_is_expected(container[1][1][1][0])
+        
+        # The sub-container's second sub-container has things overridden
+        # again, so check that those are correct
+        def assert_is_expected_2(impl):
+            self.assertEquals(impl.get_tags(), {'target': ['core'], 'foo': ['baz']})
+            self.assertEquals(impl.invocation_phase(), 'pre')
+            self.assertEquals(impl.get_refs(), None)
+            self.assertEquals(impl.output, '/foo/root2/foosubdir2')
+        assert_is_expected_2(container[1][2][0])
+        assert_is_expected_2(container[1][2][1][0])
 
     def test_tempfeature_definitions(self):
         xml_data = """<?xml version="1.0"?>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/tests/unittest_problem.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,63 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+import unittest
+
+
+
+from cone.public import api, exceptions
+
+class TestProblems(unittest.TestCase):
+    
+    def test_create_from_generic_exception(self):
+        ex = RuntimeError('foobar')
+        self.assertEquals(
+            api.Problem.from_exception(ex),
+            api.Problem('foobar', severity = api.Problem.SEVERITY_ERROR))
+    
+    def test_create_from_cone_exception_simple(self):
+        ex = exceptions.ConeException('foobar')
+        self.assertEquals(
+            api.Problem.from_exception(ex),
+            api.Problem('foobar',
+                        type     = '',
+                        severity = api.Problem.SEVERITY_ERROR))
+    
+    def test_create_from_cone_exception_all_attributes(self):
+        ex = exceptions.ConeException('foobar',
+                                      problem_lineno = 101,
+                                      problem_msg    = 'foobar2',
+                                      problem_type   = 'foo.bar')
+        self.assertEquals(
+            api.Problem.from_exception(ex),
+            api.Problem('foobar2',
+                        type     = 'foo.bar',
+                        line     = 101,
+                        severity = api.Problem.SEVERITY_ERROR))
+    
+    def test_create_from_xml_parse_error(self):
+        ex = exceptions.XmlParseError('XML parse error',
+                                      problem_lineno = 1)
+        self.assertEquals(
+            api.Problem.from_exception(ex),
+            api.Problem('XML parse error',
+                        type     = 'xml',
+                        line     = 1,
+                        severity = api.Problem.SEVERITY_ERROR))
+
+if __name__ == '__main__':
+    unittest.main()
+      
--- a/configurationengine/source/cone/public/tests/unittest_project.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/public/tests/unittest_project.py	Tue Aug 10 14:29:28 2010 +0300
@@ -21,10 +21,7 @@
 import string
 import sys,os,shutil
 
-import __init__
-
 from cone.public import *
-#from cone.public import stringstorage
 from cone.storage import persistentdictionary
 
 class TestProjectOpen(unittest.TestCase):    
@@ -37,7 +34,7 @@
     def test_open_project_of_non_storage(self):
         fs = ""
         try:
-            p = api.Project(fs)
+            p = api.Project("")
             self.fail("Opening on top of non storage succeeds!!")
         except exceptions.StorageException:
             self.assertTrue(True)
@@ -50,6 +47,25 @@
         self.prj.create_configuration("test.confml")
         self.assertTrue(self.prj.test_confml)
         self.assertEquals(self.prj.test_confml.get_path(),"test.confml")
+
+    def test_create_configuration_already_existing(self):
+        self.prj.create_configuration("test.confml")
+        try:
+            self.prj.create_configuration("test.confml")
+            self.fail("Succeeded to create already existing configuration")
+        except exceptions.AlreadyExists:
+            pass
+        try:
+            self.prj.add_configuration(api.Configuration("test.confml"))
+            self.fail("Succeeded to create already existing configuration")
+        except exceptions.AlreadyExists:
+            pass
+
+    def test_create_configuration_already_existing_with_overwrite(self):
+        self.prj.create_configuration("test.confml")
+        self.prj.create_configuration("test.confml", True)
+        self.prj.add_configuration(api.Configuration("test.confml"), True)
+
         
     def test_create_and_getconfiguration(self):
         self.prj.create_configuration("test.confml")
@@ -101,7 +117,10 @@
         self.prj.create_configuration("test3.confml")
         self.prj.test2_confml.create_configuration("foo/root.confml")
         conf = self.prj.test2_confml.create_configuration("fii/root.confml")
-        #self.assertEquals(conf.get_full_path(),'')
+        conf.add_configuration(api.Configuration("confml/data.confml"))
+        self.assertEquals(conf.get_full_path(),'fii/root.confml')
+        self.assertEquals(conf.get_configuration("confml/data.confml").get_path(),'confml/data.confml')
+        self.assertEquals(conf.get_configuration("confml/data.confml").get_full_path(),'fii/confml/data.confml')
         self.assertTrue(self.prj.is_configuration("test3.confml"))
         # TODO: this is not working at the moment due to performance problem in
         # Project.list_all_configurations()
@@ -110,9 +129,17 @@
         self.assertEquals(self.prj.list_configurations(), ["test1.confml",
                                                            "test2.confml",
                                                            "test3.confml"])
-        
+        self.assertEquals(self.prj.list_all_configurations(), ['test1.confml', 
+                                                               'test2.confml', 
+                                                               'foo/root.confml', 
+                                                               'fii/root.confml', 
+                                                               'fii/confml/data.confml', 
+                                                               'test3.confml'])
         self.assertEquals(self.prj.test2_confml.list_configurations(), ["foo/root.confml",
                                                                  "fii/root.confml",])
+        self.assertEquals(self.prj.test2_confml.list_all_configurations(), ["foo/root.confml",
+                                                                            "fii/root.confml",
+                                                                            "fii/confml/data.confml"])
 
     def test_create_multi_and_add_subconfigurations_and_features(self):
         self.prj.create_configuration("test1.confml")
@@ -133,7 +160,6 @@
                                                            'testfea3.testfea31', 
                                                            'testfea4'])
 
-
 class TestProjectConfigurationsStorage(unittest.TestCase):    
     def test_create_configuration_and_store_storage(self):
         prj = api.Project(api.Storage.open("temp/testproject.pk", "w"))
@@ -242,6 +268,7 @@
         prj.test_confml.include_configuration("foo/foo.confml")
         prj.test_confml.include_configuration("s60/root.confml")
         prj.test_confml.foo__foo_confml.create_configuration("data.confml")
+        prj.test_confml.foo__foo_confml.add_configuration(api.Configuration("confml/test.confml"))
         foofea = api.Feature("foofea")
         foofea.add_feature(api.Feature("foofea_setting1"))
         foofea.add_feature(api.Feature("foofea_setting2"))
@@ -255,13 +282,19 @@
         res = layer.content_folder().open_resource("foobar.txt","w")
         res.write("foo bar")
         res.close()
-        self.assertEquals(layer.list_confml(), ['confml/component.confml', 'confml/component1.confml'])
+        self.assertEquals(layer.list_confml(), ['confml/component.confml', 'confml/component1.confml', 'confml/test.confml'])
         self.assertEquals(layer.list_content(), ['content/foobar.txt'])
-        self.assertEquals(layer.list_all_resources(), ['confml/component.confml', 'confml/component1.confml', 'content/foobar.txt'])
-        self.assertEquals(foo_config.list_resources(), ['foo/foo.confml','foo/data.confml', 'foo/confml/component.confml', 'foo/confml/component1.confml', 'foo/content/foobar.txt'])
+        self.assertEquals(layer.list_all_resources(), ['confml/component.confml', 'confml/component1.confml', 'confml/test.confml', 'content/foobar.txt'])
+        self.assertEquals(foo_config.list_resources(), ['foo/foo.confml',
+                                                        'foo/data.confml', 
+                                                        'foo/confml/test.confml', 
+                                                        'foo/confml/component.confml', 
+                                                        'foo/confml/component1.confml', 
+                                                        'foo/content/foobar.txt'])
         self.assertEquals(prj.test_confml.list_resources(), ['test.confml',
                                                       'foo/foo.confml',
                                                       'foo/data.confml',
+                                                      'foo/confml/test.confml',
                                                       's60/root.confml',
                                                       'foo/confml/component.confml', 
                                                       'foo/confml/component1.confml', 
@@ -287,7 +320,6 @@
         shutil.rmtree("temp")
 
 
-
 if __name__ == '__main__':
     unittest.main()
       
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/public/tests/unittest_property.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,156 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+"""
+Test sets
+"""
+import unittest
+
+from cone.public import api,exceptions
+
+
+class TestProperty(unittest.TestCase):
+    def test_create_property(self):
+        property = api.Property(name='test',value='foo', unit='kB')
+        self.assertEquals(property.name, 'test')
+        self.assertEquals(property.value, 'foo')
+        self.assertEquals(property.unit, 'kB')
+        property.name = 'testnew'
+        property.value = 'foo faa'
+        property.unit = "MB"
+        self.assertEquals(property.name, 'testnew')
+        self.assertEquals(property.value, 'foo faa')
+        self.assertEquals(property.unit, 'MB')
+
+    def test_add_property_to_feature(self):
+        fea = api.Feature("testfea")
+        prop1 = api.Property(name='test',value='foo', unit='kB')
+        fea.add_property(prop1)
+        self.assertEquals(fea.list_properties(),['test'])
+        self.assertEquals(fea.get_property('test'),prop1)
+
+    def test_add_and_remove_property_to_feature(self):
+        fea = api.Feature("testfea")
+        prop1 = api.Property(name='test',value='foo', unit='kB')
+        fea.add_property(prop1)
+        self.assertEquals(fea.list_properties(),['test'])
+        fea.remove_property('test')
+        self.assertEquals(fea.list_properties(),[])
+
+    def test_add_property_invalid_param(self):
+        fea = api.Feature('test')
+        self.assertRaises(TypeError, fea.add_property, object())
+        
+    def test_property_compare(self):
+        elem1 = api.Property(name='test1',value='foo', unit='kB')
+        elem2 = api.Property(name='test2',value='bar', unit='MB')
+        elem3 = api.Property(name='test3',value='foobar', unit='B')
+        self.assertFalse(elem1==elem2)
+        self.assertFalse(elem1==elem3)
+
+    def test_get_property_nonexistent(self):
+        fea = api.Feature('test')
+        self.assertRaises(exceptions.NotFound, fea.get_property, 'foo')
+
+    def test_get_property_invalid_type(self):
+        fea = api.Feature('test')
+        fea.add(api.Feature('property_foo'))
+        self.assertRaises(TypeError, fea.get_property, 'foo')
+
+    def test_create_feature_with_properties(self):
+        fea = api.Feature('test')
+        prop1 = api.Property(name='test1',value='foo', unit='kB')
+        prop2 = api.Property(name='test2',value='bar', unit='MB')
+        fea.add_property(prop1)
+        fea.add(prop2)
+        self.assertEquals(fea.list_properties(), ['test1','test2'])
+        self.assertEquals(fea.property_test1.get_name(),'test1')
+        self.assertEquals(fea.property_test1.get_value(),'foo')
+        self.assertEquals(fea.property_test1.get_unit(),'kB')
+        self.assertEquals(fea.get_property('test1').get_name(),'test1')
+        self.assertEquals(fea.get_property('test1').get_value(),'foo')
+        self.assertEquals(fea.get_property('test1').get_unit(),'kB')
+        self.assertEquals(fea.property_test2.get_name(),'test2')
+        self.assertEquals(fea.property_test2.get_value(),'bar')
+        self.assertEquals(fea.property_test2.get_unit(),'MB')
+        fea.add_property(prop2)
+        self.assertEquals(fea.list_properties(), ['test1','test2'])
+
+    def test_resetting_properties(self):
+        fea = api.Feature('test')
+        prop1 = api.Property(name='test1',value='foo', unit='kB')
+        prop2 = api.Property(name='test1',value='bar', unit='MB')
+        fea.add_property(prop1)
+        self.assertEquals(fea.list_properties(), ['test1'])
+        self.assertEquals(fea.get_property('test1').get_name(),'test1')
+        self.assertEquals(fea.get_property('test1').get_value(),'foo')
+        self.assertEquals(fea.get_property('test1').get_unit(),'kB')
+        fea.add_property(prop2)
+        self.assertEquals(fea.get_property('test1').get_name(),'test1')
+        self.assertEquals(fea.get_property('test1').get_value(),'bar')
+        self.assertEquals(fea.get_property('test1').get_unit(),'MB')
+        self.assertEquals(fea.list_properties(), ['test1'])
+
+    def test_adding_and_removing_multiple_properties(self):
+        fea = api.Feature('test')
+        prop1 = api.Property(name='test1',value='foo', unit='kB')
+        prop2 = api.Property(name='test2',value='bar1', unit='MB1')
+        prop3 = api.Property(name='test3',value='bar2', unit='MB2')
+        
+        self.assertEquals(fea.list_properties(), [])
+        
+        fea.add_property(prop1)
+        self.assertEquals(fea.list_properties(), ['test1'])
+        
+        fea.add_property(prop2)
+        self.assertEquals(fea.list_properties(), ['test1', 'test2'])
+
+        fea.add_property(prop3)
+        self.assertEquals(fea.list_properties(), ['test1', 'test2', 'test3'])
+        self.assertEquals(fea.get_property('test1').get_name(),'test1')
+        self.assertEquals(fea.get_property('test1').get_value(),'foo')
+        self.assertEquals(fea.get_property('test1').get_unit(),'kB')
+        self.assertEquals(fea.get_property('test2').get_name(),'test2')
+        self.assertEquals(fea.get_property('test2').get_value(),'bar1')
+        self.assertEquals(fea.get_property('test2').get_unit(),'MB1')
+        self.assertEquals(fea.get_property('test3').get_name(),'test3')
+        self.assertEquals(fea.get_property('test3').get_value(),'bar2')
+        self.assertEquals(fea.get_property('test3').get_unit(),'MB2')
+
+        fea.remove_property('test2')
+        self.assertEquals(fea.list_properties(), ['test1', 'test3'])
+
+        fea.remove_property('test3')
+        self.assertEquals(fea.list_properties(), ['test1'])
+
+        fea.remove_property('test1')
+        self.assertEquals(fea.list_properties(), [])
+
+    def test_remove_property_nonexistent(self):
+        fea = api.Feature('test')
+        self.assertRaises(exceptions.NotFound, fea.remove_property, 'nonexisting')
+    
+    def test_remove_property_invalid_param(self):
+        fea = api.Feature('test')
+        fea.add(api.Feature('property_xyz'))
+        self.assertRaises(TypeError, fea.remove_property, 'xyz')
+        
+    def test_create_property_without_name(self):
+        try:
+            api.Property(name=None, value='foo', unit='kB')
+        except ValueError:
+            return #ValueError expected
+        self.fail("ValueError expected.")
--- a/configurationengine/source/cone/public/tests/unittest_public_api.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/public/tests/unittest_public_api.py	Tue Aug 10 14:29:28 2010 +0300
@@ -16,7 +16,7 @@
 
 import unittest
 import os
-import __init__
+
 from cone.public import *
 
 class TestPublicApiConfiguration(unittest.TestCase):
--- a/configurationengine/source/cone/public/tests/unittest_rules.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/public/tests/unittest_rules.py	Tue Aug 10 14:29:28 2010 +0300
@@ -16,25 +16,21 @@
 #
 
 import unittest
-import sys, os
-import __init__
 
-from cone.public.api import CompositeConfiguration, Feature
-from cone.public.rules import ASTInterpreter, RelationContainerImpl, RELATIONS, get_tokens
-from cone.public.rules import ParseException, DefaultContext, BaseRelation, RequireExpression, OPERATORS
+from cone.public import rules
 
 #### TEST RELATIONS ####
 
-AA_BA = 'a.a require b.b'
-AB_BB = 'a.b require b.b'
-BA_CA = 'b.a require c.a and c.b and a.b'
+AA_BA = '${a.a} require ${b.b}'
+AB_BB = '${a.b} require ${b.b}'
+BA_CA = '${b.a} require ${c.a} and ${c.b} and ${a.b}'
 
-CB_DA = 'c.b require d.a'
-DA_DB = 'd.a require d.b'
+CB_DA = '${c.b} require ${d.a}'
+DA_DB = '${d.a} require ${d.b}'
 
-AC_AB_BA = 'a.c and a.a require b.a'
+AC_AB_BA = '${a.c} and ${a.a} require ${b.a}'
 
-EA_FSTAR = 'e.a require f.*'
+EA_FSTAR = '${e.a} require ${f.*}'
 
 TEST_RELATIONS = {
     'a.a' : [AA_BA],
@@ -46,18 +42,21 @@
     'e.a' : [EA_FSTAR]
 }
 
+#rules.RELATIONS[rules.BaseRelation.KEY] = rules.BaseRelation
+#rules.OPERATORS[rules.BaseRelation.KEY] = rules.BaseRelation
+
 class DummyRelationFactory():
     def get_relations_for(self, configuration, ref):
         rels = TEST_RELATIONS.get(ref)
 
         if rels:
-            relation_container = RelationContainerImpl()
+            relation_container = rules.RelationContainerImpl()
             for rel in rels:
                 rel_s = rel.split(' ')
                 from_ref = rel_s[0]
                 relation_name = 'require'
                 to_ref = ' '.join(rel_s[2:])
-                relation = RELATIONS.get(relation_name)(configuration, from_ref, to_ref)
+                relation = rules.RELATIONS.get(relation_name)(configuration, from_ref, to_ref)
                 relation_container.add_relation(relation)
                 propagated_relations = self.get_relations_for(configuration, to_ref)
                 if propagated_relations:
@@ -82,11 +81,25 @@
     def get_feature(self, ref):
         return DummyConfiguration.VALUES.get(ref, False)
 
-class DummyContext(DefaultContext):
+class DummyContext(rules.DefaultContext):
     def handle_terminal(self, expression):
         return DummyConfiguration.VALUES.get(expression, False)
 
-class DummyBaseRelation(BaseRelation):
+class DictContext(rules.DefaultContext):    
+    def handle_terminal(self, expression):
+        return self.data.get(expression, None)
+
+    def convert_value(self, value):
+        if isinstance(value, (str, unicode)):
+            return eval(value)
+        else:
+            return value
+        
+    def set(self, expression, value):
+        self.data[expression] =  value
+        
+
+class DummyBaseRelation(rules.BaseRelation):
     def __init__(self, data, left, right):
         self.context = DummyContext(data)
         super(DummyBaseRelation, self).__init__(data, left, right)
@@ -98,8 +111,8 @@
         self.context = DummyContext(data)
         super(DummyRequireRelation, self).__init__(data, left, right)
 
-RELATIONS[DummyRequireRelation.KEY] = DummyRequireRelation
-OPERATORS['require'] = RequireExpression
+rules.RELATIONS[DummyRequireRelation.KEY] = DummyRequireRelation
+rules.OPERATORS['require'] = rules.RequireExpression
 multilines = \
 """
 APs.AP configures KCRUidCommsDatCreator.KCommsDatCreatorInputFileName = 'VariantData_commsdat.xml' and
@@ -141,7 +154,7 @@
         factory = DummyRelationFactory()
         rels = factory.get_relations_for(self.configuration, 'c.b')
         ret = rels.execute()
-        self.assertFalse(ret)
+        self.assertTrue(ret)
 
     def test_two_on_the_left(self):
         factory = DummyRelationFactory()
@@ -149,46 +162,176 @@
         ret = rels.execute()
         self.assertTrue(ret)
 
+class TestExpressions(unittest.TestCase):
+    def test_one_param_expression(self):
+        exp = rules.OneParamExpression(None, rules.ValueTerminal(None, "10"))
+        c = DictContext({})
+        self.assertEquals(exp.eval(c), 10)
+        exp = rules.OneParamExpression(None, rules.ReferenceTerminal(None, "${foo}"))
+        c = DictContext({'foo' : 'Foo string'})
+        self.assertEquals(exp.eval(c), 'Foo string')
+        
+    def test_neg_expression(self):
+        exp = rules.NegExpression(None, rules.ValueTerminal(None, "10"))
+        c = DictContext({})
+        self.assertEquals(exp.eval(c), -10)
+        exp = rules.NegExpression(None, rules.ReferenceTerminal(None, "${foo}"))
+        c = DictContext({'foo' : 2})
+        self.assertEquals(exp.eval(c), -2)
+
+    def test_and_expression(self):
+        exp = rules.AndExpression(None, rules.ValueTerminal(None, True),
+                                  rules.ReferenceTerminal(None, "${foo}"))
+        c = DictContext({'foo' : 1})
+        self.assertEquals(exp.eval(c), True)
+        c = DictContext({'foo' : 0})
+        self.assertEquals(exp.eval(c), False)
+        c = DictContext({'foo' : ""})
+        self.assertEquals(exp.eval(c), False)
+        c = DictContext({'foo' : False})
+        self.assertEquals(exp.eval(c), False)
+        c = DictContext({'foo' : True})
+        self.assertEquals(exp.eval(c), True)
+
+    def test_minus_expression(self):
+        exp = rules.MinusExpression(None, rules.ValueTerminal(None, "10"), rules.ReferenceTerminal(None, "${foo}"))
+        c = DictContext({'foo' : 10})
+        self.assertEquals(exp.eval(c), 0)
+
+    def test_plus_expression(self):
+        exp = rules.PlusExpression(None, rules.ValueTerminal(None, "10"), rules.ReferenceTerminal(None, "${foo}"))
+        c = DictContext({'foo' : 10})
+        self.assertEquals(exp.eval(c), 20)
+
+    def test_mul_expression(self):
+        exp = rules.MultiplyExpression(None, rules.ValueTerminal(None, "10"), rules.ReferenceTerminal(None, "${foo}"))
+        c = DictContext({'foo' : 10})
+        self.assertEquals(exp.eval(c), 100)
+
+    def test_div_expression(self):
+        exp = rules.DivideExpression(None, rules.ValueTerminal(None, "10"), rules.ReferenceTerminal(None, "${foo}"))
+        c = DictContext({'foo' : 10}) 
+        self.assertEquals(exp.eval(c), 1)
+
+    def test_get_expressions_from_relation(self):
+        rel = rules.RequireRelation(None,"${foo} == True","${test} = 2 and ${aaa} == ${bbb}")
+        self.assertEquals(len(rel.get_expressions()), 11)
+
+    def test_get_refs_from_relation(self):
+        rel = rules.BaseRelation(None,"${foo} == True","${test} = 2 and ${aaa} == ${bbb}")
+        self.assertEquals(rel.get_refs(), ['foo'])
+
+    def test_set_expression(self):
+        exp = rules.SetExpression(None,rules.ReferenceTerminal(None, "${t}"),  rules.ValueTerminal(None, "10"))
+        c = DictContext({'foo' : 10, 't' :None}) 
+        self.assertEquals(exp.eval(c), True)
+        self.assertEquals(c.data['t'], 10)
+
+    def test_set_expression_in_relation(self):
+        rel = rules.RequireRelation(None,"1","${test} = 1")        
+        c = DictContext({'test' : None, 't' :None})
+        rel.execute(c) 
+        self.assertEquals(c.data['test'], 1)
+        rel = rules.RequireRelation(None,"1","${test} = 2 and ${t} = 3")
+        rel.execute(c) 
+        self.assertEquals(c.data['test'], 2)
+        self.assertEquals(c.data['t'], 3)
+
+    def test_set_expression_in_relation_and_get_set_elements(self):
+        rel = rules.RequireRelation(None,"1","${test} = 2")        
+        self.assertEquals(rel.get_set_expressions()[0].left.get_ref(), 'test')
+
+        rel = rules.RequireRelation(None,"1","${test} = 2 and ${t} = 3")
+        self.assertEquals(len(rel.get_set_expressions()), 2)
+        self.assertEquals(rel.get_set_expressions()[0].left.get_ref(), 'test')
+        self.assertEquals(rel.get_set_expressions()[1].left.get_ref(), 't')
+
+    def test_set_expression_in_relation_and_get_refs(self):
+        rel = rules.RequireRelation(None,"${foo}","${test} = 2")
+        self.assertEquals(rel.get_refs(), ['foo'])
+        rel = rules.RequireRelation(None,"${foo}","${test} = 2 and ${t} = 3")
+        self.assertEquals(rel.get_refs(), ['foo'])
+
+    def test_set_expression_in_relation_and_get_set_refs(self):
+        rel = rules.RequireRelation(None,"1","${test} = 2")
+        self.assertEquals(rel.get_set_refs(), ['test'])
+
+        rel = rules.RequireRelation(None,"1","${test} = 2 and ${t} = 3")
+        self.assertEquals(rel.get_set_refs(),['test','t'])
+
+    def test_set_expression_in_relation_with_string(self):
+        rel = rules.RequireRelation(None,"1",'${test} = "foo "')
+        c = DictContext({'test' : None, 't' :None})
+        rel.execute(c) 
+        self.assertEquals(c.data['test'], 'foo ')
+
+    def test_set_expression_in_relation_with_string_concat(self):
+        rel = rules.RequireRelation(None,"1",'${test} = "foo " + "bar"')
+        c = DictContext({'test' : None, 't' :None})
+        rel.execute(c) 
+        self.assertEquals(c.data['test'], 'foo bar')
+
+    def test_set_expression_in_relation_with_ref_concat(self):
+        rel = rules.RequireRelation(None,"1",'${test} = ${s1} + " " + u"bar" + ${s2}')
+        c = DictContext({'test' : None, 's1' : 'test', 's2' : 'one'})
+        rel.execute(c) 
+        self.assertEquals(c.data['test'], 'test barone')
+
+class TestRuleUtils(unittest.TestCase):
+    def test_is_str_literal(self):
+        self.assertEquals(rules.is_str_literal(1), False)
+        self.assertEquals(rules.is_str_literal([]), False)
+        self.assertEquals(rules.is_str_literal("foo"), False)
+        self.assertEquals(rules.is_str_literal("'foo'"), True)
+        self.assertEquals(rules.is_str_literal('foo'), False)
+        self.assertEquals(rules.is_str_literal('"foo bar"'), True)
+
+    def test_get_str_literal(self):
+        self.assertEquals(rules.get_str_literal(1), None)
+        self.assertEquals(rules.get_str_literal([]), None)
+        self.assertEquals(rules.get_str_literal("foo"), None)
+        self.assertEquals(rules.get_str_literal("'foo'"), 'foo')
+        self.assertEquals(rules.get_str_literal('foo'), None)
+        self.assertEquals(rules.get_str_literal('"foo bar"'), 'foo bar')
 
 class TestASTInterpreter(unittest.TestCase):
     def test_require(self):
-        ip = ASTInterpreter('a excludes b require 0')
+        ip = rules.ASTInterpreter('a excludes b require 0')
         ret = ip.eval()
 
     def test_get_tokens(self):
-        self.assertEquals(get_tokens("foo=(2+1) * 3"),['foo','=','(','2','+','1',')','*','3'])
-        self.assertEquals(get_tokens("Arithmetic.MixedResult3 = (Arithmetic.Value2 / 2 + Arithmetic.Value1 * 9) - 7"),['Arithmetic.MixedResult3', '=', '(', 'Arithmetic.Value2', '/', '2', '+', 'Arithmetic.Value1', '*', '9', ')', '-', '7'])
-        print get_tokens(multilines)
-        self.assertEquals(len(get_tokens(multilines)),25)
+        self.assertEquals(rules.get_tokens("foo=(2+1) * 3"),['foo','=','(','2','+','1',')','*','3'])
+        self.assertEquals(rules.get_tokens("Arithmetic.MixedResult3 = (Arithmetic.Value2 / 2 + Arithmetic.Value1 * 9) - 7"),['Arithmetic.MixedResult3', '=', '(', 'Arithmetic.Value2', '/', '2', '+', 'Arithmetic.Value1', '*', '9', ')', '-', '7'])
+        self.assertEquals(len(rules.get_tokens(multilines)),25)
     
     def test_get_unindented_multiline_tokens(self):
         self.assertEquals(
-            get_tokens("foo = 2+bar\nand foobar = 3 and\nfubar=4"),
+            rules.get_tokens("foo = 2+bar\nand foobar = 3 and\nfubar=4"),
             ['foo', '=', '2', '+', 'bar', 'and', 'foobar', '=', '3', 'and', 'fubar', '=', '4'])
     
     def test_get_tab_separated_tokens(self):
         self.assertEquals(
-            get_tokens("foo\tconfigures\t\tbar\t=\t5"),
+            rules.get_tokens("foo\tconfigures\t\tbar\t=\t5"),
             ['foo', 'configures', 'bar', '=', '5'])
 
     def test_get_unicode_tokens(self):
         self.assertEquals(
-            get_tokens(u'xÿz configures xzÿ = ÿxá'),
+            rules.get_tokens(u'xÿz configures xzÿ = ÿxá'),
             [u'xÿz', 'configures', u'xzÿ', '=', u'ÿxá'])
     
     def test_get_unicode_tokens_2(self):
         self.assertEquals(
-            get_tokens(u'ελληνικά configures ünicode = u"test string" + ελληνικά'),
+            rules.get_tokens(u'ελληνικά configures ünicode = u"test string" + ελληνικά'),
             [u'ελληνικά', 'configures', u'ünicode', '=', 'u"test string"', '+', u'ελληνικά'])
     
     def test_get_unicode_tokens_3(self):
         self.assertEquals(
-            get_tokens(u'oöoä äöoö oöo öoö äaäa'),
+            rules.get_tokens(u'oöoä äöoö oöo öoö äaäa'),
             [u'oöoä', u'äöoö', u'oöo', u'öoö', u'äaäa'])
     
     def test_get_unicode_tokens_4(self):
         self.assertEquals(
-            get_tokens(u'ünicode.rêf1 require rêf2 . ελληνικά'),
+            rules.get_tokens(u'ünicode.rêf1 require rêf2 . ελληνικά'),
             [u'ünicode.rêf1', u'require', u'rêf2.ελληνικά'])
     
     def test_get_unicode_tokens_multiline(self):
@@ -201,7 +344,7 @@
             u'xÿz', 'configures', u'xzÿ', '=', u'ÿxá',
             u'ελληνικά', 'configures', u'ünicode', '=', 'u"test string"', '+', u'ελληνικά',
         ]
-        actual = get_tokens(tokenstr)
+        actual = rules.get_tokens(tokenstr)
         self.assertEquals(actual, expected, '\n%r \n!= \n%r' % (actual, expected))
     
     def test_multiline_string(self):
@@ -212,30 +355,30 @@
 """
         '''
         expected = ['"""\ntes-\nti\n"""']
-        self.assertEquals(get_tokens(tokenstr), expected)
+        self.assertEquals(rules.get_tokens(tokenstr), expected)
 
     def test_syntax_error(self):
         try:
-            ip = ASTInterpreter('a and and')
+            ip = rules.ASTInterpreter('a and and')
             self.assertTrue(False)
-        except ParseException:
+        except rules.ParseException:
             self.assertTrue(True)
 
     def test_empty_expression(self):
         expression = ''
-        ip = ASTInterpreter(expression)
+        ip = rules.ASTInterpreter(expression)
         result = ip.eval()
         self.assertFalse(result)
 
     def test_no_expression(self):
-        ip = ASTInterpreter()
+        ip = rules.ASTInterpreter()
         result = ip.eval()
         self.assertFalse(result)       
 
         try:
             ip.create_ast(None)
             self.assertFalse(True)
-        except ParseException:
+        except rules.ParseException:
             self.assertTrue(True)
 
         ip.create_ast('1 and 1')
@@ -243,7 +386,7 @@
         self.assertTrue(result)       
 
     def test_one_param_ops(self):
-        ip = ASTInterpreter('1 and truth 1')
+        ip = rules.ASTInterpreter('1 and truth 1')
         result = ip.eval()
         self.assertTrue(result)
         
@@ -257,18 +400,24 @@
 
     def test_infix_to_postfix(self):
         expression = '1 and not 1'
-        ip = ASTInterpreter(expression)
+        ip = rules.ASTInterpreter(expression)
         self.assertEqual(ip.postfix_array, ['1', '1', 'not', 'and'])
         self.assertFalse(ip.eval())
 
+    def test_infix_to_postfix_with_minus(self):
+        expression = '1 - 1'
+        ip = rules.ASTInterpreter(expression)
+        self.assertEqual(ip.postfix_array, ['1', '1', '-'])
+        self.assertFalse(ip.eval())
+
     def test_infix_to_postfix_pars(self):
         expression = '1 and ( 0 or 1 and 1 )'
-        ip = ASTInterpreter(expression)
+        ip = rules.ASTInterpreter(expression)
         self.assertEqual(ip.postfix_array, ['1', '0', '1', 'or', '1', 'and', 'and'])
         self.assertTrue(ip.eval())
 
     def test_not(self):
-        ip = ASTInterpreter(u'not 1',)
+        ip = rules.ASTInterpreter(u'not 1',)
         ret = ip.eval()
         self.assertFalse(ret)
 
@@ -281,7 +430,7 @@
         self.assertFalse(ret)
 
     def test_not_with_multiple(self):
-        ip = ASTInterpreter(u'1 and not 0')
+        ip = rules.ASTInterpreter(u'1 and not 0')
         ret = ip.eval()
         self.assertTrue(ret)
         ip.create_ast(u'1 and not 1')
@@ -289,7 +438,7 @@
         self.assertFalse(ret)
 
     def test_and(self):
-        ip = ASTInterpreter(u'1 and 1 and 0')
+        ip = rules.ASTInterpreter(u'1 and 1 and 0')
         ret = ip.eval()
         self.assertFalse(ret)
 
@@ -298,7 +447,7 @@
         self.assertTrue(ret)
 
     def test_nand(self):
-        ip = ASTInterpreter(u'1 nand 1 nand 1')
+        ip = rules.ASTInterpreter(u'1 nand 1 nand 1')
         ret = ip.eval()
         self.assertTrue(ret)
 
@@ -315,7 +464,7 @@
         self.assertTrue(ret)
 
     def test_or(self):
-        ip = ASTInterpreter(u'1 or 1 or 0')
+        ip = rules.ASTInterpreter(u'1 or 1 or 0')
         ret = ip.eval()
         self.assertTrue(ret)
 
@@ -325,7 +474,7 @@
         and the rule evaluation should fail, the exclude rule should
         evaluate if PostfixRuleEngine.eval(expression) -> return False
         """
-        ip = ASTInterpreter(u'1 or 1 or 1')
+        ip = rules.ASTInterpreter(u'1 or 1 or 1')
         ret = ip.eval()
         self.assertTrue(ret)
 
@@ -354,7 +503,7 @@
         self.assertFalse(ret)
 
     def test_nor(self):
-        ip = ASTInterpreter(u'1 nor 1 nor 1')
+        ip = rules.ASTInterpreter(u'1 nor 1 nor 1')
         ret = ip.eval()
         self.assertFalse(ret)
 
@@ -372,7 +521,7 @@
 
 
     def test_xor(self):
-        ip = ASTInterpreter(u'1 xor 1')
+        ip = rules.ASTInterpreter(u'1 xor 1')
         ret = ip.eval()
         self.assertFalse(ret)
 
@@ -381,7 +530,7 @@
         self.assertTrue(ret)  
 
     def test_eq_cmp(self):
-        ip = ASTInterpreter(u'1 == 0')
+        ip = rules.ASTInterpreter(u'1 == 0')
         ret = ip.eval()
         self.assertFalse(ret)
         
@@ -398,7 +547,7 @@
         self.assertFalse(ret)
 
     def test_neq_cmp(self):
-        ip = ASTInterpreter(u'1 != 1')
+        ip = rules.ASTInterpreter(u'1 != 1')
         ret = ip.eval()
         self.assertFalse(ret)
 
@@ -407,15 +556,15 @@
         self.assertTrue(ret)   
 
     def test_lt_cmp(self):
-        ip = ASTInterpreter(u'0 < 1')
+        ip = rules.ASTInterpreter(u'0 < 1')
         ret = ip.eval()
         self.assertTrue(ret)
 
-        ip.create_ast(u'-1 < 1')
+        ip.create_ast(u'0-1 < 1')
         ret = ip.eval()
         self.assertTrue(ret)
 
-        ip.create_ast(u'-1 < -2')
+        ip.create_ast(u'0-1 < 0-2')
         ret = ip.eval()
         self.assertFalse(ret)
 
@@ -424,7 +573,7 @@
         self.assertFalse(ret)
 
     def test_gt_cmp(self):
-        ip = ASTInterpreter(u'0 > -1')
+        ip = rules.ASTInterpreter(u'0 > 0-1')
         ret = ip.eval()
         self.assertTrue(ret)
 
@@ -436,12 +585,12 @@
         ret = ip.eval()
         self.assertFalse(ret)
 
-        ip.create_ast(u'-1 > 1')
+        ip.create_ast(u'0-1 > 1')
         ret = ip.eval()
         self.assertFalse(ret)
 
     def test_lte_cmp(self):
-        ip = ASTInterpreter(u'0 <= 1')
+        ip = rules.ASTInterpreter(u'0 <= 1')
         ret = ip.eval()
         self.assertTrue(ret)
 
@@ -454,7 +603,7 @@
         self.assertFalse(ret)
 
     def test_gte_cmp(self):
-        ip = ASTInterpreter(u'1 >= 0')
+        ip = rules.ASTInterpreter(u'1 >= 0')
         ret = ip.eval()
         self.assertTrue(ret)
 
@@ -465,9 +614,9 @@
         ip.create_ast(u'0 >= 1')
         ret = ip.eval()
         self.assertFalse(ret)
-
+ 
     def test_extract_refs(self):
-        refs = ASTInterpreter.extract_refs('a.a and ( b.c and d.e )')
+        refs = rules.ASTInterpreter.extract_refs('${a.a} and ( ${b.c} and ${d.e} )')
         self.assertTrue('a.a' in refs)
         self.assertTrue('b.c' in refs)
         self.assertTrue('d.e' in refs)
@@ -476,7 +625,7 @@
     def test_one_of(self):
         """ Test for showing that relation one-of is basically "LEFT and R1 xor R2"
         """
-        ip = ASTInterpreter(u'1 and 1 and 1 xor 0')
+        ip = rules.ASTInterpreter(u'1 and 1 and 1 xor 0')
         ret = ip.eval()
         self.assertTrue(ret)
 
--- a/configurationengine/source/cone/public/tests/unittest_rules_on_configuration.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/public/tests/unittest_rules_on_configuration.py	Tue Aug 10 14:29:28 2010 +0300
@@ -14,33 +14,28 @@
 # Description: 
 #
 
-import operator as ops
 import unittest
-import sys, os
-import __init__
-import tokenize
-import StringIO
 
-from cone.public import api,exceptions, utils
-from cone.public.rules import ASTInterpreter, RelationContainerImpl
-from cone.public.rules import ParseException, DefaultContext, BaseRelation
+from cone.public import api,exceptions, plugin
+from cone.public.rules import RelationContainerImpl
+from cone.public.rules import DefaultContext, BaseRelation
 from cone.public import rules
 
 #### TEST RELATIONS ####
 
-AA_BA = 'a.a == "foo" requires b.b != 0'
-AB_BB = 'a.b configures b.b = a.b+":"+ "test"'
-BA_CA = 'b.a requires c.a and c.b and a.b'
+AA_BA = '${a.a} == "foo" requires ${b.b} != 0'
+AB_BB = '${a.b} configures ${b.b} = ${a.b}+":"+ "test"'
+BA_CA = '${b.a} requires ${c.a} and ${c.b} and ${a.b}'
 
-CB_DA = 'c.b requires d.a'
-DA_DB = 'd.a requires d.b'
+CB_DA = '${c.b} requires ${d.a}'
+DA_DB = '${d.a} requires ${d.b}'
 
-AC_AB_BA = 'a.c and a.a requires b.a'
+AC_AB_BA = '${a.c} and ${a.a} requires ${b.a}'
 
-EA_FSTAR = 'e.a requires f.*'
+EA_FSTAR = '${e.a} requires ${f.*}'
 
 TEST_RELATIONS = {
-    'a.a' : [AA_BA, 'a.a == "test" requires b.a'],
+    'a.a' : [AA_BA, '${a.a} == "test" requires ${b.a}'],
     'a.b' : [AB_BB],
     'a.c' : [AC_AB_BA],
     'b.a' : [BA_CA],
@@ -132,27 +127,40 @@
                 return eval(expression)
             except (NameError,SyntaxError), e:
                 return expression
-
+    
+    def convert_value(self, value):
+        try:
+            # Handle some special literals
+            if value == 'true':     return True
+            if value == 'false':    return False
+            if value == 'none':     return None
+            
+            # Values can be any Python literals, so eval() the string to
+            # get the value
+            return eval(value)
+        except Exception:
+            raise RuntimeError("Could not evaluate '%s'" % value)
+    
     def eval(self, ast, expression, value):
         #print "expression %s = %s" % (expression,value)
         pass
         
 class ConfigurationBaseRelation(BaseRelation):
     def __init__(self, data, left, right):
-        self.context = ConfigurationContext(data)
+        self.context = None
         super(ConfigurationBaseRelation, self).__init__(data, left, right)
 
 class RequireRelation(ConfigurationBaseRelation):
     KEY = 'requires'
     def __init__(self, data, left, right):
         super(RequireRelation, self).__init__(data, left, right)
-        self.context = ConfigurationContext(data)
+        self.context = None
 
 class ConfigureRelation(ConfigurationBaseRelation):
     KEY = 'configures'
     def __init__(self, data, left, right):
         super(ConfigureRelation, self).__init__(data, left, right)
-        self.context = ConfigurationContext(data)
+        self.context = None
 
 def handle_configure(self, left, right):
     if left and right:
@@ -169,8 +177,8 @@
     KEY = 'configures'
     OP = handle_configure
 
-    def eval(self, context):
-        super(ConfigureExpression, self).eval(context)
+    def eval(self, context, **kwargs):
+        super(ConfigureExpression, self).eval(context, **kwargs)
         if not self.value:
             left_keys = []
             for ref in self.ast.extract_refs(str(self.left)):
@@ -193,20 +201,6 @@
     KEY= '+'
     OP = handle_plus
 
-
-class SetExpression(rules.TwoOperatorExpression):
-    PRECEDENCE = rules.PRECEDENCES['SET_OPERATORS']
-    KEY= '='
-    OP = handle_set
-
-    def eval(self, context):
-        try:
-            variable = context.data.get_feature(self.left.expression)
-            variable.set_value(self.right.eval(context))
-            return True
-        except exceptions.NotFound:
-            return False
-
 class TestRelations(unittest.TestCase):
 
     def setUp(self):
@@ -223,7 +217,6 @@
         rules.RELATIONS[ConfigureRelation.KEY] = ConfigureRelation
         rules.OPERATORS[ConfigureExpression.KEY] = ConfigureExpression
         rules.OPERATORS[ConcatExpression.KEY] = ConcatExpression
-        rules.OPERATORS[SetExpression.KEY] = SetExpression
     
     def tearDown(self):
         rules.RELATIONS = self.RELATIONS_BACKUP
@@ -237,15 +230,6 @@
         rels = factory.get_relations_for(self.configuration, 'a.a')
         ret= rels.execute()
         self.assertTrue(ret)
-
-    def test_has_ref(self):
-        """
-        Tests the relation and relation container
-        """
-        factory = TestFactory()
-        rels = factory.get_relations_for(self.configuration, 'a.a')
-        ret= rels.execute()
-        self.assertTrue(ret)
         
     def test_not_has_ref(self):
         factory = TestFactory()
@@ -257,7 +241,8 @@
     def test_not_has_ref_in_container(self):
         factory = TestFactory()
         rels = factory.get_relations_for(self.configuration, 'c.b')
-        ret = rels.execute()
+        context = plugin.GenerationContext(configuration=self.configuration)
+        ret = rels.execute(context)
         self.assertFalse(ret)
 
     def test_two_on_the_left(self):
@@ -269,9 +254,16 @@
     def test_configure_right_side(self):
         factory = TestFactory()
         rels = factory.get_relations_for(self.configuration, 'a.b')
-        ret = rels.execute()
+        context = plugin.GenerationContext(configuration=self.configuration)
+        ret = rels.execute(context)
         self.assertTrue(ret)
         self.assertEquals(self.configuration.get_default_view().get_feature('b.b').get_value(),'hey:test')
 
+    def test_get_refs_from_relation(self):
+        factory = TestFactory()
+        rels = factory.get_relations_for(self.configuration, 'a.b')
+        self.assertEquals(rels.value_list[0].get_refs(), [u'a.b'])
+        self.assertEquals(rels.value_list[0].get_set_refs(), [u'b.b'])
+
 if __name__ == '__main__':
     unittest.main()
--- a/configurationengine/source/cone/public/tests/unittest_rules_simplecondition.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/public/tests/unittest_rules_simplecondition.py	Tue Aug 10 14:29:28 2010 +0300
@@ -18,11 +18,13 @@
 import os
 import re
 import logging
-import __init__
+
 from cone.public import *
+from cone.public.rules import DefaultContext, ASTInterpreter
+from cone.confml import model 
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
 
-class TestContext(object):
+class TestContext(DefaultContext):
     """ DefaultContext implements ConE specific context for handling rules
     """
     def __init__(self, data):
@@ -39,23 +41,14 @@
         pass
 
     def handle_terminal(self, expression):
-        try:
-            m = re.match("\${(.*)}", expression)
-            if m:
-                return self.data[m.group(1)]
-            elif expression in ['true','1','True']:
-                return True
-            elif expression in ['false','0','False']:
-                return False
-            else:
-                return eval(expression)
-        except:
-            return expression
+        return self.data[expression]
 
 class TestPluginCondition(unittest.TestCase):
     
     def test_create_plugin_condition(self):
-        condition = rules.SimpleCondition("foo.bar", "True")
+        condition = rules.SimpleCondition("${foo.bar}", "True")
+        self.assertTrue(isinstance(condition.left, rules.ReferenceTerminal))
+        self.assertEquals(str(condition),'(${foo.bar} => None) == True')
 
     def test_create_plugin_and_eval_booleans(self):
         context = TestContext(None)
@@ -63,6 +56,235 @@
         self.assertTrue(condition.eval(context))
         condition = rules.SimpleCondition("0", True)
         self.assertFalse(condition.eval(context))
+    
+    def test_create_plugin_and_eval_none(self):
+        context = TestContext(None)
+        condition = rules.SimpleCondition("None", "None")
+        self.assertTrue(condition.eval(context))
+        condition = rules.SimpleCondition("None", None)
+        self.assertTrue(condition.eval(context))
+        condition = rules.SimpleCondition(None, "None")
+        self.assertTrue(condition.eval(context))
+        condition = rules.SimpleCondition(None, None)
+        self.assertTrue(condition.eval(context))
+        
+        condition = rules.SimpleCondition("True", None)
+        self.assertFalse(condition.eval(context))
+        condition = rules.SimpleCondition(None, "True")
+        self.assertFalse(condition.eval(context))
+    
+    def test_create_plugin_and_eval_none_from_ref(self):
+        context = TestContext({'Foo.Bar': None})
+        condition = rules.SimpleCondition("${Foo.Bar}", None)
+        self.assertTrue(condition.eval(context))
+    
+    def test_create_plugin_and_eval_unicode(self):
+        context = TestContext({'Foo.Bar': u"foo\u20ac"})
+        condition = rules.SimpleCondition("${Foo.Bar}", u"foo\u20ac")
+        self.assertTrue(condition.eval(context))
+    
+    def test_create_plugin_and_eval_number_against_string(self):
+        context = TestContext({'Foo.Int': 123,
+                               'Foo.Real': 123.4})
+        condition = rules.SimpleCondition("${Foo.Int}", "foo")
+        self.assertFalse(condition.eval(context))
+        condition = rules.SimpleCondition("${Foo.Real}", "foo")
+        self.assertFalse(condition.eval(context))
+        
+        condition = rules.SimpleCondition("${Foo.Int}", "123")
+        self.assertTrue(condition.eval(context))
+        condition = rules.SimpleCondition("${Foo.Real}", "123.4")
+        self.assertTrue(condition.eval(context))
+
+    def xtest_selection_setting(self):
+        conf =  api.Configuration("test.confml", namespace="com.nokia.s60")
+        
+        context = TestContext(None)
+        context.configuration = conf
+        fea= api.Feature("foo")
+        fea.add_feature(api.Feature("child1",type='selection'))
+        fea.child1.create_option('one','1')
+        fea.child1.create_option('two','2')
+        
+        conf.add_feature(fea)
+        
+        fea.child1.add_data(api.Data(value="2"))
+        
+        condition = rules.SimpleCondition("${fea.child1}", "2")
+        self.assertTrue(condition.eval(context))
+
+    def test_sequence_setting(self):
+        context = plugin.GenerationContext()
+        context.configuration = api.Configuration()
+        fea = model.ConfmlSequenceSetting("test")
+        fea.add_feature(model.ConfmlIntSetting('child1'))
+        fea.add_feature(model.ConfmlIntSetting('child2'))
+        fea.add_feature(model.ConfmlIntSetting('child3'))
+        context.configuration.add_feature(fea)
+        seq = context.configuration.get_default_view().get_feature('test')
+        seq.add_sequence(['1','2','3'])
+        seq.add_sequence(['4','5','6'])
+        seq.add_sequence(['7','8','9'])
+
+        condition = rules.SimpleCondition("${test}", [[1,2,3], [4,5,6], [7,8,9]])
+        self.assertTrue(condition.eval(context))
+
+        condition = rules.SimpleCondition("${test}", [['11','22','33'], ['44','55','66'], ['77','88','99']])
+        self.assertFalse(condition.eval(context))
+
+    def test_boolean_setting(self):
+        context = plugin.GenerationContext()
+        context.configuration = api.Configuration()
+        context.configuration.add_feature(model.ConfmlBooleanSetting("test"))
+        
+        context.configuration.get_default_view().test.value = True
+
+        condition = rules.SimpleCondition("${test}", True)
+        self.assertTrue(condition.eval(context))
+
+        condition = rules.SimpleCondition("${test}", "zoobar")
+        self.assertFalse(condition.eval(context))
+        
+        condition = rules.SimpleCondition("${test}", "1")
+        self.assertFalse(condition.eval(context))
+
+        condition = rules.SimpleCondition("${test}", "true")
+        self.assertTrue(condition.eval(context))
+
+        condition = rules.SimpleCondition("${test}", "0")
+        self.assertFalse(condition.eval(context))
+
+        condition = rules.SimpleCondition("${test}", "")
+        self.assertFalse(condition.eval(context))
+
+        condition = rules.SimpleCondition("${test}", None)
+        self.assertFalse(condition.eval(context))
+
+    def test_string_setting(self):
+        context = plugin.GenerationContext()
+        context.configuration = api.Configuration()
+        context.configuration.add_feature(model.ConfmlStringSetting("test"))
+        
+        context.configuration.get_default_view().test.value = "foobar"
+
+        condition = rules.SimpleCondition("${test}", "foobar")
+        self.assertTrue(condition.eval(context))
+
+        condition = rules.SimpleCondition("${test}", "zoobar")
+        self.assertFalse(condition.eval(context))
+        
+        condition = rules.SimpleCondition("${test}", "1")
+        self.assertFalse(condition.eval(context))
+
+        condition = rules.SimpleCondition("${test}", "true")
+        self.assertFalse(condition.eval(context))
+
+        condition = rules.SimpleCondition("${test}", "false")
+        self.assertFalse(condition.eval(context))
+
+        condition = rules.SimpleCondition("${test}", "0")
+        self.assertFalse(condition.eval(context))
+
+        condition = rules.SimpleCondition("${test}", "")
+        self.assertFalse(condition.eval(context))
+
+        condition = rules.SimpleCondition("${test}", None)
+        self.assertFalse(condition.eval(context))
+
+    def test_int_setting(self):
+        context = plugin.GenerationContext()
+        context.configuration = api.Configuration()
+        context.configuration.add_feature(model.ConfmlIntSetting("test"))
+        
+        context.configuration.get_default_view().test.value = "1"
+
+        condition = rules.SimpleCondition("${test}", "1")
+        self.assertTrue(condition.eval(context))
+
+        condition = rules.SimpleCondition("${test}", 2)
+        self.assertFalse(condition.eval(context))
+
+        condition = rules.SimpleCondition("${test}", True)
+        self.assertTrue(condition.eval(context))
+
+        condition = rules.SimpleCondition("${test}", False)
+        self.assertFalse(condition.eval(context))
+
+        condition = rules.SimpleCondition("${test}", 0)
+        self.assertFalse(condition.eval(context))
+
+        condition = rules.SimpleCondition("${test}", "zoobar")
+        try:
+            self.assertFalse(condition.eval(context))
+            self.fail("Exception expected.")
+        except Exception:
+            pass
+        
+        condition = rules.SimpleCondition("${test}", "")
+        try:
+            self.assertFalse(condition.eval(context))
+            self.fail("Exception expected.")
+        except Exception:
+            pass
+
+        condition = rules.SimpleCondition("${test}", None)
+        self.assertFalse(condition.eval(context))
+
+        context.configuration.get_default_view().test.value = "-1"
+        
+        condition = rules.SimpleCondition("${test}", -1)
+        self.assertTrue(condition.eval(context))
+        
+        condition = rules.SimpleCondition("${test}", 0)
+        self.assertFalse(condition.eval(context))
+        
+    def test_selection_setting_true(self):
+        context = plugin.GenerationContext()
+        context.configuration = api.Configuration()
+        context.configuration.add_feature(model.ConfmlSelectionSetting("test"))
+        
+        context.configuration.get_default_view().test.value = "True"
+
+        condition = rules.SimpleCondition("${test}", "True")
+        self.assertTrue(condition.eval(context))
+
+        condition = rules.SimpleCondition("${test}", True)
+        self.assertTrue(condition.eval(context))
+        
+        condition = rules.SimpleCondition("${test}", "1")
+        self.assertFalse(condition.eval(context))
+
+    def test_selection_setting_false(self):
+        context = plugin.GenerationContext()
+        context.configuration = api.Configuration()
+        context.configuration.add_feature(model.ConfmlSelectionSetting("test"))
+        
+        context.configuration.get_default_view().test.value = "False"
+
+        condition = rules.SimpleCondition("${test}", False)
+        self.assertTrue(condition.eval(context))
+        
+        condition = rules.SimpleCondition("${test}", "False")
+        self.assertTrue(condition.eval(context))
+        
+        condition = rules.SimpleCondition("${test}", "0")
+        self.assertFalse(condition.eval(context))
+
+        condition = rules.SimpleCondition("False", "0")
+        self.assertFalse(condition.eval(context))
+
+    def test_selection_setting_int(self):
+        context = plugin.GenerationContext()
+        context.configuration = api.Configuration()
+        context.configuration.add_feature(model.ConfmlSelectionSetting("test"))
+
+        context.configuration.get_default_view().test.value = "2"
+        
+        condition = rules.SimpleCondition("${test}", "2")
+        self.assertTrue(condition.eval(context))
+
+        condition = rules.SimpleCondition("${test}", 2)
+        self.assertTrue(condition.eval(context))
 
     def test_create_plugin_and_eval_integers(self):
         context = TestContext(None)
@@ -72,8 +294,12 @@
         self.assertFalse(condition.eval(context))
         condition = rules.SimpleCondition("2", "2")
         self.assertTrue(condition.eval(context))
+        condition = rules.SimpleCondition("2", 2)
+        self.assertTrue(condition.eval(context))
         condition = rules.SimpleCondition(2, 2)
         self.assertTrue(condition.eval(context))
+        condition = rules.SimpleCondition("-2", -2)
+        self.assertTrue(condition.eval(context))
 
     def test_create_plugin_and_eval_string(self):
         context = TestContext(None)
@@ -87,6 +313,7 @@
     def test_create_plugin_and_eval_data_reference(self):
         context = TestContext({'test' : 1, 'foo' : 2, 'bar' : True})
         condition = rules.SimpleCondition("${test}", 1)
+        condition.eval(context)
         self.assertTrue(condition.eval(context))
         condition = rules.SimpleCondition("${test}", False)
         self.assertFalse(condition.eval(context))
@@ -104,6 +331,7 @@
         condition = rules.SimpleCondition("${test}", None)
         self.assertTrue(condition.eval(context))
         condition = rules.SimpleCondition("${test.stringsub}", "None")
+        condition.eval(context)
         self.assertTrue(condition.eval(context))
         condition = rules.SimpleCondition("${test.intsub}", "None")
         self.assertTrue(condition.eval(context))
@@ -131,3 +359,6 @@
             self.fail("access of non existing elements succeds?")
         except:
             pass
+
+if __name__ == '__main__':
+    unittest.main()
--- a/configurationengine/source/cone/public/tests/unittest_settings.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/public/tests/unittest_settings.py	Tue Aug 10 14:29:28 2010 +0300
@@ -21,7 +21,6 @@
 import string
 import StringIO
 import sys,os
-import __init__
 
 from cone.public import api,exceptions,settings
 
@@ -76,13 +75,13 @@
         settings.SettingsFactory.defaultconfig = os.path.join(ROOT_PATH,'test_defaults.cfg')
         s = settings.SettingsFactory.cone_parser()
         cs = settings.ConeSettings(s)
-        self.assertEquals(s.get('DEFAULT','output'),'output//')
+        self.assertEquals(s.get('DEFAULT','output'),'//')
 
     def test_cone_settings(self):
         settings.SettingsFactory.defaultconfig = os.path.join(ROOT_PATH,'test_defaults.cfg')
         s = settings.SettingsFactory.cone_parser()
         cs = settings.ConeSettings(s)
-        self.assertEquals(cs.get('output'),'output//')
+        self.assertEquals(cs.get('output'),'//')
         self.assertEquals(cs.get('foobar'),None)
         self.assertEquals(cs.get('foobar', 'test'),'test')
 
@@ -91,11 +90,11 @@
         settings.SettingsFactory.configsettings = None
         s = settings.SettingsFactory.cone_parser()
         cs = settings.ConeSettings(s,'FOOBAR')
-        self.assertEquals(cs.get('output'),'output//')
+        self.assertEquals(cs.get('output'),'//')
         self.assertEquals(cs.get('foobar'),None)
         self.assertEquals(cs.get('foobar', 'test'),'test')
         self.assertEquals(cs.get('output','',{'output_subdir':'content',
-                                              'output_subdir':'content'}),'output/content/')
+                                              'output_subdir':'content'}),'/content/')
 
 if __name__ == '__main__':
       unittest.main()
--- a/configurationengine/source/cone/public/tests/unittest_storage.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/public/tests/unittest_storage.py	Tue Aug 10 14:29:28 2010 +0300
@@ -21,7 +21,6 @@
 import string
 import sys,os
 import pickle
-import __init__
 
 from cone.public import api, exceptions, utils
 
@@ -177,7 +176,7 @@
         res1.close()
         res1 = store.open_resource("test/foo.txt","w")
         res1.close()
-        self.assertEquals(store.list_resources('', True),['test/foo.txt'])
+        self.assertEquals(store.list_resources('', recurse=True),['test/foo.txt'])
 
     def test_open_many(self):
         store = api.Storage.open(storage_path,"w")
@@ -206,7 +205,7 @@
         self.assertEquals(store.list_resources('/'), ['root.txt'])
         self.assertEquals(store.list_resources('/test'), ['test/bar.txt',
                                                           'test/foo.txt'])
-        self.assertEquals(store.list_resources('/',True), ['root.txt',
+        self.assertEquals(store.list_resources('/',recurse=True), ['root.txt',
                                                            'test/bar.txt',
                                                            'test/foo.txt'])
 
@@ -367,7 +366,7 @@
         res.close()
         self.assertEquals(store.list_resources(""), ["foo.txt"])
         store.set_current_path("/")
-        self.assertEquals(store.list_resources("", True), ["subdir/foo.txt"])
+        self.assertEquals(store.list_resources("", recurse=True), ["subdir/foo.txt"])
         store.close()
         os.unlink(temp_file)
 
@@ -406,8 +405,8 @@
         res = layer.open_resource("confml/test.confml","w")
         res.write("foo.conf")
         res.close()
-        self.assertEquals(layer.list_resources("", True),["confml/test.confml"])
-        self.assertEquals(store.list_resources("", True),["foo/confml/test.confml"])
+        self.assertEquals(layer.list_resources("", recurse=True),["confml/test.confml"])
+        self.assertEquals(store.list_resources("", recurse=True),["foo/confml/test.confml"])
 
     def test_create_two_layers_and_open_resource(self):
         store = api.Storage.open(storage_path,"w")
@@ -421,12 +420,15 @@
         res = bar_layer.open_resource("confml/root.confml","w")
         res.write("foo.conf")
         res.close()
-        self.assertEquals(foo_layer.list_resources("", True),['confml/test.confml', 'root.confml'])
-        self.assertEquals(store.list_resources("", True),['bar/confml/root.confml','foo/confml/test.confml','foo/root.confml'])
+        self.assertEquals(foo_layer.list_resources("", recurse=True),['root.confml', 'confml/test.confml'])
+        self.assertEquals(store.list_resources("", recurse=True),['bar/confml/root.confml',
+                                                                  'foo/root.confml',
+                                                                  'foo/confml/test.confml'])
         
         foo_layer.delete_resource("confml/test.confml")
-        self.assertEquals(foo_layer.list_resources("", True),["root.confml"])
-        self.assertEquals(store.list_resources("", True),["bar/confml/root.confml","foo/root.confml"])
+        self.assertEquals(foo_layer.list_resources("", recurse=True),["root.confml"])
+        self.assertEquals(store.list_resources("", recurse=True),["bar/confml/root.confml",
+                                                                  "foo/root.confml"])
 
 
 if __name__ == '__main__':
--- a/configurationengine/source/cone/public/tests/unittest_utils.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/public/tests/unittest_utils.py	Tue Aug 10 14:29:28 2010 +0300
@@ -20,14 +20,11 @@
 Test the CPF root file parsing routines
 """
 
-import zipfile
 import unittest
-import string
-import token
-import sys,os,re
-import __init__
+import StringIO
+import os,re
 
-from cone.public import utils, rules, api, exceptions
+from cone.public import utils, api, exceptions
 
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
 testdata  = os.path.abspath(os.path.join(ROOT_PATH,'utils-testdata'))
@@ -78,7 +75,7 @@
         filtered = utils.resourceref.filter_resources(['test.txt','foo.dat','teat/data/bar.confml'],".*\.dat")
         self.assertEquals(filtered[0],'foo.dat')
 
-    def test_neg_filter_resources(self):
+    def test_neg_filter_resources2(self):
         filtered = utils.resourceref.neg_filter_resources(['/test/.svn/test.txt','.svn/test/foo.dat','teat/data/bar.confml'],"\.svn")
         self.assertEquals(filtered[0],'teat/data/bar.confml')
 
@@ -138,7 +135,7 @@
         self.assertEquals(utils.resourceref.norm('./skeleton.txt'),
                                      'skeleton.txt')
 
-    def test_norm_ref_with_begin_dot(self):
+    def test_norm_ref_with_begin_dot2(self):
         self.assertEquals(utils.resourceref.norm('.svn'),
                                      '.svn')
 
@@ -275,9 +272,6 @@
     def test_to_objref_dotted_start(self):
         self.assertEquals(utils.resourceref.to_objref('../foo/bar/test.confml'),'____foo__bar__test_confml')
 
-    def test_to_objref_dot_in_name_start(self):
-        self.assertEquals(utils.resourceref.to_objref('/foo.bar/test.confml'),'_foo_bar_test_confml')
-
     def test_to_objref_number_in_name_start(self):
         self.assertEquals(utils.resourceref.to_objref('_1.0.test_one'),'_1_0_test_one')
         self.assertEquals(utils.resourceref.to_objref('0.test_one'),'_0_test_one')
@@ -293,6 +287,13 @@
     def test_to_objref_dot_in_name_start(self):
         self.assertEquals(utils.resourceref.to_objref('/foo.bar/test.confml'),'__foo_bar__test_confml')
 
+    def test_to_objref_with_python_comment(self):
+        ##STRATEGIC## Customization offering for ##PROD_CODE##
+        self.assertEquals(utils.resourceref.to_objref('##STRATEGIC## Customization offering for ##PROD_CODE##'),
+                                                      '__STRATEGIC__Customizationofferingfor__PROD_CODE__')
+        self.assertEquals(utils.resourceref.to_objref('Feature A ## Testing ##'),
+                                                      'FeatureA__Testing__')
+
     def test_to_hash_dotted_start(self):
         self.assertEquals(utils.resourceref.to_hash('../foo/bar/test.confml'),'0x5a063087')
         self.assertEquals(utils.resourceref.to_hash('../foo/bar/test.confml'),'0x5a063087')
@@ -312,11 +313,17 @@
     def test_to_dref_from_dotted(self):
         self.assertEquals(utils.resourceref.to_dref('fii.faa.foo'),'fii.faa')
 
+    def test_is_path(self):
+        self.assertEquals(utils.resourceref.is_path('foo'),False)
+        self.assertEquals(utils.resourceref.is_path('foo.txt'),True)
+        self.assertEquals(utils.resourceref.is_path('bar/foo'),True)
+        self.assertEquals(utils.resourceref.is_path('bar/foo.txt'),True)
+
 class TestUtils(unittest.TestCase):    
     def test_distinct_array_with_single_values(self):
         self.assertEquals(utils.distinct_array(['1','2','1','1']),['1','2'])
 
-    def test_distinct_array_with_single_values(self):
+    def test_distinct_array_with_single_values2(self):
         self.assertEquals(utils.distinct_array(['1','2','3','1','2','4']),['1','2','3','4'])
 
     def test_list_files_from_testdata(self):
@@ -337,7 +344,7 @@
     def test_pathmatch_with_star(self):
         self.assertEquals(utils.pathmatch('test.foo.*','test.foo.bar'),True)
 
-    def test_pathmatch_with_star(self):
+    def test_pathmatch_with_star2(self):
         self.assertEquals(utils.pathmatch('test.foo.*','test.foo.bar.fiba'),False)
 
     def test_pathmatch_with_twostar(self):
@@ -368,6 +375,28 @@
         filters.append(lambda x: isinstance(x,F))
         self.assertEquals(utils.filter(obj,filters),False)
 
+    def test_is_float(self):
+        self.assertEquals(utils.is_float(-10), False)
+        self.assertEquals(utils.is_float(0), False)
+        self.assertEquals(utils.is_float(1), False)
+        self.assertEquals(utils.is_float(10), False)
+        self.assertEquals(utils.is_float(212), False)
+        self.assertEquals(utils.is_float('-10'), False)
+        self.assertEquals(utils.is_float('0'), False)
+        self.assertEquals(utils.is_float('1'), False)
+        self.assertEquals(utils.is_float('10'), False)
+        self.assertEquals(utils.is_float('212'), False)
+        self.assertEquals(utils.is_float(-10.1), True)
+        self.assertEquals(utils.is_float(0.1), True)
+        self.assertEquals(utils.is_float(1.1), True)
+        self.assertEquals(utils.is_float(10.1), True)
+        self.assertEquals(utils.is_float(212.1), True)
+        self.assertEquals(utils.is_float('-10.1'), True)
+        self.assertEquals(utils.is_float('0.00001'), True)
+        self.assertEquals(utils.is_float('1.1231'), True)
+        self.assertEquals(utils.is_float('10.000000001'), True)
+        self.assertEquals(utils.is_float('212.1'), True)
+
 class TestDottedRefs(unittest.TestCase):
     def test_join_two_refs(self):
         self.assertEquals(utils.dottedref.join_refs(['foo.bar.test','fancy.ref']),'foo.bar.test.fancy.ref')
@@ -544,6 +573,23 @@
             default_value_for_missing = 'giraffe')
         self.assertEquals(result, "The quick brown giraffe jumps over the lazy dog.")
         
+    def test_has_wildcard(self):
+        self.assertEquals(utils.dottedref.has_wildcard('fii.*'),True)
+        self.assertEquals(utils.dottedref.has_wildcard('fii.faa'),False)
+        self.assertEquals(utils.dottedref.has_wildcard('fii.faa.*'),True)
+        self.assertEquals(utils.dottedref.has_wildcard('fii.faa.**'),True)
+        self.assertEquals(utils.dottedref.has_wildcard('fii.faa.foo'),False)
+        self.assertEquals(utils.dottedref.has_wildcard('fii.*.faa'),True)
+        self.assertEquals(utils.dottedref.has_wildcard('*'),True)
+        
+    def test_get_wildcard_prefix(self):
+        self.assertEquals(utils.dottedref.get_static_ref('fii.*'),'fii')
+        self.assertEquals(utils.dottedref.get_static_ref('fii.faa'),'fii.faa')
+        self.assertEquals(utils.dottedref.get_static_ref('fii.faa.*'),'fii.faa')
+        self.assertEquals(utils.dottedref.get_static_ref('fii.faa.**'),'fii.faa')
+        self.assertEquals(utils.dottedref.get_static_ref('fii.faa.foo'),'fii.faa.foo')
+        self.assertEquals(utils.dottedref.get_static_ref('fii.*.faa'),'fii')
+        self.assertEquals(utils.dottedref.get_static_ref('*'),'')
 
 class TestUtilsSubclasses(unittest.TestCase):    
 
@@ -564,21 +610,6 @@
         classnames = utils.all_subclasses(base)
         self.assertEquals(len(classnames),4)
 
-class TestUtilsDataMapRef(unittest.TestCase):    
-
-    def setUp(self):
-        pass
-
-    def test_get_feature_ref(self):
-        map = "foo/bar[@key='key 1']"
-        ref = utils.DataMapRef.get_feature_ref(map)
-        self.assertEquals(ref,'foo/bar')
-
-    def test_get_key_value(self):
-        map = "foo/bar[@key='key 1']"
-        value = utils.DataMapRef.get_key_value(map)
-        self.assertEquals(value,'key 1')
-
 
 class TestMakeList(unittest.TestCase):
     def test_get_list_string(self):
@@ -638,6 +669,116 @@
             utils.xml.split_tag_namespace("{http://www.test.com/xml/1}test"),
             ('http://www.test.com/xml/1', 'test'))
 
+    
+    def test_get_xml_root_without_namespace_1(self):
+        resource = StringIO.StringIO("""<?xml version="1.0" encoding="UTF-8"?>
+            <root><elem1 attr1="test" att""")
+        namespace, name = utils.xml.get_xml_root(resource)
+        self.assertEquals(namespace, None)
+        self.assertEquals(name, 'root')
+    
+    def test_get_xml_root_without_namespace_2(self):
+        resource = StringIO.StringIO("""<?xml version="1.0" encoding="UTF-8"?>
+            <root xmlns:myns="http://www.test.com/xml/1"><elem1 attr1="test" att""")
+        namespace, name = utils.xml.get_xml_root(resource)
+        self.assertEquals(namespace, None)
+        self.assertEquals(name, 'root')
+    
+    def test_get_xml_root_with_namespace_1(self):
+        resource = StringIO.StringIO("""<?xml version="1.0" encoding="UTF-8"?>
+            <root xmlns="http://www.test.com/xml/1">
+                <elem1 attr1="test" attr2="test 2"/>
+                <elem2>testing</elem3>
+            </root>""")
+        namespace, name = utils.xml.get_xml_root(resource)
+        self.assertEquals(namespace, 'http://www.test.com/xml/1')
+        self.assertEquals(name, 'root')
+    
+    def test_get_xml_root_with_namespace_2(self):
+        resource = StringIO.StringIO("""<?xml version="1.0" encoding="UTF-16"?>
+            <myns:root xmlns:myns="http://www.test.com/xml/1">
+                <elem1 attr1="test" attr2="test 2"/>
+                <elem2>testing</elem3>
+            </myns:root>""".encode('utf-16'))
+        namespace, name = utils.xml.get_xml_root(resource)
+        self.assertEquals(namespace, 'http://www.test.com/xml/1')
+        self.assertEquals(name, 'root')
+    
+    def test_get_xml_root_with_namespace_3(self):
+        resource = StringIO.StringIO("""<configuration name="testdata_confml" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+              <data>""")
+        namespace, name = utils.xml.get_xml_root(resource)
+        self.assertEquals(namespace, 'http://www.s60.com/xml/confml/2')
+        self.assertEquals(name, 'configuration')
+    
+    def test_get_xml_root_invalid_xml_1(self):
+        resource = StringIO.StringIO("""<?xml version="1.0" encoding="UTF-16"?>
+            <root test test><elem """.encode('utf-16'))
+        self.assertRaises(exceptions.XmlParseError, utils.xml.get_xml_root, resource)
+    
+    def test_get_xml_root_invalid_xml_2(self):
+        resource = StringIO.StringIO("test test")
+        self.assertRaises(exceptions.XmlParseError, utils.xml.get_xml_root, resource)
+    
+    def test_get_xml_root_empty_string(self):
+        resource = StringIO.StringIO('')
+        self.assertRaises(exceptions.XmlParseError, utils.xml.get_xml_root, resource)
+
+class TestDictUtils(unittest.TestCase):
+    def test_update_tag_dict(self):
+        self.assertEquals(utils.update_dict({'foo' :  ['bar']}, {}),
+                                            {'foo': ['bar']})
+        self.assertEquals(utils.update_dict({}, {'foo' :  ['bar']}),
+                                            {'foo': ['bar']})
+        self.assertEquals(utils.update_dict({'foo' :  ['bar']},{'bar' : ['foo']}),
+                                            {'foo': [ 'bar'], 'bar' : ['foo']})
+        self.assertEquals(utils.update_dict({'foo' :  ['bar']},{'foo' : ['foo']}),
+                                            {'foo': ['bar', 'foo']})
+        self.assertEquals(utils.update_dict({'foo' :  ['bar'], 'moro' : ['sano','poro']},{'foo' : ['foo']}),
+                                            {'foo': ['bar', 'foo'], 'moro' : ['sano','poro']})
+
+        self.assertEquals(utils.update_dict({'foo' :  ['bar'], },{'foo' : ['foo'], 'moro' : ['sano','poro']}),
+                                            {'foo': ['bar', 'foo'], 'moro' : ['sano','poro']})
+
+class TestGrep(unittest.TestCase):
+    def test_grep_tuple(self):
+        data =['foo one','foo two','foo three','bar one','bar two','bar three']
+        self.assertEquals(utils.grep_tuple('one', data), [(0,'foo one'), (3,'bar one')])
+        self.assertEquals(utils.grep_tuple('two', data), [(1,'foo two'), (4,'bar two')])
+        self.assertEquals(utils.grep_tuple('foo', data), [(0,'foo one'), (1,'foo two'), (2,'foo three')])
+        self.assertEquals(utils.grep_tuple('foo|bar', data), [(0, 'foo one'), (1, 'foo two'), (2, 'foo three'), 
+                                                              (3, 'bar one'), (4, 'bar two'), (5, 'bar three')])
+
+    def test_grep_dict(self):
+        data =['foo one','foo two','foo three','bar one','bar two','bar three']
+        self.assertEquals(utils.grep_dict('one', data), {0 : 'foo one', 3 : 'bar one'})
+        self.assertEquals(utils.grep_dict('two', data), {1 : 'foo two', 4 : 'bar two'})
+        self.assertEquals(utils.grep_dict('foo', data), {0 : 'foo one', 1 : 'foo two', 2 : 'foo three'})
+
+class TestCmdLineParsing(unittest.TestCase):
+    def test_nt_parsing(self):
+        self.assertEquals(utils.cmdsplit(""), [])
+        self.assertEquals(utils.cmdsplit('--foo="foo bar"', 'nt'), ['--foo=foo bar'])
+        self.assertEquals(utils.cmdsplit('--foo="foo bar" -v5 -o "\epoc32\rom stuff\config"', 'nt'), ['--foo=foo bar',
+                                                                                                      '-v5', 
+                                                                                                      '-o', 
+                                                                                                      '\\epoc32\rom stuff\\config'])
+
+    def test_posix_parsing(self):
+        self.assertEquals(utils.cmdsplit("", 'posix'), [])
+        self.assertEquals(utils.cmdsplit('--foo="foo bar"', 'posix'), ['--foo=foo bar'])
+        self.assertEquals(utils.cmdsplit('--foo="foo bar" -v5 -o "/epoc32/rom stuff/config"', 'posix'), ['--foo=foo bar',
+                                                                                                      '-v5', 
+                                                                                                      '-o', 
+                                                                                                      '/epoc32/rom stuff/config'])
+
+
+class TestPathMethods(unittest.TestCase):
+    def test_relpath(self):
+        self.assertEquals(utils.relpath('foo/bar.txt','foo'), 'bar.txt')
+        self.assertEquals(utils.relpath('foo/bar.txt'), os.path.normpath('foo/bar.txt'))
+
 if __name__ == '__main__':
     unittest.main()
       
+
--- a/configurationengine/source/cone/public/tests/unittest_valueset.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/public/tests/unittest_valueset.py	Tue Aug 10 14:29:28 2010 +0300
@@ -18,10 +18,8 @@
 Test sets
 """
 import unittest
-import sets
 import sys
 import os
-import __init__
 
 from cone.public import api,exceptions,utils
 
--- a/configurationengine/source/cone/public/tests/unittest_views.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/public/tests/unittest_views.py	Tue Aug 10 14:29:28 2010 +0300
@@ -20,7 +20,8 @@
 import unittest
 import string
 import sys,os
-import __init__
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
 
 from cone.public import api,exceptions,utils
 
@@ -33,6 +34,12 @@
         self.assertTrue(view)
         self.assertTrue(view.ref, "view1")
 
+    def test_create_view_with_configuration(self):
+        config = api.Configuration("")
+        view = config.create_view("view1")
+        self.assertTrue(view)
+        self.assertTrue(view.ref, "view1")
+
     def test_view_add(self):
         view = api.View("view1")
         view._add(api.Group("Test"))
@@ -67,7 +74,7 @@
         feature._add(api.Feature("Test"))
         self.assertEquals(feature._list(),['Test'])
 
-    def test_view_add_groups_and_features_and_list_all(self):
+    def test_view_create_groups_and_features_and_list_all(self):
         view = api.View("view1")
         view._add(api.Group("group1"))
         view._add(api.Group("group2"))
@@ -85,7 +92,7 @@
                                            'group1.group21.feature212', 
                                            'feature1.feature11']))
 
-    def test_view_add_groups_and_features_and_list_features(self):
+    def test_view_create_groups_and_features_and_list_features(self):
         view = api.View("view1")
         view._add(api.Group("group1"))
         view._add(api.Group("group2"))
@@ -113,27 +120,40 @@
                                           ]))
 
 
-    def test_view_add_features_and_get_features(self):
+    def test_view_add_features_and_get_matching_features(self):
         view = api.View("view1")
         view.add_feature(api.Feature("feature1"))
         view.add_feature(api.Feature("feature2"), "com.nokia.s60")
         view.com.nokia.s60.feature2.add_feature(api.Feature("feature21"))
         self.assertEquals(view.get_feature("com.nokia.s60.feature2"), view.com.nokia.s60.feature2)
 
-    def test_view_get_features(self):
+    def test_view_get_matching_features(self):
         view = api.View("view1")
         view.add_feature(api.Feature("feature1",type='boolean'))
         view.add_feature(api.Feature("feature2"))
         view.add_feature(api.Feature("feature11", type='boolean'),"feature1")
         view.add_feature(api.Feature("feature12"),"feature1")
-        self.assertEquals(view.get_features("feature2"), [view.feature2])
-        self.assertEquals(view.get_features("feature2.*"), [])
-        self.assertEquals(view.get_features("feature1.*"), [view.feature1.feature11, view.feature1.feature12])
-        self.assertEquals(view.get_features("feature1.*", name='feature11'), [view.feature1.feature11])
-        self.assertEquals(view.get_features("**", filters=[lambda x: x.get_type()=='boolean']), 
+        self.assertEquals(view.get_matching_features("feature2"), [view.feature2])
+        self.assertEquals(view.get_matching_features("feature2.*"), [])
+        self.assertEquals(view.get_matching_features("feature1.*"), [view.feature1.feature11, view.feature1.feature12])
+        self.assertEquals(view.get_matching_features("feature1.*", name='feature11'), [view.feature1.feature11])
+        self.assertEquals(view.get_matching_features("**", filters=[lambda x: x.get_type()=='boolean']), 
                           [view.feature1,
                            view.feature1.feature11])
 
+
+    def test_view_get_matching_features_with_list(self):
+        view = api.View("view1")
+        view.add_feature(api.Feature("feature1",type='boolean'))
+        view.add_feature(api.Feature("feature2"))
+        view.add_feature(api.Feature("feature11", type='boolean'),"feature1")
+        view.add_feature(api.Feature("feature12"),"feature1")
+        self.assertEquals(view.get_features(["feature2", "feature1"]), [view.feature2, view.feature1])
+        self.assertEquals(view.get_features(["feature2", "feature1.*"]), [view.feature2, 
+                                                                          view.feature1.feature11,
+                                                                          view.feature1.feature12])
+        self.assertEquals(view.get_features([""]), [])
+
     def test_view_add_features_and_remove_features(self):
         view = api.View("view1")
         view.add_feature(api.Feature("feature1"))
@@ -146,10 +166,10 @@
             view.remove_feature(fearef)
         self.assertEquals(view.list_all_features(),['com.nokia.s60.feature2', 'com.nokia.s60.feature2.feature21'])
 
-    def test_view_add_groups_remove_groups(self):
+    def test_view_create_groups_remove_groups(self):
         view = api.View("view1")
-        view.add_group("Group one")
-        view.add_group("Group two")
+        view.create_group("Group one")
+        view.create_group("Group two")
         view.add_feature(api.Feature("feature2"),"Group one")
         self.assertEquals(view.list_groups(),['Group one',  'Group two'])
         view.remove_group("Group two")
@@ -161,16 +181,35 @@
         self.assertEquals(view.list_groups(),[])
         self.assertEquals(view.list_features(),[])
 
+    def test_create_featurelink(self):
+        self.assertEquals(api.FeatureLink.get_featurelink_ref("fealink"), "link_fealink")
+        fealink = api.FeatureLink("fealink")
+        self.assertEquals(fealink.ref, "link_fealink")
+        self.assertEquals(fealink.link, "fealink")
+        
+    def test_view_create_featurelink(self):
+        view = api.View("view1")
+        fl = view.create_featurelink("Testing.foobar")
+        self.assertTrue(isinstance(fl, api.FeatureLink))
+        self.assertEquals(view.get_featurelink("Testing.foobar"), fl)
+        
+
+    def test_view_create_group_with_name(self):
+        view = api.View("view1")
+        view.create_group("Group one", name="Testing group")
+        self.assertEquals(view.get_group("Group one").name, "Testing group")
+
     def test_view_add_featurelink(self):
         view = api.View("view1")
-        view.add_group("Group one")
-        view.add_group("Group two")
+        view.create_group("Group one")
+        view.create_group("Group two")
         view.add_feature(api.Feature("feature2"),"Group one")
         self.assertEquals(view.list_groups(),['Group one',  'Group two'])
         view.remove_group("Group two")
         #view.add(api.FeatureGroup('foo.*'))
         self.assertEquals(view.list_groups(),['Group one'])
-        view.get_group('Group one').add(api.FeatureLink("testing"))
+        view.get_group('Group one').create_featurelink("testing", name='testing 1')
+        self.assertEquals(view.get_group('Group one').get_featurelink('testing').get_name(), 'testing 1')
         g1 = view.get_group('Group one')
         self.assertEquals(g1.list_features(),['feature2'])
         self.assertEquals(view.list_all_features(),['Group one.feature2'])
@@ -179,6 +218,49 @@
         self.assertEquals(view.list_groups(),[])
         self.assertEquals(view.list_features(),[])
 
+    def test_feature_link_get_overrides(self):
+        fl = api.FeatureLink("testing")
+        self.assertEquals(fl.get_attributes(), {})
+        self.assertEquals(fl.get_attributes(), {})
+        fl.override_attributes.append('desc')
+        fl.override_attributes.append('name')
+        fl.name = None
+        fl.desc = "test"
+        self.assertEquals(fl.get_attributes(), {'desc': 'test'})
+        fl.desc = "bar"
+        self.assertEquals(fl.get_attributes(), {'desc': 'bar'})
+        fl.desc = ""
+        fl.minLength = 2
+        fl.override_attributes.append('minLength')
+        self.assertEquals(fl.get_attributes(), { 'minLength' : 2, 'desc': ''})
+
+    def test_add_view_to_configuration_and_populate(self):
+        config = api.Configuration("foo")
+        config.add_feature(api.Feature("testing"))
+        view = api.View("view1")
+        view.create_group("Group one")
+        fl = api.FeatureLink("testing")
+        view.get_group('Group one').add(fl)
+        config.add_view(view)
+        view.populate()
+        self.assertEquals(view.get_group('Group one').list_features(),['proxy_testing'])
+    
+    def test_view_add_featurelink_with_description_override(self):
+        api.FeatureLink.override_attributes.append('dict')
+        config = api.Configuration("foo")
+        fea = api.Feature("testing")
+        fea.desc = "feature desc"
+        config.add_feature(fea)
+        view = api.View("view1")
+        view.create_group("Group one")
+        fl = api.FeatureLink("testing")
+        fl.desc = "view desc"
+        view.get_group('Group one').add(fl)
+        config.add_view(view)
+        view.populate()
+        self.assertEquals(view.get_group('Group one').list_features(),['proxy_testing'])
+        self.assertEquals(view.get_group('Group one').get_feature('proxy_testing').desc, "view desc")
+    
     def compareview(self,view1,view2):
         self.assertEquals(view1.ref, view2.ref)
         self.assertEquals(view1.container, view2.container)
@@ -188,9 +270,9 @@
 
     def test_clone_view_with_featurelink(self):
         view1 = api.View("view1")
-        view1.add_group("Group one")
-        view1.add_group("Group two")
-        view1.get_group('Group one').add(api.FeatureLink("testing"))
+        view1.create_group("Group one")
+        view1.create_group("Group two")
+        view1.get_group('Group one').create_featurelink("testing/foo")
         fea2 = api.Feature("feature2")
         view1.add_feature(fea2,"Group one")
         view1.add_feature(api.Feature("feature3"),"Group one")
@@ -199,10 +281,64 @@
         view2 = view1._clone(recursion=True)
         self.compareview(view1,view2)
         self.assertEquals(view2.list_groups(),['Group one',  'Group two'])
-        self.assertEquals(view2.get_group('Group one')._list(),['testing', 'feature2', 'feature3'])
+        self.assertEquals(view2.get_group('Group one')._list(),['link_testing_foo', 'feature2', 'feature3'])
         #self.assertEquals(view2.get_group('Group one').feature2._obj, fea2)
+    
+    
+    def test_populate_group_with_same_name_features(self):
+        config = api.Configuration("foo")
+        
+        feature = api.Feature("Feature1", name="Some feature")
+        feature.add_feature(api.Feature("Setting1", name="Setting 1"))
+        feature.add_feature(api.Feature("Setting2", name="Setting 2"))
+        config.add_feature(feature)
+        
+        feature = api.Feature("Feature2", name="Some feature")
+        feature.add_feature(api.Feature("Setting1", name="Setting 1"))
+        feature.add_feature(api.Feature("Setting2", name="Setting 2"))
+        config.add_feature(feature)
         
         
+        view = api.View('testview')
+        config.add_view(view)
+        
+        # Test using explicit links for all settings
+        view.create_group('testgroup')
+        group = view.get_group('testgroup')
+        group.create_featurelink('Feature1.Setting1')
+        group.create_featurelink('Feature1.Setting2')
+        group.create_featurelink('Feature2.Setting1')
+        group.create_featurelink('Feature2.Setting2')
+        
+        group.populate()
+        self.assertEquals(sorted(group.list_features()),
+                          ['proxy_Feature1_Setting1',
+                           'proxy_Feature1_Setting2',
+                           'proxy_Feature2_Setting1',
+                           'proxy_Feature2_Setting2'])
+        
+        
+        # Test using wildcards
+        view.create_group('testgroup2')
+        group = view.get_group('testgroup2')
+        group.create_featurelink('Feature1.*')
+        group.create_featurelink('Feature2.*')
+        
+        group.populate()
+        self.assertEquals(sorted(group.list_features()),
+                          ['proxy_Feature1_Setting1',
+                           'proxy_Feature1_Setting2',
+                           'proxy_Feature2_Setting1',
+                           'proxy_Feature2_Setting2'])
+    
+    def test_readonly_attribute(self):
+        p = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'testdata', 'view_tests')))
+        root = p.get_configuration('view_tests-cpf.confml')
+        views = root.get_view(root.list_views()[0])
+        seqs = views.get_group('Sequences')
+        japan_car_name = seqs.get_feature('proxy_japan-car-fea_CarSequence_CarName')
+        self.assertTrue(japan_car_name.readOnly)
+    
 if __name__ == '__main__':
       unittest.main()
 
--- a/configurationengine/source/cone/public/tests/unittest_xml_parsing.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/public/tests/unittest_xml_parsing.py	Tue Aug 10 14:29:28 2010 +0300
@@ -18,7 +18,6 @@
 import sys, os
 import unittest
 import StringIO
-import __init__
 
 from cone.public import utils, exceptions
 
@@ -62,6 +61,12 @@
         else:
             self.assertEquals(actual, None)
     
+    def assert_elem_tag(self, actual, expected):
+        if self.LINE_NUMBERS:
+            self.assertEquals(actual.tag, expected)
+        else:
+            self.assertEquals(actual, None)
+    
     def test_correct_parser_set(self):
         self.assertEquals(utils.etree.get_backend_id(), self.BACKEND_ID)
     
@@ -79,7 +84,8 @@
         self.assert_lineno_equals(utils.etree.get_lineno(children[0]), 4)
         self.assert_lineno_equals(utils.etree.get_lineno(children[1]), 5)
         self.assert_lineno_equals(utils.etree.get_lineno(children[2]), 6)
-    
+        self.assert_elem_tag(utils.etree.get_elem_from_lineno(root, 5), '{http://www.test.com/xml/1}elem2')
+
     def test_tostring_ascii(self):
         root = utils.etree.fromstring(self.DATA)
         output = utils.etree.tostring(root)
@@ -102,7 +108,7 @@
             etree = utils.etree.fromstring(data)
             self.fail("XmlParseError not raised!")
         except exceptions.XmlParseError, e:
-            self.assertEquals(e.lineno, 4)
+            self.assertEquals(e.problem_lineno, 4)
 
 # ============================================================================
 # Actual test cases
--- a/configurationengine/source/cone/public/utils.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/public/utils.py	Tue Aug 10 14:29:28 2010 +0300
@@ -17,16 +17,17 @@
 
 import os
 import re
+import posixpath
 import StringIO
 import tokenize
 import inspect
 import traceback
 import logging
+import shlex
+from xml.parsers import expat
 import imghdr
 from token import ENDMARKER, NAME, NUMBER, STRING
-import api
-import mimetypes
-import exceptions
+from cone.public import exceptions
 
 import _etree_wrapper
 etree = _etree_wrapper.ElementTreeWrapper()
@@ -61,10 +62,10 @@
     
     @classmethod
     def remove_begin_slash(cls, ref):
-        if ref.startswith('/'): 
-            return ref.replace('/', '', 1)
+        while ref.startswith('/'): 
+            ref = ref.replace('/', '', 1)
         return ref
-
+    
     @classmethod
     def remove_end(self, path, str):
         try:
@@ -98,7 +99,9 @@
         # Do not modify emtpy string at all
         if not ref == '':
             normref = os.path.normpath(ref)
-            normref = normref.replace('\\','/').replace('"','').replace('//','/')
+            normref = normref.replace('\\','/').replace('"','')
+            normref = posixpath.normpath(normref)
+            normref = normref.rstrip('\\/')
         else:
             normref = ref
         return normref
@@ -193,17 +196,17 @@
     def get_filename(cls, ref):
         """
         get file name part from ref 
-        1. get file extension
-        @return: a reference. E.g. (foo/test.confml) => confml
+        1. get file name
+        @return: a reference. E.g. (foo/test.confml) => test.confml
         """
         return ref.rsplit('/', 1)[-1]
 
     @classmethod
     def get_path(cls, ref):
         """
-        get file name part from ref 
-        1. get file extension
-        @return: a reference. E.g. (foo/test.confml) => confml
+        get path part from ref 
+        1. get path from ref
+        @return: a reference. E.g. (foo/test.confml) => foo
         """
         if len(ref.rsplit('/', 1)) == 2: 
             return ref.rsplit('/', 1)[0]
@@ -232,6 +235,9 @@
         @return: a dotted reference. E.g. (foo/test.confml) => foo_test
         """
         ref = ref.replace('/', '__')
+        # Change the python comment character also as underscore so that the tokenizer 
+        # does not leave anything out
+        ref = ref.replace('#', '_')
         newref = ''
         first_token = True
         try:
@@ -274,6 +280,16 @@
         """
         return "%s" % hex(hash(ref))
 
+    @classmethod
+    def is_path(cls, ref):
+        """
+        returns true if the ref seems like a path
+        @return: Boolean value [True|False]
+        """
+        if cls.get_ext(ref) or cls.get_path(ref):
+            return True
+        return False
+
 class dottedref(object):
     """
     Class container for set of dotted reference related functions
@@ -378,6 +394,28 @@
                 elems.append(refelem.replace("*","[^\.]*"))
         return "\\.".join(elems)+"$"
     
+    @classmethod
+    def has_wildcard(cls, ref):
+        """
+        Tests if the ref has any wildcards '*' in it.
+        @return: Boolean value. True when wildcards are found.
+        """
+        return ref.find('*') != -1
+
+    @classmethod
+    def get_static_ref(cls, ref):
+        """
+        Checks if the ref has any wildcards and return the non wildcard part of ref.
+        @return: string.
+        """
+        retparts = []
+        for part in cls.split_ref(ref):
+            if cls.has_wildcard(part):
+                break
+            else:
+                retparts.append(part)
+        return ".".join(retparts)
+
 def extract_delimited_tokens(string, delimiters=('${', '}')):
     """
     Return a list of all tokens delimited by the given strings in the given string.
@@ -388,7 +426,7 @@
     ['my.ref1', 'my.ref2']
     """
     ref_tuples = extract_delimited_token_tuples(string, delimiters)
-    return distinct_array([ref for ref, raw_ref in ref_tuples])
+    return distinct_array([u'%s' % ref for ref, raw_ref in ref_tuples])
 
 def extract_delimited_token_tuples(string, delimiters=('${', '}')):
     """
@@ -443,19 +481,26 @@
             result = result.replace(raw_token, entry.value)
     return result
 
-def expand_refs_by_default_view(string, default_view, delimiters=('${', '}'), default_value_for_missing=''):
+def expand_refs_by_default_view(string, default_view, delimiters=('${', '}'), default_value_for_missing='',
+                                catch_not_found=True):
     """
     Convenience function for expanding the refs in a string using setting values.
     @param default_value_for_missing: The default value used if a setting for
-        a reference cannot be found.
+        a reference cannot be found. Has no effect if catch_not_found is False.
+    @param catch_not_found: If True, the NotFound exception raised when a setting
+        is not found is caught and the value of default_value_for_missing is inserted
+        in its place.
     @return: The expanded string.
     """
     def expand(ref, index):
-        try:
+        if catch_not_found:
+            try:
+                return default_view.get_feature(ref).get_original_value()
+            except exceptions.NotFound:
+                logging.getLogger('cone').error("Feature '%s' not found" % ref)
+                return default_value_for_missing
+        else:
             return default_view.get_feature(ref).get_original_value()
-        except exceptions.NotFound:
-            logging.getLogger('cone').error("Feature '%s' not found" % ref)
-            return default_value_for_missing
     return expand_delimited_tokens(string, expand, delimiters)
 
 def distinct_array(arr):
@@ -527,6 +572,15 @@
 def is_list(elem):
     return isinstance(elem, list)
 
+def is_float(value):
+    """
+    Test if the fiven value (which can be a string) is a floating point value. 
+    """
+    fvalue = float(value)
+    ivalue = int(fvalue)
+    
+    return (fvalue - ivalue) != 0
+
 def get_class(modelinstance, classinstance):
     """
     Get the actual model specific implementation class for a classinstance
@@ -538,31 +592,40 @@
                 return modelclass
     return classinstance
 
-class DataMapRef(object):
-    """
-    Utility class for handling map attributes in data section
-    """
-    @classmethod
-    def get_feature_ref(cls, map):
-        index = map.find("@")
-        if index != -1:
-            parts = map.split("@")
-            return parts[0][:-1]
+class OProperty(object):
+    """Based on the emulation of PyProperty_Type() in Objects/descrobject.c
+    from http://infinitesque.net/articles/2005/enhancing%20Python%27s%20property.xhtml"""
+    def __init__(self, fget=None, fset=None, fdel=None, doc=None):
+        self.fget = fget
+        self.fset = fset
+        self.fdel = fdel
+        self.__doc__ = doc
+ 
+    def __get__(self, obj, objtype=None):
+        if obj is None:
+            return self
+        if self.fget is None:
+            raise AttributeError, "unreadable attribute"
+        if self.fget.__name__ == '<lambda>' or not self.fget.__name__:
+            return self.fget(obj)
         else:
-            return None
-        
-    @classmethod
-    def get_key_value(cls, map):
-        index = map.find("@")
-        if index != -1:
-            parts = map.split("@")
-            key = parts[1][:-1]
-            keys = key.split("=")
-            value = keys[1].strip()
-            return value[1:-1]
+            return getattr(obj, self.fget.__name__)()
+ 
+    def __set__(self, obj, value):
+        if self.fset is None:
+            raise AttributeError, "can't set attribute"
+        if self.fset.__name__ == '<lambda>' or not self.fset.__name__:
+            self.fset(obj, value)
         else:
-            return None
-        
+            getattr(obj, self.fset.__name__)(value)
+ 
+    def __delete__(self, obj):
+        if self.fdel is None:
+            raise AttributeError, "can't delete attribute"
+        if self.fdel.__name__ == '<lambda>' or not self.fdel.__name__:
+            self.fdel(obj)
+        else:
+            getattr(obj, self.fdel.__name__)()
 
 class xml(object):
     """
@@ -585,6 +648,56 @@
         else:
             return (None, xml_tag)
 
+    @classmethod
+    def get_xml_root(cls, resource):
+        """
+        Get a (namespace, tag) tuple of the root element in the XML data
+        read from the given resource.
+        
+        @param resource:  The resource from which to read data. Should be a
+            file-like object (i.e. should have a read() method).
+        @return: A (namespace, tag) tuple. Note that the namespace may
+            be None.
+        
+        @raise exceptions.XmlParseError: The resource contains invalid XML data.
+        """
+        class RootElementFound(RuntimeError):
+            def __init__(self, root_name):
+                self.root_name = root_name
+        
+        def handle_start(name, attrs):
+            raise RootElementFound(name)
+        
+        p = expat.ParserCreate(namespace_separator=':')
+        p.StartElementHandler = handle_start
+        
+        BUFSIZE = 128
+        while True:
+            data = resource.read(BUFSIZE)
+            try:
+                p.Parse(data, len(data) < BUFSIZE)
+            except RootElementFound, e:
+                parts = e.root_name.rsplit(':', 1)
+                if len(parts) > 1:
+                    return parts[0], parts[1]
+                else:
+                    return None, parts[0]
+            except expat.ExpatError, e:
+                raise exceptions.XmlParseError(
+                    "XML parse error on line %d: %s" % (e.lineno, e),
+                    e.lineno, str(e))
+
+def update_dict(todict, fromdict):
+    """
+    Merges the elements of two dictionaries together.
+    @param todict: the target dictionary where data is merged. 
+    @param fromdict: the source dict where data is read 
+    @return: the modified todict.  
+    """
+    for key in fromdict:
+        todict.setdefault(key, []).extend(fromdict[key])
+    return todict
+
 def log_exception(logger, msg, msg_level=logging.ERROR, traceback_level=logging.DEBUG):
     """
     Log an exception so that the given message and the exception's
@@ -600,22 +713,85 @@
     logger.log(msg_level, msg)
     logger.log(traceback_level, traceback.format_exc())
 
-def make_content_info(resource, data):
+
+def grep(string,list):
+    """
+    Grep throught the items in the given list to find matching entries. 
+    """
+    expr = re.compile(string)
+    return filter(expr.search,list)
+
+def grep_tuple(string,list):
+    """
+    Grep throught the items in the given list to find matching entries. 
+    @return: a list of tuples (index,text) 
     """
-    Factory for ContentInfo
+    results = []
+    expr = re.compile(string)
+    for (index,text) in enumerate(list):
+        match = expr.search(text)
+        if match != None:
+            results.append((index,match.string))
+    return results
+
+def grep_dict(string,list):
     """
-    cnt_inf = None
+    Grep throught the items in the given list to find matching entries. 
+    @return: a dictionary with list index as key and matching text as value.
+    """
+    results = {}
+    expr = re.compile(string)
+    for (index,text) in enumerate(list):
+        match = expr.search(text)
+        if match != None:
+            results[index]  = match.string
+    return results
+
+def cmdsplit(s, comments=False, os_name='nt'):
+    """
+    Copy of shlex split method to allow parsing of command line parameters in operating system specific mode.
     
-    if resource != None:
-        guessed_type = mimetypes.guess_type(resource.get_path())
-        mimetype = None
-        mimesubtype = None
-        
-        if guessed_type != None:
-            mimetype, mimesubtype = guessed_type[0].split('/') 
-        
-        if mimetype == 'image' and mimesubtype == 'x-ms-bmp':
-            cnt_inf = api.BmpImageContentInfo(resource, data)
+    """
+    posix = True
+    lex = shlex.shlex(s, posix=posix)
+    lex.whitespace_split = True
+    if not comments:
+        lex.commenters = ''
+    if os_name == 'nt':
+        lex.escape = '^'
+    return list(lex)
+
+
+import sys
+sys_version = "%d.%d" % (sys.version_info[0],sys.version_info[1])
+if sys_version >= "2.6":
+    def relpath(path, start=os.curdir):
+        return os.path.relpath(path, start)
+else:
+    def relpath(path, start=os.curdir):
+        """Return a relative version of a path"""
+    
+        if not path:
+            raise ValueError("no path specified")
+        start_list = os.path.abspath(start).split(os.sep)
+        path_list = os.path.abspath(path).split(os.sep)
+        if start_list[0].lower() != path_list[0].lower():
+            unc_path, rest = os.path.splitunc(path)
+            unc_start, rest = os.path.splitunc(start)
+            if bool(unc_path) ^ bool(unc_start):
+                raise ValueError("Cannot mix UNC and non-UNC paths (%s and %s)"
+                                                                    % (path, start))
+            else:
+                raise ValueError("path is on drive %s, start on drive %s"
+                                                    % (path_list[0], start_list[0]))
+        # Work out how much of the filepath is shared by start and path.
+        for i in range(min(len(start_list), len(path_list))):
+            if start_list[i].lower() != path_list[i].lower():
+                break
         else:
-            cnt_inf = api.ContentInfo(mimetype, mimesubtype)
-    return cnt_inf
+            i += 1
+    
+        rel_list = [os.pardir] * (len(start_list)-i) + path_list[i:]
+        if not rel_list:
+            return os.curdir
+        return os.path.join(*rel_list) 
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/report/__init__.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,20 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+import sys,os
+
+__all__ = []
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/report/generation_report.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,211 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import os, logging, pickle
+import time
+from time import strftime
+from cone.public import api, exceptions, utils, plugin
+from cone.confml import model
+from cone.report import report_util 
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+SERIALISATION_FORMAT = 'pickle'
+
+def save_report_data(rep_data, file_path):
+    """
+    Save report data into an intermediary report data file.
+    """
+    dir = os.path.dirname(file_path)
+    if dir != '' and not os.path.exists(dir):
+        os.makedirs(dir)
+    f = open(file_path, 'wb')
+    try:
+        if SERIALISATION_FORMAT == 'yaml':
+            yaml.dump(rep_data, f)
+        elif SERIALISATION_FORMAT == 'pickle':
+            pickle.dump(rep_data, f)
+        elif SERIALISATION_FORMAT == 'pickle/2':
+            pickle.dump(rep_data, f, 2)
+    finally:    
+        f.close()
+
+def load_report_data(file_path):
+    """
+    Load report data from an intermediary report data file.
+    """
+    try:        
+        f = open(file_path, "rb")
+        if SERIALISATION_FORMAT == 'yaml':
+            data = yaml.load(f)
+        elif SERIALISATION_FORMAT == 'pickle':
+            data = pickle.load(f)
+        elif SERIALISATION_FORMAT == 'pickle/2':
+            data = pickle.load(f)
+    finally:
+        f.close()
+        
+    data.label = get_generation_run_label(file_path)
+    return data
+
+def get_generation_run_label(datafile_path):
+    filename = os.path.split(datafile_path)[1]
+    filename_noext = os.path.splitext(filename)[0]
+    return filename_noext
+
+def _get_parent_sequence_or_self(feature):
+    current = feature._parent
+    while current is not None:
+        if isinstance(current, api.FeatureSequence):
+            return current
+        current = current._parent
+    return feature
+
+
+def generate_report(rep_data, report_file_path, template_file_path=None, template_paths=[], report_options=[]):
+    """
+    Generate a generation report based on the given report data.
+    @param rep_data: The report data.
+    @param report_file_path: Path to the report file to generate.
+    @param template_file_path: Path to the template file to use.
+        If None, the default template is used.
+    @param template_paths: the additional search paths for templates. The default location cone.report is 
+    always included.   
+    """
+    # Determine the template file and directory to use
+    if template_file_path is None:
+        template_file_path = 'gen_report_template.html'
+    contexts = [report_data.context for report_data in rep_data]
+    report_data = {'rep_data' : rep_data, 
+                   'report_options' : report_options,
+                   'merged_context' : plugin.MergedContext(contexts)}
+    report_util.generate_report(template_file_path, report_file_path, report_data, template_paths)
+
+def normalize_slash(path):
+    """
+    Normalize backslashes to slashes to make testing easier (no differences
+    between reports in linux and windows).
+    """
+    return path.replace('\\', '/')
+
+class ReportData(object):
+    """
+    Data object that stores all information used in report generation.
+    """
+    
+    def __init__(self):
+        self.project = None
+        self.generation_timestamp = time.time()
+        self.generation_time = strftime("%d.%m.%Y %H:%M:%S")
+        self.options = None
+        self.duration = 0
+        self.output_dir = os.getcwd()
+        self.project_dir = ''
+        self.context = None
+        self.label = ''
+
+    def set_output_dir(self, dir):
+        self.output_dir = os.path.abspath(os.path.normpath(dir))
+        
+    def set_duration(self, duration):
+        self.duration = duration
+    
+    def set_options(self, options):
+        self.options = options
+        self.project_dir = os.path.abspath(options.project)
+        
+    def set_report_filename(self, filename):
+        self.report_filename = filename
+        
+    def __repr__(self):
+        return "ReportData(%s)" % [self.generation_timestamp, 
+                                   self.generation_time,
+                                   self.options,
+                                   self.duration,
+                                   self.output_dir,
+                                   self.project_dir]    
+
+
+class RefLine(object):
+    """
+    Data object that stores information for one ref in report generation.
+    """
+    
+    def __init__(self, ref, type):
+        self.ref = ref
+        self.feat_type = type 
+        self.feat_name = None
+        self.feat_value = None
+        self.config_path = None
+        self.impls = []
+        self.output = None
+        self.nbr_impls = 0
+        self.nbr_outputfiles = 0
+        self.datas = []
+        self.nbr_of_datas = 0
+        self.nbr_of_rows = 0
+        self.seq_data = []
+        self.is_temp_feature = False
+        
+    def add_impl(self, impl_file, impl_type, outputfiles):
+        self.impls.append(ImplLine(impl_file, impl_type, outputfiles))
+        self.nbr_impls = len(self.impls)
+        self.nbr_outputfiles = len(outputfiles) + self.nbr_outputfiles
+
+    def add_data(self, layer, value):
+        self.datas.append(DataLine(layer,value))
+        self.nbr_of_datas = len(self.datas)
+        
+    def add_sequence(self, subsetting, values):
+        self.seq_data.append([subsetting, values])
+        
+    def set_feat_name(self, name):
+        self.feat_name = name
+        
+    def set_feat_value(self, value):
+        self.feat_value = value
+        
+    def set_config_path(self, filename):
+        self.config_path = normalize_slash(os.path.normpath(filename))
+        
+
+class ImplLine():
+    def __init__(self, impl_file, impl_type, outputfiles, generation_runs=[]):
+        self.name = normalize_slash(os.path.normpath(impl_file))
+        self.type = impl_type
+        files = []
+        
+        for outputfile in outputfiles:
+            files.append(Outputfile(outputfile))
+        
+        self.outputfiles = files
+        self.generation_runs = generation_runs
+        
+class Outputfile():
+    def __init__(self, filename):
+        self.filename = normalize_slash(os.path.normpath(filename))
+        self.abs_filename = normalize_slash(os.path.abspath(filename))
+        self.exists = os.path.isfile(self.abs_filename)
+    
+    def __eq__(self, other):
+        if type(self) is type(other):
+            return self.filename == other.filename
+        else:
+            return False
+        
+class DataLine():
+    def __init__(self, layer, value):
+        self.layer = normalize_slash(os.path.normpath(layer))
+        self.value = value
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/report/report_util.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,205 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import os
+import urllib
+import logging
+from jinja2 import Environment, FileSystemLoader
+from cone.public import utils
+
+ROOT_PATH = os.path.abspath(os.path.dirname(__file__))
+
+log = logging.getLogger('cone.report_util')
+
+class ReportShortcut(object):
+    def __init__(self, template_file, report_file, description):
+        self.template_file = template_file
+        self.report_file = report_file
+        self.description = description
+
+class ReportShortcutContainer(object):
+    """
+    Container for report shortcuts.
+    
+    A report shortcut describes a pre-defined report option that
+    has a default template, report file and description. The shortcut
+    container holds a set of shortcuts and can be used to generate
+    
+    """
+    def __init__(self, shortcuts, default_shortcut):
+        """
+        @param shortcuts: The shortcuts, a dictionary mapping shortcut
+            names to ReportShortcut objects.
+        @param default_shortcut: The default shortcut name to use
+        """
+        if not isinstance(shortcuts, dict):
+            raise ValueError("'shortcuts' must a dictionary (%s given)!" % type(shortcuts))
+        if default_shortcut is not None and default_shortcut not in shortcuts:
+            raise ValueError("'default_shortcut' must be either None or exist ing 'shortcuts'!")
+        self.shortcuts = shortcuts
+        self.default_shortcut = default_shortcut
+    
+    def get_shortcut_help_text(self):
+        """
+        Create the text to append to the option description for the
+        option used to specify the used shortcut.
+        """
+        shortcuts_text = []
+        refs = sorted(self.shortcuts.keys())
+        if refs:
+            for ref in refs:
+                sc = self.shortcuts[ref]
+                text = "%s - %s" % (ref, sc.description)
+                COLUMN_WIDTH = (80 - 25)
+                space_count = COLUMN_WIDTH - (len(text) % COLUMN_WIDTH)
+                shortcuts_text.append(text + space_count * ' ')
+        else:
+            shortcuts_text.append("None")
+        shortcuts_text = '\n'.join(shortcuts_text)
+        return shortcuts_text
+    
+    def is_valid_shortcut(self, shortcut):
+        """
+        Return whether the given shortcut is valid within the context
+        of this container.
+        """
+        return shortcut is None or shortcut in self.shortcuts
+    
+    def determine_template_and_report(self, shortcut, template_file, report_file, report_file_name_without_ext):
+        """
+        Determine the actual template and report files based on the shortcuts
+        and given options.
+        @param shortcut: The used shortcut or None.
+        @param template_file: Explicitly given template file or None.
+        @param report_file: Explicitly given report file or None.
+        @param report_file_name_without_ext: Prefix used to determine the
+            report file name if the template was explicitly given, but the
+            report file was not. E.g. if this is 'test' and the explicitly
+            given template file is 'my_template.html', the report file would
+            be 'test.html'.
+        @return: Tuple (template_file, report_file) specifying the actual
+            template and report files.
+        """
+        actual_shortcut      = None
+        actual_template_file = None
+        actual_report_file   = None
+        
+        # Handle report shortcut (set to default or check the given one)
+        if not shortcut:
+            actual_shortcut = self.default_shortcut
+        else:
+            actual_shortcut = shortcut
+        
+        # Determine template file
+        if template_file:
+            actual_template_file = template_file
+        else:
+            actual_template_file = self.shortcuts[actual_shortcut].template_file
+        
+        # Determine report output file
+        if report_file:
+            actual_report_file = report_file
+        else:
+            if template_file:
+                # Determine report file name based on the template file name
+                # if the template was explicitly given
+                actual_report_file = report_file_name_without_ext + os.path.splitext(template_file)[1]
+            else:
+                actual_report_file = self.shortcuts[actual_shortcut].report_file
+        
+        return actual_template_file, actual_report_file
+
+def generate_report(template_file, report_file, report_data, template_paths=[], extra_filters={}):
+    """
+    Generate a report based on the given template file, report file
+    and data dictionary.
+    @param template_file: Path to the template file to use.
+    @param report_file: Path to the output report file.
+    @param report_data: The report data dictionary used when rendering
+        the report from the template.
+    @param template_paths: the additional search paths for templates. The default location cone.report is 
+    always included.   
+    @return: True if successful, False if not.
+    """
+    template_paths.insert(0, ROOT_PATH)
+    template_paths.insert(0, os.path.dirname(template_file))
+    template_paths = utils.distinct_array(template_paths)
+    log.debug('generate_report(template_file=%r, report_file=%r, <data>, template_paths=%s)' % (template_file, report_file, template_paths))
+    if not isinstance(report_data, dict):
+        raise ValueError("report_data must be a dictionary!")
+    
+    try:
+        template_file = os.path.abspath(template_file)
+        
+        loader = FileSystemLoader(template_paths)
+        env = Environment(loader=loader)
+        set_filters(env,extra_filters)
+        
+        template = env.get_template(os.path.basename(template_file))
+        file_string = template.render(report_data)
+        
+        # Create directories for the report
+        report_dir = os.path.dirname(report_file)
+        if report_dir != '' and not os.path.exists(report_dir):
+            os.makedirs(report_dir)
+        
+        # Write the rendered report to file
+        f = open(report_file, 'wb')
+        try:        f.write(file_string.encode('utf-8'))
+        finally:    f.close()
+        
+        print "Generated report to '%s'" % report_file
+        return True
+    except Exception, e:
+        utils.log_exception(log, "Failed to generate report: %s %s" % (type(e), e))
+        return False
+
+def _set_default_filters(env):
+    """
+    Set default filters to the given Jinja environment
+    """
+    env.filters['xml_charref_replace'] = lambda value: unicode(value).encode('ascii', 'xmlcharrefreplace')
+    env.filters['pathname_to_url'] = lambda value: urllib.pathname2url(value)
+    env.filters['csv_escape'] = _csv_escape
+    env.filters['csv_escape_partial'] = lambda value: unicode(value).replace('"', '""')
+
+def set_filters(env, filters={}):
+    """
+    First set the default filters and then possible extra filters from filters dict
+    @param filters: the filters dictionary where the key is the filter name and value the method pointer
+     
+    """
+    _set_default_filters(env)
+    for name, filter in filters.iteritems():
+        env.filters[name]=filter
+
+def _csv_escape(value):
+    """
+    Escape a string value so that it can be used as a field in a CSV file.
+    """
+    value = unicode(value)
+    
+    needs_quoting = False
+    for special_char in '",\n':
+        if special_char in value:
+            needs_quoting = True
+    
+    if needs_quoting:
+        if '"' in value:
+            value = value.replace('"', '""')
+        value = '"' + value + '"'
+    
+    return value
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/report/tests/project/layer1/confml/accessoryserver.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,92 @@
+<configuration name="accessoryserver" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+  <feature name="Accessory Server Settings" ref="KCRUidAccServerSettings">
+    <desc>Central repository for accessory related UI settings.</desc>
+  <setting relevant="false" name="Accessory Server HW Devices" ref="KAccServerHWDevices" type="int">
+      <desc>Setting used to detect properly some connected accessories (e.g. TTY, Loopset).
+
+Phone may support some HW devices that are not properly identified when they are connected to phone. To properly identify such devices user has to tell by using appropriate user interface setting the type of connected device.</desc>
+    </setting>
+  <setting name="Accessory Server Wired HS Lights" ref="KAccServerWiredHSLights" type="int">
+      <desc>Lights setting for wired headset mode. User may force lights on when wired headset is connected to phone. 
+Possible integer values:
+0 lights off
+1 lights on
+</desc>
+    </setting>
+  <setting name="Accessory Server Wireless HS Lights" ref="KAccServerWirelessHSLights" type="int">
+      <desc>Lights setting for wireless headset mode. User may force lights on when wireless headset is connected to phone. 
+Possible integer values:
+0 lights off
+1 lights on
+</desc>
+    </setting>
+  <setting name="Accessory Server Wired Car Kit Lights" ref="KAccServerWiredCarKitLights" type="int">
+      <desc>Lights setting for wired car kit mode. User may force lights on when wired car kit is connected to phone. 
+Possible integer values:
+0 lights off
+1 lights on
+</desc>
+    </setting>
+  <setting name="Accessory Server Wireless Car Kit Lights" ref="KAccServerWirelessCarKitLights" type="int">
+      <desc>Lights setting for wireless car kit mode. User may force lights on when wireless car kit is connected to phone. 
+Possible integer values:
+0 lights off
+1 lights on
+</desc>
+    </setting>
+  <setting name="Accessory Server Text Device Lights" ref="KAccServerTextDeviceLights" type="int">
+      <desc>Lights setting for text device mode. User may force lights on when text device is connected to phone.
+Possible integer values:
+0 lights off
+1 lights on
+</desc>
+    </setting>
+  <setting name="Accessory Server Loopset Lights" ref="KAccServerLoopsetLights" type="int">
+      <desc>Lights setting for loopset. User may force lights on when loopset is connected to phone.
+Possible integer values:
+0 lights off
+1 lights on
+</desc>
+    </setting>
+  <setting name="Accessory Server Music Stand Lights" ref="KAccServerMusicStandLights" type="int">
+      <desc>Lights setting for music stand. User may force lights on when music stand is connected to phone.
+Possible integer values:
+0 lights off
+1 lights on
+</desc>
+    </setting>
+  <setting name="Accessory Server Sync Stand Lights" ref="KAccServerSyncStandLights" type="int">
+      <desc>Lights setting for synchronization stand. User may force lights on when synchronization stand is connected to phone.
+Possible integer values:
+0 lights off
+1 lights on
+</desc>
+    </setting>
+  </feature>
+<data>
+    <KCRUidAccServerSettings>
+      <KAccServerHWDevices>8</KAccServerHWDevices>
+    <KAccServerWiredHSLights>0</KAccServerWiredHSLights>
+    <KAccServerWirelessHSLights>0</KAccServerWirelessHSLights>
+    <KAccServerWiredCarKitLights>0</KAccServerWiredCarKitLights>
+    <KAccServerWirelessCarKitLights>0</KAccServerWirelessCarKitLights>
+    <KAccServerTextDeviceLights>0</KAccServerTextDeviceLights>
+    <KAccServerLoopsetLights>0</KAccServerLoopsetLights>
+    <KAccServerMusicStandLights>0</KAccServerMusicStandLights>
+    <KAccServerSyncStandLights>0</KAccServerSyncStandLights>
+    </KCRUidAccServerSettings>
+  </data>
+<rfs>
+    <KCRUidAccServerSettings>
+      <KAccServerHWDevices>true</KAccServerHWDevices>
+    <KAccServerWiredHSLights>true</KAccServerWiredHSLights>
+    <KAccServerWirelessHSLights>true</KAccServerWirelessHSLights>
+    <KAccServerWiredCarKitLights>true</KAccServerWiredCarKitLights>
+    <KAccServerWirelessCarKitLights>true</KAccServerWirelessCarKitLights>
+    <KAccServerTextDeviceLights>true</KAccServerTextDeviceLights>
+    <KAccServerLoopsetLights>true</KAccServerLoopsetLights>
+    <KAccServerMusicStandLights>true</KAccServerMusicStandLights>
+    <KAccServerSyncStandLights>true</KAccServerSyncStandLights>
+    </KCRUidAccServerSettings>
+  </rfs>
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/report/tests/project/layer1/confml/feature1.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/1" name="Feature 1" version="1">
+  <feature ref="Feature1" name="Feature 1 (ConfML v1.0)">
+    <desc>Feature with all supported setting types for ConfML v1.0</desc>
+    <setting ref="RealSetting" name="Real setting" type="real">
+      <desc>A real setting</desc>
+    </setting>
+    <setting ref="IntSetting" name="Int setting" type="int">
+      <desc>An int setting</desc>
+    </setting>
+    <setting ref="StringSetting" name="String setting" type="string">
+      <desc>A string setting</desc>
+    </setting>
+    <setting ref="BooleanSetting" name="Boolean setting" type="boolean">
+      <desc>A boolean setting</desc>
+    </setting>
+    <setting ref="SelectionSetting" name="Selection setting" type="selection">
+      <desc>A selection setting</desc>
+      <option name="Option0" value="0"/>
+      <option name="Option1" value="1"/>
+      <option name="Option2" value="2"/>
+      <option name="Option3" value="3"/>
+      <option name="Option4" value="4"/>
+    </setting>
+    <setting ref="SequenceSetting" name="Sequence setting" type="sequence">
+      <desc>A sequence setting</desc>
+      <setting ref="RealSubSetting" name="Real sub-setting" type="real">
+        <desc>A real sub-setting</desc>
+      </setting>
+      <setting ref="IntSubSetting" name="Int sub-setting" type="int">
+        <desc>An int sub-setting</desc>
+      </setting>
+      <setting ref="StringSubSetting" name="String sub-setting" type="string">
+        <desc>A string sub-setting</desc>
+      </setting>
+      <setting ref="BooleanSubSetting" name="Boolean sub-setting" type="boolean">
+        <desc>A boolean sub-setting</desc>
+      </setting>
+      <setting ref="SelectionSubSetting" name="Selection sub-setting" type="selection">
+        <desc>A selection sub-setting</desc>
+        <option name="Op0" value="0"/>
+        <option name="Op1" value="1"/>
+        <option name="Op2" value="2"/>
+        <option name="Op3" value="3"/>
+        <option name="Op4" value="4"/>
+      </setting>
+    </setting>
+  </feature>
+  <data>
+    <Feature1>
+      <RealSetting>3.14</RealSetting>
+      <IntSetting>10</IntSetting>
+      <StringSetting>default string</StringSetting>
+      <BooleanSetting>true</BooleanSetting>
+      <SelectionSetting>1</SelectionSetting>
+      <SequenceSetting template="true">
+        <RealSubSetting>1.0</RealSubSetting>
+        <IntSubSetting>1</IntSubSetting>
+        <StringSubSetting>template</StringSubSetting>
+        <BooleanSubSetting>false</BooleanSubSetting>
+        <SelectionSubSetting>0</SelectionSubSetting>
+      </SequenceSetting>
+      <SequenceSetting>
+        <RealSubSetting>1.25</RealSubSetting>
+        <IntSubSetting>128</IntSubSetting>
+        <StringSubSetting>def1</StringSubSetting>
+        <BooleanSubSetting>false</BooleanSubSetting>
+        <SelectionSubSetting>1</SelectionSubSetting>
+      </SequenceSetting>
+      <SequenceSetting>
+        <RealSubSetting>1.5</RealSubSetting>
+        <IntSubSetting>256</IntSubSetting>
+        <StringSubSetting>def2</StringSubSetting>
+        <BooleanSubSetting>false</BooleanSubSetting>
+        <SelectionSubSetting>1</SelectionSubSetting>
+      </SequenceSetting>
+    </Feature1>
+  </data>
+  
+  <rfs>
+    <Feature1>
+      <RealSetting>true</RealSetting>
+      <IntSetting>false</IntSetting>
+      <StringSetting>false</StringSetting>
+      <BooleanSetting>true</BooleanSetting>
+      <SelectionSetting>true</SelectionSetting>
+    </Feature1>
+  </rfs>
+</configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/report/tests/project/layer1/implml/accessoryserver_1020505A.implml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<container xmlns="http://www.symbianfoundation.org/xml/implml/1">
+    <phase name="normal"/>
+    <tag name="target" value="rofs2"/>
+    <repository xmlns="http://www.s60.com/xml/cenrep/1" uidName="KCRUidAccServerSettings" uidValue="0x1020505A" owner="0x10205030" backup="true" rfs="true">
+      <key ref="KCRUidAccServerSettings/KAccServerHWDevices" name="KAccServerHWDevices" int="0x00000001" backup="true">
+        <access type="R" capabilities="AlwaysPass"/>
+        <access type="W" capabilities="WriteDeviceData"/>
+      </key>
+      <key ref="KCRUidAccServerSettings/KAccServerWiredHSLights" name="KAccServerWiredHSLights" int="0x00000002" backup="true">
+        <access type="R" capabilities="AlwaysPass"/>
+        <access type="W" capabilities="WriteDeviceData"/>
+      </key>
+      <key ref="KCRUidAccServerSettings/KAccServerWirelessHSLights" name="KAccServerWirelessHSLights" int="0x00000003" backup="true">
+        <access type="R" capabilities="AlwaysPass"/>
+        <access type="W" capabilities="WriteDeviceData"/>
+      </key>
+      <key ref="KCRUidAccServerSettings/KAccServerWiredCarKitLights" name="KAccServerWiredCarKitLights" int="0x00000004" backup="true">
+        <access type="R" capabilities="AlwaysPass"/>
+        <access type="W" capabilities="WriteDeviceData"/>
+      </key>
+      <key ref="KCRUidAccServerSettings/KAccServerWirelessCarKitLights" name="KAccServerWirelessCarKitLights" int="0x00000005" backup="true">
+        <access type="R" capabilities="AlwaysPass"/>
+        <access type="W" capabilities="WriteDeviceData"/>
+      </key>
+      <key ref="KCRUidAccServerSettings/KAccServerTextDeviceLights" name="KAccServerTextDeviceLights" int="0x00000006" backup="true">
+        <access type="R" capabilities="AlwaysPass"/>
+        <access type="W" capabilities="WriteDeviceData"/>
+      </key>
+      <key ref="KCRUidAccServerSettings/KAccServerLoopsetLights" name="KAccServerLoopsetLights" int="0x00000007" backup="true">
+        <access type="R" capabilities="AlwaysPass"/>
+        <access type="W" capabilities="WriteDeviceData"/>
+      </key>
+      <key ref="KCRUidAccServerSettings/KAccServerMusicStandLights" name="KAccServerMusicStandLights" int="0x00000008" backup="true">
+        <access type="R" capabilities="AlwaysPass"/>
+        <access type="W" capabilities="WriteDeviceData"/>
+      </key>
+      <key ref="KCRUidAccServerSettings/KAccServerSyncStandLights" name="KAccServerSyncStandLights" int="0x00000009" backup="true">
+        <access type="R" capabilities="AlwaysPass"/>
+        <access type="W" capabilities="WriteDeviceData"/>
+      </key>
+      <access type="R" capabilities="AlwaysPass"/>
+      <access type="W" capabilities="WriteDeviceData"/>
+      <keyRange firstInt="0x00100000" lastInt="0xFFFFFF00" backup="true">
+        <access type="R" capabilities="AlwaysPass"/>
+        <access type="W" capabilities="WriteDeviceData"/>
+      </keyRange>
+    </repository>
+</container>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/report/tests/project/layer1/implml/test.implml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<container xmlns="http://www.symbianfoundation.org/xml/implml/1">
+    <phase name="normal"/>
+    <tag name="target" value="rofs2"/>
+    
+    <ruleml xmlns="http://www.s60.com/xml/ruleml/3">
+        <rule>${Feature1.IntSetting} configures ${Feature1.StringSetting} = 'set from rule'</rule>
+        <eval_globals>
+        def test_function2(foo):
+            return foo
+        </eval_globals>
+    </ruleml>
+    
+    <ruleml xmlns="http://www.s60.com/xml/ruleml/2">
+        <rule>Feature1.IntSetting configures Feature1.SelectionSetting = '0'</rule>
+        <eval_globals>
+        def test_function2(foo):
+            return foo
+        </eval_globals>
+    </ruleml>
+    
+    <templateml xmlns="http://www.s60.com/xml/templateml/1">
+        <output file="test.txt" encoding="UTF-8">
+            <template>Test output: {{ feat_tree.Feature1.StringSetting._value }}</template>
+        </output>
+    </templateml>
+</container>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/report/tests/project/layer1/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="ASCII"?>
+<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/1" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="http://www.w3.org/2001/XInclude http://www.s60.com/xml/confml/1#//include" name="Base layer">
+  <xi:include href="confml/feature1.confml"/>
+  <xi:include href="confml/accessoryserver.confml"/>
+  <confml:meta/>
+</confml:configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/report/tests/project/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="ASCII"?>
+<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/1" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="http://www.w3.org/2001/XInclude http://www.s60.com/xml/confml/1#//include" name="Base layer">
+  <xi:include href="layer1/root.confml"/>
+  <confml:meta/>
+</confml:configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/report/tests/unittest_report.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,102 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+import os
+import unittest
+
+from cone.report import generation_report
+from cone.public import plugin, api
+from testautomation.utils import remove_if_exists
+
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+TEMP_DIR     = os.path.normpath(os.path.join(ROOT_PATH, 'temp'))
+
+class TestGenerateReport(unittest.TestCase):
+    def setUp(self):
+        remove_if_exists(TEMP_DIR)
+
+    def test_create_report_data(self):
+        rdata = generation_report.ReportData()
+        self.assertEquals(rdata.context, None)
+
+    def test_save_load_empty_report_data(self):
+        rdata = generation_report.ReportData()
+        tmpfile = os.path.join(TEMP_DIR, 'repdata.dat')
+        generation_report.save_report_data(rdata, tmpfile)
+        rdata2 = generation_report.load_report_data(tmpfile)
+        self.assertEquals(repr(rdata), repr(rdata2))
+
+    def test_save_load_report_data_with_some_content(self):
+        rdata = generation_report.ReportData()
+        p = api.Project(api.Storage.open(TEMP_DIR, 'w'))
+        config = api.Configuration('test.confml')
+        fea = config.create_feature('Foo')
+        fea.create_feature('Child1')
+        fea.create_feature('Child2')
+        c3 = fea.create_feature('Child3')
+        c3.value = 'test'
+        rdata.log = ['one',
+                     'two',
+                     'three']
+        p.add_configuration(config)
+        p.save()
+        rdata.context = plugin.GenerationContext(phase="pre",
+                                                 tags={'target' : 'rofs3'},
+                                                 output='foo',
+                                                 configuration=config,
+                                                 project=p)
+        
+        tmpfile = os.path.join(TEMP_DIR, 'repdata.dat')
+        generation_report.save_report_data(rdata, tmpfile)
+        rdata2 = generation_report.load_report_data(tmpfile)
+        self.assertEquals(repr(rdata), repr(rdata2))
+        self.assertEquals(rdata.log, rdata2.log) 
+        self.assertEquals(rdata.log, rdata2.log) 
+        self.assertEquals(rdata2.context.phase, 'pre')
+        self.assertEquals(rdata2.context.tags, {'target' : 'rofs3'})
+        self.assertEquals(rdata2.context.output, 'foo')
+        self.assertEquals(rdata2.context.configuration.Foo.Child3.fqr, 'Foo.Child3')
+        self.assertEquals(rdata2.context.configuration.Foo.Child3.get_value(), 'test')
+        self.assertEquals(rdata2.context.configuration.Foo.Child3.value, 'test')
+
+    def test_save_load_report_data_with_real_content(self):
+        prj = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'project')))
+        config = prj.get_configuration('root.confml')
+        impls = plugin.get_impl_set(config)
+        context = plugin.GenerationContext(phase="normal",
+                                           tags={'target' : ['rofs2']},
+                                           output='temp',
+                                           configuration=config)
+                
+        impls.generate(context)
+        prj = config.get_project()
+        c1 = config.get_configuration('layer1/root.confml')
+        
+        self.assertEquals(len(context.generation_output), 4)
+        rdata = generation_report.ReportData()
+        rdata.context = context
+        rdata.project = prj
+        tmpfile = os.path.join(TEMP_DIR, 'repdata_real.dat')
+        generation_report.save_report_data(rdata, tmpfile)
+        rdata2 = generation_report.load_report_data(tmpfile)
+        self.assertEquals(repr(rdata), repr(rdata2))
+        dview = rdata2.context.configuration.get_default_view()
+        self.assertEquals(len(rdata2.context.generation_output), 4)
+
+
+if __name__ == '__main__':
+    unittest.main()
--- a/configurationengine/source/cone/runtests.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/runtests.py	Tue Aug 10 14:29:28 2010 +0300
@@ -15,28 +15,6 @@
 #
 
 
-import os,sys,unittest
-from optparse import OptionParser, OptionGroup
-
-ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
-sys.path.insert(0, os.path.join(ROOT_PATH,'..'))
-#sys.path.insert(0, os.path.join(ROOT_PATH,'../testautomation'))
-
-import cone.storage.tests
-import cone.core.tests
-import cone.confml.tests
-import cone.carbon.tests
-import cone.public.tests
-#from testautomation import testcli
-
-def collect_suite():
-    suite = unittest.TestSuite()
-    suite.addTests(cone.storage.tests.collect_suite())
-    suite.addTests(cone.core.tests.collect_suite())
-    suite.addTests(cone.confml.tests.collect_suite())
-    suite.addTests(cone.carbon.tests.collect_suite())
-    suite.addTests(cone.public.tests.collect_suite())
-    return suite
 
 if __name__ == '__main__':
     import nose
@@ -49,9 +27,5 @@
     conf = nose.config.Config(files=allfiles,
                   plugins=plugins)
     conf.configure(argv=['collector'])
-    print "conf :", conf.include
     nose.main(config=conf)
 
-#if __name__ == '__main__':
-#    testcli.run(collect_suite())
-
--- a/configurationengine/source/cone/storage/authenticate.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/storage/authenticate.py	Tue Aug 10 14:29:28 2010 +0300
@@ -38,6 +38,8 @@
     The data is saved in varables inside class
     """
     def __init__(self, *argv, **kwargs):
+        self.username_func = kwargs.pop('username_func',None)
+        self.password_func = kwargs.pop('password_func',None)
         HTMLParser.__init__(self, *argv, **kwargs)
         self.html_end = False
         self.httpdata = {}
@@ -45,8 +47,6 @@
         self.input_entered = False
         self.method = ''
         self.action = ''
-        self.username = kwargs.get('username')
-        self.password = kwargs.get('password')
         
     def handle_starttag(self, tag, attrs):
         attrs = dict(attrs)
@@ -64,13 +64,13 @@
                 self.httpdata[attrs.get('name')] = attrs.get('value')
             if inputtype == 'password':
                 self.input_requested = True
-                data = self.password
+                data = self.password_func()
                 if data:
                     self.input_entered = True
                 self.httpdata[attrs.get('name')] = data
             if inputtype == 'text':
                 self.input_requested = True
-                data = raw_input()
+                data = self.username_func()
                 if data:
                     self.input_entered = True
                 self.httpdata[attrs.get('name')] = data
@@ -95,13 +95,47 @@
 
 class CarbonAuthHandler(urllib2.AbstractHTTPHandler):
     handler_order = 600
+    def __init__(self):
+        urllib2.AbstractHTTPHandler.__init__(self)
+        self.auth_count = 0
+        self.auth_max = 5
+        self.username = ""
+        self.password = ""
+        self.username_func = None
+        self.password_func = None
+        
     
-    def add_password(self, username, password):
+    def add_username_func(self, username_func):
+        """
+        Add password getting function
+        """
+        self.username_func = username_func
+
+    def add_password_func(self, password_func):
+        """
+        Add password getting function
         """
-        Add username and password
+        self.password_func = password_func
+
+    def get_username(self):
+        """
+        Add password getting function
         """
-        self.username = username
-        self.password = password
+        if self.auth_count == 0  and self.username_func:            
+            return self.username_func()
+        else:
+            self.username = raw_input("Username: ")
+            return self.username 
+            
+    def get_password(self):
+        """
+        Add password getting function
+        """
+        if self.auth_count == 0 and self.password_func:            
+            return self.password_func()
+        else:
+            self.password = getpass.getpass()
+            return self.password
 
     def https_response(self, request, response):
         """
@@ -111,8 +145,13 @@
         original page.
         """
         if (re.match('login.*\.europe\.nokia\.com', request.get_host())):
-            sso_parser = SSOHTMLParser(username=self.username, password=self.password)
+            if self.auth_count > self.auth_max:
+                print "Authentication failed!"
+                return response
+            sso_parser = SSOHTMLParser(username_func=self.get_username, password_func=self.get_password)
             sso_parser.feed(response.read())
+            self.auth_count += 1
+            
             # !sso_parser.input_requested when we have posted the form and
             # are reading the redirect back. We don't want to handle that
             if sso_parser.input_requested:
@@ -140,14 +179,18 @@
         original page.
         """    
         if response.code == 200 and (re.match('.*/extauth/login/?.*', request.get_full_url())):
+            if self.auth_count > self.auth_max:
+                raise urllib2.HTTPError("Authentication failed!")
+            
             loginreq = urllib2.Request(request.get_full_url(),
-                                     urllib.urlencode({ 'username' : self.username, 
-                                                        'password' : self.password,
+                                     urllib.urlencode({ 'username' : self.get_username(), 
+                                                        'password' : self.get_password(),
                                                         'submit' : 'login'}
                                                       ),
                                      origin_req_host=request.get_origin_req_host(),
                                      unverifiable=True,
                                      )
+            self.auth_count += 1
             return self.parent.open(loginreq)
         else:            
             return response
--- a/configurationengine/source/cone/storage/common.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/storage/common.py	Tue Aug 10 14:29:28 2010 +0300
@@ -17,18 +17,20 @@
 import logging
 import xml.parsers.expat
 
-from cone.public import api, utils
+from cone.public.api import Storage
+from cone.public import utils
 from cone.storage import metadata
 
-class StorageBase(api.Storage):
+class StorageBase(Storage):
     """
     A general base class for all storage type classes
     """
     METADATA_FILENAME = ".metadata"
 
-    def __init__(self,path):
-        super(StorageBase, self).__init__(path)
+    def __init__(self, path, mode):
+        super(StorageBase, self).__init__(path, mode)
         self.meta = self.read_metadata()
+        
 
     def get_active_configuration(self): 
         """
@@ -37,7 +39,7 @@
         """
         root_confmls = self.list_resources("/")
         root_confmls = utils.resourceref.filter_resources(root_confmls,"\.confml")
-        if self.meta.get_root_file() == '' and len(root_confmls) == 1:
+        if self.meta.get_root_file() == None and len(root_confmls) == 1:
             return root_confmls[0]
         else:
             return self.meta.get_root_file()
@@ -68,7 +70,7 @@
         # Try to update the metadata, which might fail on ZipStorage
 
         try:
-            if self.get_mode(self.mode) != api.Storage.MODE_READ:
+            if self.get_mode(self.mode) != Storage.MODE_READ:
                 # update the active configuration
                 self.set_active_configuration(self.get_active_configuration())
                 metares = self.open_resource(self.METADATA_FILENAME,"wb")
--- a/configurationengine/source/cone/storage/filestorage.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/storage/filestorage.py	Tue Aug 10 14:29:28 2010 +0300
@@ -26,13 +26,13 @@
     except ImportError:
         try:
             from xml.etree import cElementTree as ElementTree
-        except ImpotError:
+        except ImportError:
             from xml.etree import ElementTree
             
 from cone.public import exceptions  
-from cone.public import api, utils
+from cone.public import api, utils, parsecontext
 #from cone.storage.configurationpersistence import ConfigurationReader, ConfigurationWriter
-from cone.storage import metadata, common
+from cone.storage import metadata, common, zipstorage
 from cone.confml import persistentconfml
 debug = 0
 
@@ -43,12 +43,10 @@
     @param mode: the mode for the folder. Default is a=append that expects the folder to exist.
     """
     
-    def __init__(self,path,mode="r", **kwargs):
-        super(FileStorage, self).__init__(path)
-        self.logger = logging.getLogger('cone')
-        self.logger.debug("FileStorage path %s" % self.get_path())
+    def __init__(self, path, mode="r", **kwargs):
+        super(FileStorage, self).__init__(path, mode)
+        logging.getLogger('cone').debug("FileStorage path %s" % self.get_path())
         self.persistentmodule = persistentconfml
-        self.mode = mode
         if mode.find("a")!=-1 or mode.find("r")!=-1:
             # check that the given folder exists and is a folder    
             if not os.path.isdir(self.get_path()):
@@ -151,7 +149,7 @@
         return entry
 
 
-    def list_resources(self,path,recurse=False,empty_folders=False):
+    def list_resources(self, path, **kwargs):
         """
         Get an array of files in a folder
         """
@@ -162,16 +160,20 @@
         joined = os.path.join(self.get_path(), self.get_current_path())
         current_root = os.path.normpath(os.path.abspath(joined))
         # return always unix type file paths
-        if recurse:    
+        if kwargs.get('recurse', False):    
             # Walk through all files in the layer
             for root, dirs, files in os.walk(fullpath):
+                # ensure that the directories and files are returned
+                # with alphabetical sorting in all platforms (e.g linux)
+                dirs.sort()
+                files.sort()
                 for name in files:
                     entry = os.path.join(root, name)
                     entry = os.path.normpath(os.path.abspath(entry))
                     if os.path.isfile(entry):
                         retarray.append(self.fix_entry(entry,current_root))
                         
-                if empty_folders: 
+                if kwargs.get('empty_folders', False): 
                     for name in dirs:
                         entry = os.path.join(root, name)
                         entry = os.path.normpath(os.path.abspath(entry))
@@ -179,7 +181,7 @@
                             retarray.append(self.fix_entry(entry,current_root))
                         
         else:
-            filelist = os.listdir(fullpath)
+            filelist = sorted(os.listdir(fullpath))
             for name in filelist:
                 entry = os.path.join(path, name)
                 entry = os.path.normpath(entry)
@@ -191,7 +193,7 @@
                     if debug: print "list_resources adding %s" % entry
                     retarray.append(entry)
                     
-                if os.path.isdir(fileentry) and empty_folders:
+                if os.path.isdir(fileentry) and kwargs.get('empty_folders', False):
                     if debug: print "list_resources adding %s" % entry
                     retarray.append(entry)
         return retarray
@@ -217,11 +219,19 @@
                 logging.getLogger('cone').warning("The given path is not a Resource in this storage %s! Ignoring from export!" % path)
                 continue
             if self.is_resource(path):
-                wres = storage.open_resource(path,'wb')
-                res  = self.open_resource(path,"rb")
-                wres.write(res.read())
-                wres.close()
-                res.close()
+                # Optimization for direct file to ZIP export.
+                # There's no need to juggle the data through ConE code
+                # when we can just write the file directly into the ZIP
+                if isinstance(storage, zipstorage.ZipStorage):
+                    source_abspath = os.path.join(self.rootpath, path)
+                    logging.getLogger("cone").debug("Exporting directly from file to ZIP: %r -> %r" % (source_abspath, path))
+                    storage.zipfile.write(source_abspath, path)
+                else:
+                    wres = storage.open_resource(path,'wb')
+                    res  = self.open_resource(path,"rb")
+                    wres.write(res.read())
+                    wres.close()
+                    res.close()
                 
                 
             if  self.is_folder(path) and  empty_folders:
@@ -235,7 +245,7 @@
         Create a folder entry to a path
         @param path : path to the folder
         """
-        
+        path = utils.resourceref.remove_begin_slash(path)
         path = utils.resourceref.join_refs([self.get_path(), self.get_current_path(), path])
         if not os.path.exists(path):
             os.makedirs(path)
@@ -289,13 +299,15 @@
         if self.is_resource(path):
             res = self.open_resource(path,"r")
             # read the resource with persistentmodule
+            parsecontext.get_confml_context().current_file = path
             try:
                 obj = self.persistentmodule.loads(res.read())
                 #obj.set_path(path)
                 res.close()
                 return obj
             except exceptions.ParseError,e:
-                logging.getLogger('cone').error("Resource %s parsing failed with exception: %s" % (path,e))
+                parsecontext.get_confml_context().handle_exception(e)
+                #logging.getLogger('cone').error("Resource %s parsing failed with exception: %s" % (path,e))
                 # returning an empty config in case of xml parsing failure.
                 return api.Configuration(path)
         else:
@@ -345,6 +357,6 @@
         data = self.handle.read()
         self.handle.seek(orig_pos, os.SEEK_SET)
         if self.content_info == None:
-            self.content_info = utils.make_content_info(self, data)
+            self.content_info = api.make_content_info(self, data)
         
         return self.content_info
--- a/configurationengine/source/cone/storage/metadata.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/storage/metadata.py	Tue Aug 10 14:29:28 2010 +0300
@@ -24,8 +24,10 @@
             from xml.etree import cElementTree as ElementTree
         except ImportError:
             from xml.etree import ElementTree
+
 import StringIO
 import os
+import logging
 
 from cone.public import exceptions, persistence
 
@@ -42,13 +44,13 @@
         self.data = {}
         if copyobj != None:
             self.data = copyobj.data.copy()
-        pass
 
     def get_root_file(self):
-        return self.data.get(self.META_ROOT_FILE,"")
+        return self.data.get(self.META_ROOT_FILE, None)
 
     def set_root_file(self,filename):
-        self.data[self.META_ROOT_FILE] = filename
+        if filename:
+            self.data[self.META_ROOT_FILE] = filename
 
 class MetadataReader(persistence.ConeReader):
     """
@@ -56,16 +58,16 @@
     """ 
     class_type = "Metadata"
     NAMESPACES = ['http://www.nokia.com/xml/ns/confml-core/metadata-2.0']
-    def __init__(self):
-        return
     
     def fromstring(self, xml_as_string):
         meta = Metadata()
-        etree = ElementTree.fromstring(xml_as_string)
-        iter = etree.getiterator("{%s}property" % self.NAMESPACES[0])
-        for elem in iter:
-            (key,value) = self.get_property(elem)
-            meta.data[key] = value
+        try:
+            etree = ElementTree.fromstring(xml_as_string)
+            for elem in etree.getiterator("{%s}property" % self.NAMESPACES[0]):
+                (key,value) = self.get_property(elem)
+                meta.data[key] = value
+        except Exception,e:
+            logging.getLogger('cone').warning("Could not read metadata! Exception %s" % (e))
         return meta
 
     def get_property(self, elem):
@@ -82,6 +84,7 @@
     NAMESPACES = ['http://www.nokia.com/xml/ns/confml-core/metadata-2.0']
     DEFAULT_ENCODING = "ASCII"
     def __init__(self):
+        super(MetadataWriter, self).__init__()
         self.encoding = self.DEFAULT_ENCODING
         return
     
@@ -100,6 +103,18 @@
             self.set_property(prop, key, obj.data[key])
         if indent:
             persistence.indent(root)
+        
+        # To make the output the same in linux and windows
+        # (needed to make testing easier)
+        class LinesepNormalizerResource(object):
+            def __init__(self, resource):
+                self.resource = resource
+            def write(self, data):
+                if os.linesep != '\r\n':
+                    data = data.replace(os.linesep, '\r\n')
+                self.resource.write(data)
+        res = LinesepNormalizerResource(res)
+        
         # some smarter way to implement adding of the encoding to the beginning of file
         res.write('<?xml version="1.0" encoding="%s"?>%s' % (self.encoding,os.linesep))
         ElementTree.ElementTree(root).write(res)
@@ -108,4 +123,4 @@
         elem.attrib['name'] = key
         if value != '':
             elem.attrib['value'] = value
-        return elem
\ No newline at end of file
+        return elem
--- a/configurationengine/source/cone/storage/stringstorage.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/storage/stringstorage.py	Tue Aug 10 14:29:28 2010 +0300
@@ -62,9 +62,12 @@
     A general base class for all storage type classes
     @param path : the reference to the root of the storage.
     """
-    def __init__(self, path):
+    def __init__(self, path, mode='r'):
         container.ObjectContainer.__init__(self,"")
-        api.Storage.__init__(self,path)
+        api.Storage.__init__(self, path, mode)
+
+    def __reduce_ex__(self, protocol_version):
+        return  super(container.ObjectContainer, self).__reduce_ex__(protocol_version)
 
     def __getstate__(self):
         dict = self.__dict__.copy()
@@ -189,7 +192,7 @@
             if not res.get_mode() == api.Storage.MODE_READ:
                 self._get(utils.resourceref.to_dref(res.path)).data = res.getvalue()
         except KeyError,e:
-            raise StorageException("No such %s open resource! %s" % (res.path,e))
+            raise exceptions.StorageException("No such %s open resource! %s" % (res.path,e))
             
 
     def save_resource(self, res):
@@ -213,7 +216,7 @@
         path = utils.resourceref.join_refs([self.get_current_path(), path])
         return self._has(utils.resourceref.to_dref(path))
 
-    def list_resources(self,path,recurse=False,empty_folders=False):
+    def list_resources(self, path, **kwargs):
         """
         find the resources under certain path/path 
         @param path : reference to path where resources are searched
@@ -224,14 +227,17 @@
         try:
             curelem = self._get(utils.resourceref.to_dref(self.get_current_path()))
             dref = utils.resourceref.to_dref(path)
-            if recurse:
-                return sorted([child.path_to_elem(curelem) for child in curelem._get(dref)._traverse(type=_StringStorageObject)])
-            else:
-                return sorted([child.path_to_elem(curelem) for child in curelem._get(dref)._objects(type=_StringStorageObject)])
+            elems = sorted([child.path_to_elem(curelem) for child in curelem._get(dref)._objects(type=_StringStorageObject)])
+            if kwargs.get('recurse', False):
+                # Recursively call list_resources to subelements that are of 'folder' type
+                folders = [child._name for child in curelem._get(dref)._objects() if child.__class__  == container.ObjectContainer]
+                for folderpath in sorted(folders):
+                    elems += self.list_resources(utils.resourceref.join_refs([path,folderpath]), **kwargs)
+            return elems
         except exceptions.NotFound:
             return []
         
-    def import_resources(self,paths,storage,empty_folders=False):
+    def import_resources(self, paths, storage, **kwargs):
         for path in paths:
             if not storage.is_resource(path):
                 logging.getLogger('cone').warning("The given path is not a Resource in the storage %s! Ignoring from export!" % path)
@@ -328,11 +334,11 @@
         else:
             self.handle.write(string)
 
-    def read(self, bytes=0):
-        if self.get_mode() == api.Storage.MODE_WRITE:
-            raise exceptions.StorageException("Reading attempted to %s in write-only mode." % self.path)
-        else:
-            self.handle.read(string)
+#    def read(self, length=0):
+#        if self.get_mode() == api.Storage.MODE_WRITE:
+#            raise exceptions.StorageException("Reading attempted to %s in write-only mode." % self.path)
+#        else:
+#            self.handle.read(length)
 
     def save(self):
         self.storage.save_resource(self)
@@ -348,6 +354,6 @@
 
     def get_content_info(self):
         if self.content_info == None:
-            self.content_info = utils.make_content_info(self, self.handle.getvalue())
+            self.content_info = api.make_content_info(self, self.handle.getvalue())
         
         return self.content_info
--- a/configurationengine/source/cone/storage/tests/__init__.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/storage/tests/__init__.py	Tue Aug 10 14:29:28 2010 +0300
@@ -13,37 +13,3 @@
 #
 # Description: 
 #
-
-import unittest, os, sys
-
-ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
-SOURCE_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../../..'))
-TESTAUTO_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../../../testautomation'))
-if SOURCE_ROOT not in sys.path:
-    sys.path.insert(0,SOURCE_ROOT)
-if TESTAUTO_ROOT not in sys.path:
-    sys.path.insert(0,TESTAUTO_ROOT)
-
-# Find all unittest_*.py files in this folder
-import re
-__all__ = filter(lambda name: re.match(r'^unittest_.*\.py$', name) != None, os.listdir(ROOT_PATH))
-# Strip .py endings
-__all__ = map(lambda name: name[:-3], __all__)
-
-def collect_suite():  
-    sys.path.insert(0, ROOT_PATH)
-    try:
-        suite = unittest.TestSuite()
-        for test_module in __all__:
-            # Load the test module dynamically and add it to the test suite
-            module = __import__(test_module)
-            suite.addTests(unittest.TestLoader().loadTestsFromModule(module))
-        return suite
-    finally:
-        del sys.path[0]
-
-def runtests():
-    unittest.TextTestRunner(verbosity=2).run(collect_suite())
-
-if __name__ == '__main__':
-    runtests()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/storage/tests/fileres_test/test_getsize.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,1 @@
+Writing foobar
\ No newline at end of file
--- a/configurationengine/source/cone/storage/tests/runtests.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/storage/tests/runtests.py	Tue Aug 10 14:29:28 2010 +0300
@@ -14,6 +14,6 @@
 # Description: 
 #
 
-import __init__
-
-__init__.runtests()
\ No newline at end of file
+if __name__ == '__main__':
+    import nose
+    nose.core.run(argv=['collector','--include=unittest', '--verbosity=3'])
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/storage/tests/unittest_authenticate.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,46 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import unittest
+import os
+
+from cone.storage import authenticate
+
+ROOT_PATH   = os.path.dirname(os.path.abspath(__file__))
+
+class TestCarbonAuthHandler(unittest.TestCase):
+    def setUp(self):
+        self.test_user   = "admin"
+        self.test_passwd = "minda"
+        
+    def callback_username(self):
+        return self.test_user
+
+    def callback_password(self):
+        return self.test_passwd
+        
+    def test_username_password_func(self):
+        carbon_handler = authenticate.CarbonAuthHandler()
+        carbon_handler.add_username_func(self.callback_username)
+        carbon_handler.add_password_func(self.callback_password)
+        username = carbon_handler.get_username()
+        password = carbon_handler.get_password()
+        self.assertEqual(self.test_user,username)
+        self.assertEqual(self.test_passwd,password)        
+   
+if __name__ == '__main__':
+    unittest.main()
+
--- a/configurationengine/source/cone/storage/tests/unittest_fileresource.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/storage/tests/unittest_fileresource.py	Tue Aug 10 14:29:28 2010 +0300
@@ -19,14 +19,11 @@
 Test the CPF root file parsing routines
 """
 
-import zipfile
 import unittest
-import string
-import sys,os
+import os
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
 
-import __init__
-from cone.public.exceptions import NotResource, StorageException
+from cone.public.exceptions import StorageException
 from cone.public import api
 from cone.storage import filestorage
 
@@ -151,12 +148,12 @@
         res.close()
         
     def test_get_content_info_and_read_data(self):
-        res = self.storage.open_resource("testread.txt", "r")
+        res = self.storage.open_resource("testread.txt", "rb")
         ci = res.get_content_info()
         self.assertEquals('text/plain', ci.content_type)
         data = res.read()
-        self.assertEquals('foo bar test.\n', data)
+        self.assertEquals('foo bar test.\r\n', data)
         res.close()
         
 if __name__ == '__main__':
-      unittest.main()
+    unittest.main()
--- a/configurationengine/source/cone/storage/tests/unittest_filestorage.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/storage/tests/unittest_filestorage.py	Tue Aug 10 14:29:28 2010 +0300
@@ -25,7 +25,6 @@
 import sys,os,shutil
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
 
-import __init__
 from cone.public.exceptions import NotResource,StorageException
 from cone.public import api 
 from cone.storage import filestorage
@@ -35,103 +34,118 @@
 datafolder= os.path.join(ROOT_PATH,"data")
 
 
-class TestFileStorageCreation(unittest.TestCase):    
-    def setUp(self):
-        pass
-
-    def test_create_storage_on_non_existing_path_fails(self):
-        try:
-            storage = filestorage.FileStorage("dummydatafolder")
-            self.fail("opening on dummydatafolder succeeds?")
-        except StorageException,e:
-            self.assertTrue(True)
-
-    def test_create_storage_on_file_fails(self):
-        try:
-            storage = filestorage.FileStorage(datazip)
-            self.fail("opening on data file succeeds?")
-        except StorageException,e:
-            self.assertTrue(True)
-
-    def test_create_storage_on_new_directory(self):
-        storage = filestorage.FileStorage("dummytest/storage","w")
-        self.assertTrue(os.path.exists("dummytest/storage"))
-        shutil.rmtree("dummytest")
-
+#class TestFileStorageCreation(unittest.TestCase):    
+#    def setUp(self):
+#        pass
+#    def test_create_storage_on_non_existing_path_fails(self):
+#        try:
+#            storage = filestorage.FileStorage("dummydatafolder")
+#            self.fail("opening on dummydatafolder succeeds?")
+#        except StorageException,e:
+#            self.assertTrue(True)
+#
+#    def test_create_storage_on_file_fails(self):
+#        try:
+#            storage = filestorage.FileStorage(datazip)
+#            self.fail("opening on data file succeeds?")
+#        except StorageException,e:
+#            self.assertTrue(True)
+#
+#    def test_create_storage_on_new_directory(self):
+#        storage = filestorage.FileStorage("dummytest/storage","w")
+#        self.assertTrue(os.path.exists("dummytest/storage"))
+#        shutil.rmtree("dummytest")
+#
 class TestFileStorage(unittest.TestCase):    
-    def setUp(self):
-        self.storage = filestorage.FileStorage(datafolder)
-
-    def test_supported_storage(self):        
-        self.assertTrue(filestorage.FileStorage.supported_storage("C:/GenerationRegressionTest/wc/genregtest_workdir/cone_vs_ct2/pf7132_020.006/config_project/"))
-        self.assertTrue(filestorage.FileStorage.supported_storage("C:/GenerationRegressionTest/wc/genregtest_workdir"))
-        self.assertFalse(filestorage.FileStorage.supported_storage("C:/GenerationRegressionTest/wc/genregtest_workdir.zip"))
-    
-    def test_open_resource_existing_file_for_reading(self):
-        res = self.storage.open_resource("simple.confml")
-        self.assertTrue(res)
-        self.assertTrue(isinstance(res,api.Resource))
-
-    def test_open_resource_new_file(self):
-        res = self.storage.open_resource("newfile.txt","w")
-        self.assertTrue(res)
-        self.assertTrue(isinstance(res,api.Resource))
-        res.close()
-        self.assertTrue(os.path.exists(datafolder+"/newfile.txt"))
-        os.remove(datafolder+"/newfile.txt")
-
-    def test_list_resources(self):
-        self.assertEquals(self.storage.list_resources("."),
-                          ['.metadata', 'morestuff.confml', 'prodX.confml', 'simple.confml'])
-        
-    def test_delete_resource(self):
-        tf = open(os.path.join(datafolder,"tempfile.txt"),"w")
-        tf.close()
-        res = self.storage.delete_resource("tempfile.txt")
-        self.assertFalse(os.path.exists(datafolder+"tempfile.txt"))
-        
-    def test_open_resource_nonexisting(self):
-        try:
-            res = self.storage.open_resource("iamnothere.txt")
-            self.fail("Opening of a non existing file succeeds!??")
-        except NotResource: 
-            self.assertTrue(True)
-
-    def test_list_resources_nonrecurse(self):
-        file_array = self.storage.list_resources("")
-        self.assertEquals(file_array[0],".metadata")
-
-    def test_list_resources_nonrecurse_from_root(self):
-        file_array = self.storage.list_resources("/")
-        self.assertTrue(file_array.index(".metadata")==0)
-
-    def test_list_resources_recurse_from_root(self):
-        file_array = self.storage.list_resources("",True)
-        self.assertEquals(file_array[0],".metadata")
-
-    def test_list_resources_from_subfolder(self):
-        file_array = self.storage.list_resources("familyX")
-        self.assertEquals(file_array[0],"familyX/root.confml")
-
-    def test_list_resources_recurse_from_subfolder(self):
-        file_array = self.storage.list_resources("familyX", True)
-        self.assertEquals(file_array[0],"familyX/root.confml")
-        # Count only non-SVN files
-        self.assertEquals(len(filter(lambda x: x.find('.svn') == -1, file_array)), 7)
-
-    def test_is_resource_true(self):
-        self.assertTrue(self.storage.is_resource("simple.confml"))
-
-    def test_is_resource_true_with_begin_slash(self):
-        self.assertTrue(self.storage.is_resource("/simple.confml"))
-
-    def test_is_resource_false(self):
-        self.assertFalse(self.storage.is_resource("data"))
-
-    def test_open_resource_existing_file_with_root(self):
-        res = self.storage.open_resource("/simple.confml")
-        self.assertTrue(res)
-        self.assertTrue(isinstance(res,api.Resource))
+#    def setUp(self):
+#        self.storage = filestorage.FileStorage(datafolder)
+#
+#    def test_supported_storage(self):        
+#        self.assertTrue(filestorage.FileStorage.supported_storage("C:/GenerationRegressionTest/wc/genregtest_workdir/cone_vs_ct2/pf7132_020.006/config_project/"))
+#        self.assertTrue(filestorage.FileStorage.supported_storage("C:/GenerationRegressionTest/wc/genregtest_workdir"))
+#        self.assertFalse(filestorage.FileStorage.supported_storage("C:/GenerationRegressionTest/wc/genregtest_workdir.zip"))
+#    
+#    def test_open_resource_existing_file_for_reading(self):
+#        res = self.storage.open_resource("simple.confml")
+#        self.assertTrue(res)
+#        self.assertTrue(isinstance(res,api.Resource))
+#
+#    def test_open_resource_new_file(self):
+#        res = self.storage.open_resource("newfile.txt","w")
+#        self.assertTrue(res)
+#        self.assertTrue(isinstance(res,api.Resource))
+#        res.close()
+#        self.assertTrue(os.path.exists(datafolder+"/newfile.txt"))
+#        os.remove(datafolder+"/newfile.txt")
+#
+#    def test_list_resources(self):
+#        self.assertEquals(sorted(self.storage.list_resources(".")),
+#                          sorted(['.metadata', 'morestuff.confml', 'prodX.confml', 'simple.confml']))
+#        
+#    def test_delete_resource(self):
+#        tf = open(os.path.join(datafolder,"tempfile.txt"),"w")
+#        tf.close()
+#        res = self.storage.delete_resource("tempfile.txt")
+#        self.assertFalse(os.path.exists(datafolder+"tempfile.txt"))
+#        
+#    def test_open_resource_nonexisting(self):
+#        try:
+#            res = self.storage.open_resource("iamnothere.txt")
+#            self.fail("Opening of a non existing file succeeds!??")
+#        except NotResource: 
+#            self.assertTrue(True)
+#
+#    def test_list_resources_nonrecurse(self):
+#        file_array = self.storage.list_resources("")
+#        self.assertTrue(".metadata" in file_array)
+#
+#    def test_list_resources_nonrecurse_from_root(self):
+#        file_array = self.storage.list_resources("/")
+#        self.assertTrue(".metadata" in file_array)
+#
+#    def test_list_resources_recurse_from_root(self):
+#        file_array = self.storage.list_resources("",True)
+#        self.assertTrue(".metadata" in file_array)
+#
+#    def test_list_resources_from_subfolder(self):
+#        file_array = self.storage.list_resources("familyX")
+#        self.assertTrue("familyX/root.confml" in file_array)
+#
+#    def test_list_resources_recurse_from_subfolder(self):
+#        file_array = self.storage.list_resources("familyX", True)
+#        self.assertTrue("familyX/root.confml" in file_array)
+#        # Count only non-SVN files
+#        self.assertEquals(len(filter(lambda x: x.find('.svn') == -1, file_array)), 7)
+#
+#    def test_is_resource_true(self):
+#        self.assertTrue(self.storage.is_resource("simple.confml"))
+#
+#    def test_is_resource_true_with_begin_slash(self):
+#        self.assertTrue(self.storage.is_resource("/simple.confml"))
+#
+#    def test_is_resource_false(self):
+#        self.assertFalse(self.storage.is_resource("data"))
+#
+#    def test_open_resource_existing_file_with_root(self):
+#        res = self.storage.open_resource("/simple.confml")
+#        self.assertTrue(res)
+#        self.assertTrue(isinstance(res,api.Resource))
+#
+#
+#    def test_create_folder(self):
+#        store = filestorage.FileStorage("newtestfolder","w")
+#        store.create_folder("subdir")
+#        self.assertTrue(store.is_folder("subdir"))
+#        self.assertTrue(os.path.exists("newtestfolder/subdir"))
+#        store.create_folder('foo')
+#        layer = api.Folder(store, "foo")
+#        self.assertTrue(store.is_folder("foo"))
+#        self.assertTrue(layer)
+#        self.assertTrue(os.path.exists("newtestfolder/subdir"))
+#        layer.create_folder("foosubdir")
+#        self.assertTrue(store.is_folder("foo/foosubdir"))
+#        self.assertTrue(os.path.exists("newtestfolder/foo/foosubdir"))
+#        shutil.rmtree('newtestfolder')
 
     def test_metadata_writing(self):
         fs = filestorage.FileStorage("testtemp","w")
@@ -141,21 +155,7 @@
         self.assertEquals(fs.get_active_configuration(),'testing.confml')
         fs.close()
         shutil.rmtree("testtemp")
-
-    def test_create_folder(self):
-        store = filestorage.FileStorage("newtestfolder","w")
-        store.create_folder("subdir")
-        self.assertTrue(store.is_folder("subdir"))
-        self.assertTrue(os.path.exists("newtestfolder/subdir"))
-        store.create_folder('foo')
-        layer = api.Folder(store, "foo")
-        self.assertTrue(store.is_folder("foo"))
-        self.assertTrue(layer)
-        self.assertTrue(os.path.exists("newtestfolder/subdir"))
-        layer.create_folder("foosubdir")
-        self.assertTrue(store.is_folder("foo/foosubdir"))
-        self.assertTrue(os.path.exists("newtestfolder/foo/foosubdir"))
-        shutil.rmtree('newtestfolder')
+       
 
 if __name__ == '__main__':
-      unittest.main()
+    unittest.main()
--- a/configurationengine/source/cone/storage/tests/unittest_filestorage_layer.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/storage/tests/unittest_filestorage_layer.py	Tue Aug 10 14:29:28 2010 +0300
@@ -18,137 +18,69 @@
 Test the configuration
 """
 import unittest
-import string
-import sys,os, shutil
-import __init__
+import os
 
-from cone.public import api,exceptions,utils
-from cone.storage import filestorage
+from cone.storage import filestorage, zipstorage
+from cone.public.tests import unittest_layer
+from testautomation.utils import remove_if_exists
 
-class TestLayer(unittest.TestCase):    
-    storage_class = filestorage.FileStorage
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+LAYER_TMP_FOLDER = os.path.join(ROOT_PATH, "temp/layertest")
+LAYER_TMP_ZIP = os.path.join(ROOT_PATH, "temp/layertest.zip")
 
-    def test_create_layer(self):
-        store = self.storage_class("temp/layertest","w")
-        layer = api.Layer(store, "foo")
-        self.assertTrue(layer)
-        shutil.rmtree("temp/layertest")
+##########################################################################
+# FileStorage tests for folder and layer actions
 
-#    def test_create_layer_with_kwargs(self):
-#        store = self.storage_class("temp/layertest","w")
-#        layer = api.Layer(store, "foo",confml_path="foobar", implml_path="")
-#        self.assertTrue(layer)
-#        self.assertEquals(layer.confml_folder.get_current_path(),"foo/foobar")
-#        self.assertEquals(layer.implml_folder.get_current_path(),"foo")
-#        layer = api.Layer(store, "foo",confml_path="f", implml_path="test", content_path="data", doc_path="foo")
-#        self.assertEquals(layer.confml_folder.get_current_path(),"foo/f")
-#        self.assertEquals(layer.implml_folder.get_current_path(),"foo/test")
-#        self.assertEquals(layer.content_folder.get_current_path(),"foo/data")
-#        self.assertEquals(layer.doc_folder.get_current_path(),"foo/foo")
-#        layer = api.Layer(store, "foo")
-#        self.assertEquals(layer.confml_folder.get_current_path(),"foo/confml")
-#        self.assertEquals(layer.implml_folder.get_current_path(),"foo/implml")
-#        self.assertEquals(layer.content_folder.get_current_path(),"foo/content")
-#        self.assertEquals(layer.doc_folder.get_current_path(),"foo/doc")
-#        shutil.rmtree("temp/layertest")
+class TestFolderOnFileStorage(unittest_layer.TestFolder):
+    def setUp(self):
+        self.store = filestorage.FileStorage(LAYER_TMP_FOLDER,"w")
+
+    def tearDown(self):
+        remove_if_exists(LAYER_TMP_FOLDER)
 
-    def test_get_path(self):
-        store = self.storage_class("temp/layertest","w")
-        layer = api.Layer(store, "foo")
-        self.assertTrue(layer)
-        self.assertEquals(layer.get_current_path(),"foo")
-        shutil.rmtree("temp/layertest")
+class TestLayerOnFileStorage(unittest_layer.TestLayer):
+    def setUp(self):
+        self.store = filestorage.FileStorage(LAYER_TMP_FOLDER,"w")
 
-    def test_open_resource(self):
-        store = self.storage_class("temp/layertest","w")
-        layer = api.Layer(store, "foo")
-        self.assertTrue(layer)
-        res = layer.open_resource("confml/test.confml","w")
-        res.write("foo.conf")
-        res.close()
-        self.assertEquals(layer.list_resources("", True),["confml/test.confml"])
-        self.assertEquals(store.list_resources("", True),["foo/confml/test.confml"])
-        shutil.rmtree("temp/layertest")
+    def tearDown(self):
+        remove_if_exists(LAYER_TMP_FOLDER)
+
+class TestCompositeLayerOnFileStorage(unittest_layer.TestCompositeLayer):
+    def setUp(self):
+        self.store = filestorage.FileStorage(LAYER_TMP_FOLDER,"w")
 
-    def test_create_two_layers_and_open_resource(self):
-        store = self.storage_class("temp/layertest","w")
-        foo_layer = api.Layer(store, "foo")
-        bar_layer = api.Layer(store, "bar")
-        res = foo_layer.open_resource("confml/test.confml","w")
-        res.write("foo.conf")
-        res.close()
-        res = foo_layer.open_resource("root.confml","w")
-        res.close()
-        res = bar_layer.open_resource("confml/root.confml","w")
-        res.write("foo.conf")
-        res.close()
-        self.assertEquals(foo_layer.list_resources("", True),['root.confml', 'confml/test.confml'])
-        self.assertEquals(store.list_resources("", True),['bar/confml/root.confml','foo/root.confml','foo/confml/test.confml'])
-        foo_layer.delete_resource("confml/test.confml")
-        self.assertEquals(foo_layer.list_resources("", True),["root.confml"])
-        self.assertEquals(store.list_resources("", True),["bar/confml/root.confml","foo/root.confml"])
-        shutil.rmtree("temp/layertest")
+    def tearDown(self):
+        remove_if_exists(LAYER_TMP_FOLDER)
 
-    def test_list_confml(self):
-        store = self.storage_class("temp/layertest","w")
-        layer = api.Layer(store, "foo")
-        res = layer.open_resource("confml/test.confml","w")
-        res.write("foo.conf")
-        res.close()
-        res = layer.open_resource("confml/foo.confml","w")
-        res.write("foo.conf")
-        res.close()
-        res = layer.open_resource("root.confml","w")
-        res.write("foo.conf")
-        res.close()
-        self.assertEquals(layer.list_confml(),['confml/foo.confml', 'confml/test.confml'])
-        shutil.rmtree("temp/layertest")
+##########################################################################
+# ZipStorage
+
 
-    def test_list_implml(self):
-        store = self.storage_class("temp/layertest","w")
-        layer = api.Layer(store, "foo")
-        res = layer.open_resource("implml/stuff/test.confml","w")
-        res.write("foo.conf")
-        res.close()
-        res = layer.open_resource("confml/foo.confml","w")
-        res.write("foo.conf")
-        res.close()
-        res = layer.open_resource("root.confml","w")
-        res.write("foo.conf")
-        res.close()
-        self.assertEquals(layer.list_implml(),['implml/stuff/test.confml'])
-        shutil.rmtree("temp/layertest")
+#class TestFolderOnZipStorage(unittest_layer.TestFolder):
+#    def setUp(self):
+#        self.store = zipstorage.ZipStorage(LAYER_TMP_ZIP,"w")
+#
+#    def tearDown(self):
+#        self.store.close()
+#        remove_if_exists(LAYER_TMP_ZIP)
+#
+#class TestLayerOnZipStorage(unittest_layer.TestLayer):
+#    def setUp(self):
+#        self.store = zipstorage.ZipStorage(LAYER_TMP_ZIP,"w")
+#
+#    def tearDown(self):
+#        self.store.close()
+#        remove_if_exists(LAYER_TMP_ZIP)
+#
+#class TestCompositeLayerOnZipStorage(unittest_layer.TestCompositeLayer):
+#    def setUp(self):
+#        self.store = zipstorage.ZipStorage(LAYER_TMP_ZIP,"w")
+#
+#    def tearDown(self):
+#        self.store.close()
+#        remove_if_exists(LAYER_TMP_ZIP)
 
-    def test_list_content(self):
-        store = self.storage_class("temp/layertest","w")
-        layer = api.Layer(store, "foo")
-        res = layer.open_resource("content/bar/test.txt","w")
-        res.write("foo.conf")
-        res.close()
-        res = layer.open_resource("content/foo.confml","w")
-        res.write("foo.conf")
-        res.close()
-        res = layer.open_resource("root.confml","w")
-        res.write("foo.conf")
-        res.close()
-        self.assertEquals(layer.list_content(),['content/foo.confml', 'content/bar/test.txt'])
-        shutil.rmtree("temp/layertest")
-
-    def test_list_doc(self):
-        store = self.storage_class("temp/layertest","w")
-        layer = api.Layer(store, "foo")
-        res = layer.open_resource("doc/bar/test.txt","w")
-        res.write("foo.conf")
-        res.close()
-        res = layer.open_resource("doc/foo.confml","w")
-        res.write("foo.conf")
-        res.close()
-        res = layer.open_resource("root.confml","w")
-        res.write("foo.conf")
-        res.close()
-        self.assertEquals(layer.list_doc(),['doc/foo.confml', 'doc/bar/test.txt'])
-        shutil.rmtree("temp/layertest")
 
 if __name__ == '__main__':
-      unittest.main()
-      
+    unittest.main()
+
--- a/configurationengine/source/cone/storage/tests/unittest_filestorage_vs_zipstorage.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/storage/tests/unittest_filestorage_vs_zipstorage.py	Tue Aug 10 14:29:28 2010 +0300
@@ -21,7 +21,6 @@
 
 import unittest
 import sys, os, shutil
-import __init__
 
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
 
--- a/configurationengine/source/cone/storage/tests/unittest_metadata.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/storage/tests/unittest_metadata.py	Tue Aug 10 14:29:28 2010 +0300
@@ -18,7 +18,7 @@
 """
 Test the CPF metadata file parsing routines
 """
-import os, sys, unittest
+import os, unittest
 try:
     from cElementTree import ElementTree
 except ImportError:
@@ -30,9 +30,7 @@
         except ImportError:
             from xml.etree import ElementTree
 
-import __init__
-
-from cone.public import utils, exceptions, api
+from cone.public import exceptions
 from cone.storage import metadata, stringstorage
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
 emptytestdata  = '<?xml version="1.0" encoding="ASCII"?>'\
@@ -64,7 +62,7 @@
         m = metadata.MetadataReader().fromstring(testdata)
         self.assertTrue(m)
         
-    def test_create_meta_fromstring(self):
+    def test_create_meta_fromstring_test_has_key(self):
         m = metadata.MetadataReader().fromstring(testdata)
         self.assertTrue(m.data.has_key('cpf.name'))
         self.assertTrue(m.data.has_key('cpf.description'))
@@ -125,6 +123,12 @@
         meta2 = metadata.MetadataReader().fromstring(str)
         self.assertEqual(meta.data,meta2.data)
 
+    def test_metadata_write_with_empty_data(self):
+        meta = metadata.Metadata()
+        str = metadata.MetadataWriter().tostring(meta)
+        meta2 = metadata.MetadataReader().fromstring(str)
+        self.assertEqual(meta.data,meta2.data)
+
     def test_incorrect_class_fails(self):
         try:
             class dummy:
@@ -137,9 +141,10 @@
         
     def test_set_property(self):
         elem = ElementTree.Element('property')
-        prop = metadata.MetadataWriter().set_property(elem,'test','foof')
-        self.assertTrue(prop.get('name'),'test')
-        self.assertTrue(prop.get('value'),'foof')
+        mwriter = metadata.MetadataWriter()
+        prop_elem = mwriter.set_property(elem,'test','foof')
+        self.assertTrue(prop_elem.get('name'),'test')
+        self.assertTrue(prop_elem.get('value'),'foof')
 
     def test_set_property_with_only_key(self):
         elem = ElementTree.Element('property')
--- a/configurationengine/source/cone/storage/tests/unittest_resource.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/storage/tests/unittest_resource.py	Tue Aug 10 14:29:28 2010 +0300
@@ -20,7 +20,6 @@
 import unittest
 import string
 import sys,os
-import __init__
 
 from cone.public.api import Resource
 from cone.storage.stringstorage import StringResource
--- a/configurationengine/source/cone/storage/tests/unittest_stringstorage.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/storage/tests/unittest_stringstorage.py	Tue Aug 10 14:29:28 2010 +0300
@@ -18,7 +18,6 @@
 import string
 import sys,os
 import pickle
-import __init__
 
 from cone.public import api
 from cone.storage import stringstorage
--- a/configurationengine/source/cone/storage/tests/unittest_webstorage.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/storage/tests/unittest_webstorage.py	Tue Aug 10 14:29:28 2010 +0300
@@ -15,19 +15,14 @@
 #
 
 import unittest
-import string
-import sys,os
-import pickle
-import time
-import __init__
+import os
 
-from cone.public import api, exceptions
 from cone.storage import webstorage
 from cone.carbon import model
 import simplewebserver
 
 ROOT_PATH   = os.path.dirname(os.path.abspath(__file__))
-TEST_SERVER = simplewebserver.SimpleWebServer(os.path.join(ROOT_PATH,'carbondata'), 8001)
+#TEST_SERVER = simplewebserver.SimpleWebServer(os.path.join(ROOT_PATH,'carbondata'), 8001)
 #
 #def runserver():
 #    if not TEST_SERVER.active:
@@ -102,9 +97,15 @@
         self.assertEquals(rc.get_resource_link('test.confml'), 'test.configurationroot')
         self.assertEquals(rc.get_resource_link('featurelists/test.confml'), 'test.featurelist')
         self.assertEquals(rc.get_resource_link('test/root.confml'), 'test.configurationlayer')
+
+
+class TestCarbonExtapi(unittest.TestCase):
+    def test_username_password(self):
+        extapi = webstorage.CarbonExtapi("/")
+        self.assertNotEqual(extapi,None)
+        self.assertNotEqual(extapi.get_username(),"")
     
 
-
 if __name__ == '__main__':
     unittest.main()
 
--- a/configurationengine/source/cone/storage/tests/unittest_webstorage_carbon.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/storage/tests/unittest_webstorage_carbon.py	Tue Aug 10 14:29:28 2010 +0300
@@ -19,7 +19,6 @@
 import sys,os
 import pickle
 import time
-import __init__
 
 from cone.public import api, exceptions
 from cone.storage import webstorage
--- a/configurationengine/source/cone/storage/tests/unittest_zipresource.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/storage/tests/unittest_zipresource.py	Tue Aug 10 14:29:28 2010 +0300
@@ -21,14 +21,11 @@
 
 import zipfile
 import unittest
-import string
-import sys,os,shutil
+import os,shutil
 
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
 
-import __init__
-from cone.public.exceptions import *
-from cone.public.api import Resource
+from cone.public import exceptions 
 from cone.storage import zipstorage
 
 TEMP_DIR = os.path.join(ROOT_PATH, 'temp')
@@ -99,7 +96,7 @@
         store = zipstorage.ZipStorage(ZIPFILE, "w")
         res = store.open_resource("test_getsize.txt", "w")
         res.write("Writing foobar")
-        self.assertRaises(StorageException, res.get_size)
+        self.assertRaises(exceptions.StorageException, res.get_size)
         res.close()
         store.close()
 
@@ -116,4 +113,4 @@
 
         
 if __name__ == '__main__':
-      unittest.main()
+    unittest.main()
--- a/configurationengine/source/cone/storage/tests/unittest_zipstorage.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/storage/tests/unittest_zipstorage.py	Tue Aug 10 14:29:28 2010 +0300
@@ -19,14 +19,11 @@
 Test the CPF root file parsing routines
 """
 
-import zipfile
 import unittest
-import string
-import sys,os,shutil
+import os,shutil
 
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
 
-import __init__
 from cone.public import exceptions, api
 from cone.storage import zipstorage
 
@@ -95,7 +92,7 @@
         self.assertTrue(res)
         self.assertTrue(isinstance(res,api.Resource))
         res.close()
-        self.assertEquals(storage.list_resources("",True), ['data/newfile.txt'])
+        self.assertEquals(storage.list_resources("",recurse=True), ['data/newfile.txt'])
         storage.close()
         os.unlink("testnewfile.zip")
         
@@ -127,7 +124,7 @@
         res.close()
         res = storage.open_resource("data/ncp11/confml/jallaa.confml","w")
         res.close()
-        file_array = storage.list_resources("data",True)
+        file_array = storage.list_resources("data",recurse=True)
         self.assertEquals(file_array,['data/foo/morestuff.confml', 'data/prodX.confml', 'data/ncp11/confml/jallaa.confml'])
         storage.close()
         os.unlink("testrecurse.zip")
@@ -185,13 +182,13 @@
         res.close()
         storage.close()
         storage2 = api.Storage.open("testdelete.zip","a")
-        #self.assertEquals(storage2.list_resources("",True), ['.metadata', 'data/newfile.txt', 'readme.txt'])
+        #self.assertEquals(storage2.list_resources("",recurse=True), ['.metadata', 'data/newfile.txt', 'readme.txt'])
         self.assertEquals(storage2.open_resource("data/newfile.txt").read(),"test write")
         storage2.delete_resource("data/newfile.txt")
-        self.assertEquals(len(storage2.list_resources("",True)),2)
+        self.assertEquals(len(storage2.list_resources("",recurse=True)),2)
         storage2.close()
         storage3 = api.Storage.open("testdelete.zip","a")
-        self.assertEquals(storage3.list_resources("",True), ['readme.txt','.metadata'])
+        self.assertEquals(storage3.list_resources("",recurse=True), ['readme.txt','.metadata'])
         storage3.close()
         os.unlink("testdelete.zip")
         
@@ -210,7 +207,7 @@
         self.assertEquals(storage2.is_folder("data"),True)
         self.assertEquals(storage2.is_folder("data2/folder1"),True)
         self.assertEquals(storage2.is_folder("data3"),True)
-        self.assertEquals(storage2.list_resources('.',True),['test.txt','.metadata'])
+        self.assertEquals(storage2.list_resources('.',recurse=True),['test.txt','.metadata'])
         self.assertEquals(storage2.list_resources(''),['test.txt','.metadata'])
         storage2.close()
         os.unlink("empty_folder.zip")
--- a/configurationengine/source/cone/storage/webstorage.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/storage/webstorage.py	Tue Aug 10 14:29:28 2010 +0300
@@ -28,7 +28,7 @@
 import posixpath
 
 from cone.public import *
-from cone.carbon import persistentjson, model
+from cone.carbon import persistentjson, model, resourcemapper
 from cone.storage import authenticate
 
 class WebStorage(api.Storage):
@@ -55,9 +55,9 @@
         try:
             object_type = object.meta.get('type')
         except (TypeError,AttributeError):
-            logging.getLogger('cone').error('Cannot dump configuration %s to webstorage without a type.' % path)
+            logging.getLogger('cone').info('Cannot dump configuration %s to webstorage without a type.' % path)
             return False
-        carbonpath = persistentjson.CarbonResourceMapper().map_confml_resource(object_type, path)
+        carbonpath = resourcemapper.CarbonResourceMapper().map_confml_resource(object_type, path)
         if object_type == 'featurelist':
             # Create a featurelist 
             success = self.extapi.create_featurelist(carbonpath, object)
@@ -93,7 +93,11 @@
         """
         if not self._resource_cache: 
             self._resource_cache = ResourceCache()
-            reslist = self.extapi.list_resources("/", True)
+            try:
+                reslist = self.extapi.list_resources("/", True)
+            except urllib2.HTTPError, e:
+                print e
+                return []
             # Append all resources to resource cache
             for res in reslist:
                 self._resource_cache.add_resource(res)
@@ -103,7 +107,7 @@
 #                        self._resource_cache.add_featurelist(res)
         return self._resource_cache
 
-    def list_resources(self,path, recurse=False, empty_folders=False):
+    def list_resources(self,path, **kwargs):
         """
         find the resources under certain path/path 
         @param path : reference to path where resources are searched
@@ -112,7 +116,7 @@
         @param empty_folders: parameters that defined whether empty folders are included. This parameter is ignored 
         in WebStorage. 
         """
-        return self.resource_cache.list_resources(path,recurse)
+        return self.resource_cache.list_resources(path, kwargs.get('recurse', False))
 
 
     def open_resource(self,path,mode="r"):
@@ -141,7 +145,14 @@
             raise exceptions.NotResource("The given resource is not found %s" % path)
 
     def is_resource(self,path):
-        return self.resource_cache.is_resource(path)
+        ret= self.resource_cache.is_resource(path)
+        if not ret:
+            try:
+                mapped = self.resource_cache.get_mapped_resource(path)
+                ret = self.extapi.is_resource(mapped)
+            except Exception:
+                pass
+        return ret
 #        path = path.replace(".confml", ".configuration")
 #        path = utils.resourceref.join_refs([self.get_current_path(), path])
 #        try:
@@ -191,19 +202,23 @@
         if self.get_mode(self.mode) != api.Storage.MODE_READ:
             if self.resource_cache.get_resource_link(path):
                 path = self.resource_cache.get_resource_link(path)
+            elif self.is_resource(path):
+                 path = self.resource_cache.get_mapped_resource(path)
             else:
                 """ otherwise create the new resource first before update"""
                 if self._create_resource(path, object):
                     path = self.resource_cache.get_resource_link(path)
                 else:
                     # Creation failed
-                    logging.getLogger('cone').error('Creation of %s resource failed' % path)
+                    logging.getLogger('cone').info('Creation of %s resource failed' % path)
                     return 
             data = persistentjson.dumps(object)
             self.extapi.update_resource(path, data)
         else:
             raise exceptions.StorageException("Cannot dump object to readonly storage")
         return
+    
+    
 
     def load(self, path):
         """
@@ -298,21 +313,20 @@
         if len(pathelems) > 1: 
             self.service_path = pathelems[1]
         self._username = kwargs.get('username', None)
-        self._password = kwargs.get('password', None)
+        self._password = kwargs.get('password', None)     
         authhandler = authenticate.CarbonAuthHandler()
-        authhandler.add_password(self.username, self.password)
+        authhandler.add_username_func(self.get_username)
+        authhandler.add_password_func(self.get_password)
         self.conn = urllib2.build_opener(urllib2.HTTPCookieProcessor, authhandler, urllib2.ProxyHandler({}))
         
-    @property
-    def username(self):
+    def get_username(self):
         if self._username == None:
             self._username = getpass.getuser()
         return self._username 
 
-    @property
-    def password(self):
+    def get_password(self):
         if self._password == None:
-            self._password = getpass.getpass()
+            self._password = getpass.getpass("Password (%s):" % self._username)
         return self._password
 
     def checklogin(self):
@@ -389,14 +403,29 @@
             resp = self.conn.open(req)
             if resp.code == httplib.OK:
                 bytes = resp.read()
-                reslist = simplejson.loads(bytes)
-                return reslist.get('resources',[])
+                if bytes:
+                    reslist = simplejson.loads(bytes)
+                    return reslist.get('resources',[])
             else:
                 return []
         except exceptions.NotFound:
             return []
 
+    def is_resource(self, path):
+        try:
+            query = self._get_action_url('is_resource', path)
+            req = urllib2.Request(query)
+            resp = self.conn.open(req)
+            if resp.code == httplib.OK:
+                reader = persistentjson.HasResourceReader()
+                ret = resp.read()
+                return reader.loads(ret)
+            else:
+                return False
+        except exceptions.NotFound:
+            return False
 
+        
     def update_resource(self, path, data):
         """
         Update a resource to carbon. The resource can be a CarbonConfiguration or FeatureList object.
@@ -417,7 +446,12 @@
                 if success:
                     logging.getLogger('cone').info('Carbon update succeeds to path %s.' % (respdata.get('path')))
                 else:
-                    logging.getLogger('cone').error('Carbon update %s failed %s' % (path,respdata.get('errors')))
+                    logging.getLogger('cone').error('Carbon update %s failed!' % (path))
+                if respdata.get('errors'):
+                    formatted_err = "" 
+                    for error in respdata.get('errors'):
+                        formatted_err += "%s: %s\n" % (error,respdata.get('errors')[error])
+                    logging.getLogger('cone').info('Carbon update to path %s returned %s' % (respdata.get('path'),formatted_err))
                 return success
             else:
                 logging.getLogger('cone').error('Carbon update %s failed %s: %s' % (path,resp.code, resp))
@@ -558,7 +592,7 @@
         """
         Add a resource 
         """
-        confmlpath = persistentjson.CarbonResourceMapper().map_carbon_resource(resourcepath)
+        confmlpath = resourcemapper.CarbonResourceMapper().map_carbon_resource(resourcepath)
         self._cache[confmlpath] = resourcepath 
 
     def list_resources(self, path, recurse=False):
@@ -599,7 +633,7 @@
             object_type = 'configurationlayer'
         else:
             object_type = 'configurationroot'
-        carbonpath = persistentjson.CarbonResourceMapper().map_confml_resource(object_type, path)
+        carbonpath = resourcemapper.CarbonResourceMapper().map_confml_resource(object_type, path)
         return carbonpath
 
     def add_resource_link(self,link, path):
--- a/configurationengine/source/cone/storage/zipstorage.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/storage/zipstorage.py	Tue Aug 10 14:29:28 2010 +0300
@@ -13,6 +13,7 @@
 #
 # Description: 
 #
+import shutil
 
 import zipfile,zlib, StringIO, os, logging
 import datetime
@@ -29,7 +30,7 @@
         except ImportError:
             from xml.etree import ElementTree
 
-from cone.public import api, utils, persistence, exceptions
+from cone.public import api, utils, persistence, exceptions, parsecontext
 from cone.public.api import Resource, Storage, Configuration, Folder
 from cone.storage import metadata, common
 from cone.confml import persistentconfml
@@ -46,8 +47,7 @@
     """
     A storage for zip file 
     """
-    TEMP_FILE = '_temp_%i.zip' % os.getpid()
-    def __init__(self, path ,mode, **kwargs):
+    def __init__(self, path, mode, **kwargs):
         """
         Open the given filename object as a cpf zipfile
         """
@@ -61,11 +61,16 @@
             # If opening the file in read/append mode check that the given file is a zipfile
             if self.get_mode(mode) != self.MODE_WRITE:
                 if os.path.exists(path) and not zipfile.is_zipfile(path):
-                    raise ZipException("The file %s is not a zip file!" % path) 
+                    raise ZipException("The file %s is not a zip file!" % path)
+            # If creating a new file make sure that the path to the file exists
+            elif self.get_mode(mode) in (self.MODE_APPEND, self.MODE_WRITE):
+                dirname = os.path.dirname(path)
+                if dirname != '' and not os.path.exists(dirname):
+                    os.makedirs(dirname)
             self.zipfile = zipfile.ZipFile(path,self.mode,self.compression)
         except IOError,e:
             raise ZipException("ZipFile open error: %s" % e)
-        super(ZipStorage, self).__init__(path)
+        super(ZipStorage, self).__init__(path, mode)
 
     def _zippath(self, path):
         """
@@ -140,7 +145,7 @@
         except KeyError:
             return False 
 
-    def list_resources(self,path,recurse=False, empty_folders=False): 
+    def list_resources(self, path, **kwargs): 
         """
         Get an array of files in a folder  
         """
@@ -153,19 +158,20 @@
             (filepath,filename) = os.path.split(name)
             curname = utils.resourceref.replace_dir(name, self.get_current_path(),'')
             # return directories only if specified
-            if empty_folders == True or not self.is_dir(name):
+            if kwargs.get('empty_folders', False) == True or not self.is_dir(name):
                 # Skip the filename if it is marked as deleted
                 if self.__has_open__(name) and self.__get_open__(name)[-1].get_mode() == api.Storage.MODE_DELETE:
                     continue
                 if filepath == fullpath:
                     retarray.append(curname)
-                elif recurse and filepath.startswith(fullpath):
+                elif kwargs.get('recurse', False) and filepath.startswith(fullpath):
                     retarray.append(curname)
         #retarray = sorted(utils.distinct_array(retarray))
         return retarray
 
     def import_resources(self,paths,storage,empty_folders=False):
         for path in paths:
+            path = utils.resourceref.remove_begin_slash(utils.resourceref.norm(path))
             if not storage.is_resource(path) and empty_folders==False:
                 logging.getLogger('cone').warning("The given path is not a Resource in the storage %s! Ignoring from export!" % path)
                 continue
@@ -281,14 +287,15 @@
             if self.modified:
                 oldfile = None
                 newzipfile = None
-                tmp_path = os.path.join(tempfile.gettempdir(), self.TEMP_FILE)
-                os.rename(self.path, tmp_path)
+                fh, tmp_path = tempfile.mkstemp(suffix='.zip')
+                shutil.move(self.path, tmp_path)
                 oldfile = zipfile.ZipFile(tmp_path,"r")
                 newzipfile = zipfile.ZipFile(self.path,"w",self.compression)
                 for fileinfo in oldfile.infolist():
                     newzipfile.writestr(fileinfo, oldfile.read(fileinfo.filename))
                 if oldfile: oldfile.close()
                 if newzipfile: newzipfile.close()
+                os.close(fh)
                 os.unlink(tmp_path)
             self.zipfile = None
         else:
@@ -322,13 +329,15 @@
         if self.is_resource(path):
             res = self.open_resource(path,"r")
             # read the resource with persistentmodule
+            parsecontext.get_confml_context().current_file = path
             try:
                 obj = self.persistentmodule.loads(res.read())
                 obj.set_path(path)
                 res.close()
                 return obj
             except exceptions.ParseError,e:
-                logging.getLogger('cone').error("Resource %s parsing failed with exception: %s" % (path,e))
+                parsecontext.get_confml_context().handle_exception(e)
+                #logging.getLogger('cone').error("Resource %s parsing failed with exception: %s" % (path,e))
                 # returning an empty config in case of xml parsing failure.
                 return api.Configuration(path)
         else:
@@ -372,6 +381,6 @@
 
     def get_content_info(self):
         if self.content_info == None:
-            self.content_info = utils.make_content_info(self, self.handle.getvalue())
+            self.content_info = api.make_content_info(self, self.handle.getvalue())
         
         return self.content_info
\ No newline at end of file
--- a/configurationengine/source/cone/test.xml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/cone/test.xml	Tue Aug 10 14:29:28 2010 +0300
@@ -9,6 +9,7 @@
         <echo message="Running tests..."/>
         <delete file="nose_unittests.xml"/>
         <exec executable="nosetests">
+            <env key="PYTHONPATH" path="..;../testautomation;"/>
             <arg line=" -c nose_unittests.cfg"/>
         </exec>
     </target>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/__init__.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,20 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+import sys,os
+
+__all__ = []
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/builtinvalidators/__init__.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,15 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/builtinvalidators/confml.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,233 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+import logging
+
+from cone.public import api, exceptions, container, utils
+from cone.confml import model
+
+from cone.validation.confmlvalidation import ValidatorBase, FixerBase
+
+class SettingValidatorBase(ValidatorBase):
+    """
+    Base class for validators that validate ConfML settings
+    (sub-classes of cone.confml.model.ConfmlSetting).
+    """
+    def validate(self):
+        for ref, feature in self.context.feature_dict.iteritems():
+            if isinstance(feature._obj, model.ConfmlSetting):
+                self.validate_setting(ref, feature)
+    
+    def validate_setting(self, ref, setting):
+        raise NotImplementedError()
+
+class LengthConstraintValidator(SettingValidatorBase):
+    """
+    Validator for validating xs:length, xs:minLength and xs:maxLength
+    constraints on setting data values.
+    """
+    PROBLEM_TYPES = ['model.confml.invalid_value.length',
+                     'model.confml.invalid_value.minlength',
+                     'model.confml.invalid_value.maxlength']
+    
+    def validate_setting(self, ref, setting):
+        if setting.length:
+            value = setting.get_value()
+            if isinstance(value, basestring) and len(value) != setting.length:
+                self._add_problem(
+                    setting = setting,
+                    msg = "Setting %s: Exact number of characters must be %s (value has %s)" % (ref, setting.length, len(value)),
+                    prob_type = self.PROBLEM_TYPES[0])
+                
+        if setting.minLength:
+            value = setting.get_value()
+            if isinstance(value, basestring) and len(value) < setting.minLength:
+                self._add_problem(
+                    setting = setting,
+                    msg = "Setting %s: Minimum number of characters is %s (value has %s)" % (ref, setting.minLength, len(value)),
+                    prob_type = self.PROBLEM_TYPES[1])
+        
+        if setting.maxLength:
+            value = setting.get_value()
+            if isinstance(value, basestring) and len(value) > setting.maxLength:
+                self._add_problem(
+                    setting = setting,
+                    msg = "Setting %s: Maximum number of characters is %s (value has %s)" % (ref, setting.maxLength, len(value)),
+                    prob_type = self.PROBLEM_TYPES[2])
+   
+    def _add_problem(self, setting, msg, prob_type):
+        dataobj = setting.datas['data'][-1]
+        prob = api.Problem(
+            msg = msg,
+            type = prob_type,
+            line = dataobj.lineno,
+            file = dataobj.get_configuration_path())
+        self.context.problems.append(prob)
+
+class MissingFeatureForDataValidator(ValidatorBase):
+    """
+    Validator for validating data elements that do not have a
+    corresponding feature/setting in the configuration.
+    """
+    PROBLEM_TYPES = ['model.confml.missing_feature_for_data']
+    
+    def validate(self):
+        for dataobj in self.context.configuration._traverse(type=api.Data):
+            try:
+                self.context.dview.get_feature(dataobj.fqr)
+            except exceptions.NotFound:
+                prob = api.Problem(
+                    msg = "Feature '%s' not found" % dataobj.fqr,
+                    type = self.PROBLEM_TYPES[0],
+                    line = dataobj.lineno,
+                    file = dataobj.get_configuration_path())
+                self.context.problems.append(prob)
+
+class MissingDescriptionValidator(SettingValidatorBase):
+    """
+    Validator for validating missing descriptions in feature/setting in the configuration.
+    """
+    PROBLEM_TYPES = ['model.confml.missing_desc']
+    
+    def validate_setting(self, ref, setting):
+        print 'Validating missing desc!'
+        if not setting.desc or setting.desc == '':
+            prob = api.Problem(
+                msg = "Setting/Feature %s: has no description" % (ref),
+                type = self.PROBLEM_TYPES[0],
+                line = setting.lineno,
+                file = setting.get_configuration_path(),
+                severity = api.Problem.SEVERITY_WARNING)
+            self.context.problems.append(prob)
+
+class DuplicateSettingValidator(ValidatorBase):
+    """
+    Validator for validating that there are no settings with same ref in given 
+    configuration.
+    """
+    PROBLEM_TYPES = ['model.confml.duplicate.setting']
+    
+    def validate(self):
+        settings_container = container.DataContainer()
+        # Traverse through the configuration model and store each feature to 
+        # the settings_container. 
+        for setting in self.context.configuration._traverse(type=model.ConfmlSetting):
+            settings_container.add_value(setting.fqr, setting)
+        # Go though the settings_container to see if any features have more than one 
+        # definition and report those as problems
+        for fqr in settings_container.list_keys():
+            if len(settings_container.get_values(fqr)) > 1:
+                files = [setting.get_configuration_path() for setting in settings_container.get_values(fqr)]
+                prob = api.Problem(
+                    msg = "Feature %s has '%s' definitions in files %s" % (fqr, len(settings_container.get_values(fqr)), files),
+                    type = self.PROBLEM_TYPES[0],
+                    severity = api.Problem.SEVERITY_WARNING, 
+                    line = settings_container.get_value(fqr).lineno,
+                    file = files[-1],
+                    problem_data = settings_container.get_values(fqr))
+                self.context.problems.append(prob)
+
+class DuplicateFeatureValidator(ValidatorBase):
+    """
+    Validator for validating that there are no features with same ref in given 
+    configuration.
+    """
+    PROBLEM_TYPES = ['model.confml.duplicate.feature']
+    
+    def validate(self):
+        settings_container = container.DataContainer()
+        # Traverse through the configuration model and store each feature to 
+        # the settings_container. 
+        for setting in self.context.configuration._traverse(type=model.ConfmlFeature):
+            settings_container.add_value(setting.fqr, setting)
+        # Go though the settings_container to see if any features have more than one 
+        # definition and report those as problems
+        for fqr in settings_container.list_keys():
+            if len(settings_container.get_values(fqr)) > 1:
+                files = [setting.get_configuration_path() for setting in settings_container.get_values(fqr)]
+                prob = api.Problem(
+                    msg = "Feature %s has '%s' definitions in files %s" % (fqr, len(settings_container.get_values(fqr)), files),
+                    type = self.PROBLEM_TYPES[0],
+                    severity = api.Problem.SEVERITY_INFO,
+                    line = settings_container.get_value(fqr).lineno,
+                    file = files[-1],
+                    problem_data = settings_container.get_values(fqr))
+                self.context.problems.append(prob)
+
+class DuplicateSettingFixer(FixerBase):
+    """
+    A Fix class for duplicate settings that removes all but the last definition of the element.
+    """
+    PROBLEM_TYPES = ['model.confml.duplicate.setting']
+
+    def fix(self, context):
+        for problem in self.filter_problems(context.problems, self.PROBLEM_TYPES[0]):
+            logging.getLogger('cone.validation').info("Fixing problem %s" % problem.msg)
+            context.fixes.append("Fixed problem: %s" % problem.msg)
+            # The problem data is expected to have those duplicate settings and the 
+            # actual setting as a last element
+            for setting in problem.problem_data[0:-1]:
+                parent_fea = setting.find_parent(type=api.Feature)
+                logging.getLogger('cone.validation').info("Remove setting %s from %s" % (setting.fqr, parent_fea.get_configuration_path()))
+                try:
+                    parent_fea.remove_feature(setting.ref)
+                except exceptions.NotFound:
+                    logging.getLogger('cone.validation').info("Already removed %s from %s" % (setting.ref, parent_fea.get_configuration_path()))
+
+class DuplicateFeatureFixer(FixerBase):
+    """
+    A Fix class for duplicate features that merges all setting under a duplicate feature 
+    to the first instance of the feature and removes the duplicates.
+    """
+    PROBLEM_TYPES = ['model.confml.duplicate.feature']
+
+    def fix(self, context):
+        for problem in self.filter_problems(context.problems, self.PROBLEM_TYPES[0]):
+            logging.getLogger('cone.validation').info("Fixing problem %s" % problem.msg)
+            context.fixes.append("Fixed problem: %s" % problem.msg)
+            # The problem data is expected to have those duplicate settings and the 
+            # actual setting as a last element
+            target_feature = problem.problem_data[0]
+            target_config = target_feature.find_parent(type=api.Configuration)
+            for feature in problem.problem_data[1:]:
+                logging.getLogger('cone.validation').info("Move settings from Feature %s in %s to %s" % \
+                                                          (feature.fqr, feature.get_configuration_path(), target_feature.get_configuration_path()))
+                for setting_ref in feature.list_features():
+                    setting = feature.get_feature(setting_ref)
+                    # Get the path from feature to the parent of this setting
+                    # (pathto,ref) = utils.dottedref.psplit_ref(setting_ref)
+                    if target_feature.has_ref(setting_ref):
+                        target_feature.remove_feature(setting_ref)
+                    target_feature.add_feature(setting)
+                    
+                config = feature.find_parent(type=api.Configuration)
+                logging.getLogger('cone.validation').info("Remove feature %s from %s" % (feature.fqr, config.get_full_path()))
+                config.remove_feature(feature.ref)
+
+                
+#: List of all built-in ConfML validator classes
+VALIDATOR_CLASSES = [
+    MissingFeatureForDataValidator,
+    LengthConstraintValidator,
+    DuplicateSettingValidator,
+    DuplicateFeatureValidator,
+#    MissingDescriptionValidator,
+]
+
+#: List of all built-in ConfML fixer classes
+FIXER_CLASSES = [
+    DuplicateFeatureFixer,
+]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/builtinvalidators/implml.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,52 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+from cone.public import api, plugin
+from cone.validation.implmlvalidation import GlobalValidatorBase
+
+class DuplicateTempFeatureRefValidator(GlobalValidatorBase):
+    """
+    Validator for checking for duplicate refs in temporary variable
+    definitions.
+    """
+    PROBLEM_TYPES = ['model.implml.container.duplicate_tempvar']
+    
+    def validate(self):
+        # Collect a dictionary of all temporary variable locations,
+        # i.e. (file, lineno) tuples
+        tempvar_locations_by_ref = {}
+        for impl in self.context.all_impls:
+            if isinstance(impl, plugin.ImplContainer):
+                for td in impl._tempvar_defs:
+                    lst = tempvar_locations_by_ref.get(td.ref, [])
+                    lst.append((impl.ref, td.lineno))
+                    tempvar_locations_by_ref[td.ref] = lst
+        
+        # Check for duplicates
+        for ref, locations in tempvar_locations_by_ref.iteritems():
+            if len(locations) > 1:
+                for impl_file, lineno in locations:
+                    prob = api.Problem(
+                        msg = "Duplicate temporary variable ref '%s'" % ref,
+                        type = self.PROBLEM_TYPES[0],
+                        line = lineno,
+                        file = impl_file)
+                    self.context.problems.append(prob)
+
+#: List of all built-in ImplML validator classes
+VALIDATOR_CLASSES = [
+    DuplicateTempFeatureRefValidator,
+]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/builtinvalidators/tests/__init__.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,15 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/builtinvalidators/tests/runtests.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,19 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+if __name__ == '__main__':
+    import nose
+    nose.core.run(argv=['collector','--include=unittest', '--verbosity=3'])
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/builtinvalidators/tests/unittest_confmlfixer.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,141 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+import unittest
+
+from cone.confml import model
+from cone.public import api
+from cone.validation.confmlvalidation import ValidationContext
+from cone.validation.builtinvalidators import confml 
+
+class TestConfmlDuplicateSettingFix(unittest.TestCase):
+    def test_duplicate_setting_fix_with_duplicates(self):
+        root = model.ConfmlConfiguration("dummy_conf")
+        conf1 = root.create_configuration("conf1.confml")
+        fea = conf1.create_feature("fea1")
+        set1 = model.ConfmlStringSetting("setting1", desc="description one", name="setting")
+        fea.add_feature(set1)
+        conf2 = root.create_configuration("conf2.confml")
+        fea = conf2.create_feature("fea1")
+        set2 = model.ConfmlStringSetting("setting1", desc="description two", name="setting new")
+        fea.add_feature(set2)
+
+        context = ValidationContext(root)
+        valid = confml.DuplicateSettingValidator(context)
+        valid.validate()
+        self.assertEquals(len(context.problems),1, context.problems)
+        self.assertEquals(context.problems[0].msg,"Feature fea1.setting1 has '2' definitions in files ['conf1.confml', 'conf2.confml']", context.problems)
+        fixer = confml.DuplicateSettingFixer()
+        fixer.fix(context)
+        
+        # revalidation should now report no problems
+        context = ValidationContext(root)
+        valid = confml.DuplicateSettingValidator(context)
+        valid.validate()
+        self.assertEquals(len(context.problems),0, context.problems)
+
+        
+class TestConfmlDuplicateFeatureFix(unittest.TestCase):
+    def test_duplicate_setting_fix_with_duplicates(self):
+        root = model.ConfmlConfiguration("dummy_conf")
+        conf1 = root.create_configuration("conf1.confml")
+        fea = conf1.create_feature("fea1")
+        set1 = model.ConfmlStringSetting("setting1", desc="description one", name="setting")
+        fea.add_feature(set1)
+        conf2 = root.create_configuration("conf2.confml")
+        fea = conf2.create_feature("fea1")
+        set2 = model.ConfmlStringSetting("setting2", desc="description two", name="setting new")
+        fea.add_feature(set2)
+        self.assertEquals(conf1.list_all_features(),['fea1','fea1.setting1'])
+        
+        context = ValidationContext(root)
+        valid = confml.DuplicateFeatureValidator(context)
+        valid.validate()
+        self.assertEquals(len(context.problems),1, context.problems)
+        self.assertEquals(context.problems[0].msg,"Feature fea1 has '2' definitions in files ['conf1.confml', 'conf2.confml']", context.problems)
+        fixer = confml.DuplicateFeatureFixer()
+        fixer.fix(context)
+        
+        # revalidation should now report no problems
+        context = ValidationContext(root)
+        valid = confml.DuplicateFeatureValidator(context)
+        valid.validate()
+        self.assertEquals(len(context.problems),0, context.problems)
+        self.assertEquals(conf1.list_all_features(),['fea1','fea1.setting1','fea1.setting2'])
+        self.assertEquals(conf2.list_all_features(),[])
+
+
+    def test_duplicate_setting_fix_with_duplicates_with_options(self):
+        root = model.ConfmlConfiguration("dummy_conf")
+        conf1 = root.create_configuration("conf1.confml")
+        fea = conf1.create_feature("fea1")
+        set1 = model.ConfmlStringSetting("setting1", desc="description one", name="setting")
+        set1.add(api.Option('op1','val1'))
+        set1.add(api.Option('op2','val2'))
+        fea.add_feature(set1)
+        conf2 = root.create_configuration("conf2.confml")
+        fea = conf2.create_feature("fea1")
+        set2 = model.ConfmlStringSetting("setting1", desc="description two", name="setting new")
+        set2.add(api.Option('op3','val3'))
+        set2.add(api.Option('op4','val4'))
+        fea.add_feature(set2)
+        
+        context = ValidationContext(root)
+        valid = confml.DuplicateFeatureValidator(context)
+        valid.validate()
+        fixer = confml.DuplicateFeatureFixer()
+        fixer.fix(context)
+                
+        set1 = conf1.get_feature('fea1').get_feature('setting1')
+        options = set1.options
+        self.assertEquals(len(options),2,'After fix only options from new setting should be preserved')
+        self.assertEquals(options['val3'].name,'op3')
+        self.assertEquals(options['val4'].name,'op4')
+        
+
+    def test_duplicate_feature_fixer_with_sequence_duplicates(self):
+        root = model.ConfmlConfiguration("dummy_conf")
+        conf1 = root.create_configuration("conf1.confml")
+        fea = conf1.create_feature("fea1")
+        set1 = model.ConfmlSequenceSetting("setting1", desc="description one", name="setting")
+        set1.add_feature(model.ConfmlSetting("sub_setting1", desc="description one", name="sub_setting one"))
+        fea.add_feature(set1)
+        conf2 = root.create_configuration("conf2.confml")
+        fea = conf2.create_feature("fea1")
+        set2 = model.ConfmlSequenceSetting("setting1", desc="description one", name="setting")
+        set2.add_feature(model.ConfmlSetting("sub_setting1", desc="description two", name="sub_setting two"))
+        fea.add_feature(set2)
+
+        context = ValidationContext(root)
+        valid = confml.DuplicateFeatureValidator(context)
+        valid.validate()
+
+        self.assertEquals(len(context.problems),1, context.problems)
+        self.assertEquals(context.problems[0].msg,"Feature fea1 has '2' definitions in files ['conf1.confml', 'conf2.confml']", context.problems)
+        fixer = confml.DuplicateFeatureFixer()
+        fixer.fix(context)
+        
+        # revalidation should now report no problems
+        context = ValidationContext(root)
+        valid = confml.DuplicateFeatureValidator(context)
+        valid.validate()
+        self.assertEquals(len(context.problems),0, context.problems)
+        self.assertEquals(conf1.list_all_features(),['fea1',
+                                                     'fea1.setting1',
+                                                     'fea1.setting1.sub_setting1'])
+        self.assertEquals(conf2.list_all_features(),[])
+        
+        
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/builtinvalidators/tests/unittest_confmlvalidation.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,179 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+import os
+import unittest
+
+from cone.confml import model
+from cone.public import api
+from cone.validation.confmlvalidation import ValidationContext, get_validator_classes
+from cone.validation.builtinvalidators.confml import  LengthConstraintValidator, DuplicateSettingValidator, DuplicateFeatureValidator
+
+class TestConfmlValidation(unittest.TestCase):
+    def test_validations_for_duplicate_setting(self):
+        root = model.ConfmlConfiguration("dummy_conf")
+        conf1 = root.create_configuration("conf1.confml")
+        fea = conf1.create_feature("fea1")
+        set1 = model.ConfmlStringSetting("setting1", desc="description one", name="setting")
+        fea.add_feature(set1)
+        conf2 = root.create_configuration("conf2.confml")
+        fea = conf2.create_feature("fea1")
+        set2 = model.ConfmlStringSetting("setting1", desc="description two", name="setting new")
+        fea.add_feature(set2)
+
+        validator_classes = get_validator_classes()
+    
+        context = ValidationContext(root)
+        validators = [vc(context) for vc in validator_classes]
+        for validator in validators:
+            validator.validate()
+        self.assertEquals(len(context.problems),2, context.problems)
+        self.assertEquals(context.problems[0].msg,"Feature fea1.setting1 has '2' definitions in files ['conf1.confml', 'conf2.confml']", context.problems)
+
+    def test_validations_for_lenght_and_duplicate_setting(self):
+        root = model.ConfmlConfiguration("dummy_conf")
+        conf1 = root.create_configuration("conf1.confml")
+        fea = conf1.create_feature("fea1")
+        set1 = model.ConfmlStringSetting("setting1", desc="description one", name="setting", length="4")
+        fea.add_feature(set1)
+        set1.value = "abcdefg"
+        conf2 = root.create_configuration("conf2.confml")
+        fea = conf2.create_feature("fea1")
+        set2 = model.ConfmlStringSetting("setting1", desc="description two", name="setting new")
+        fea.add_feature(set2)
+
+        validator_classes = get_validator_classes()
+    
+        context = ValidationContext(root)
+        validators = [vc(context) for vc in validator_classes]
+        for validator in validators:
+            validator.validate()
+        self.assertEquals(len(context.problems),3, context.problems)
+        self.assertEquals(context.problems[0].msg,"Setting fea1.setting1: Exact number of characters must be 4 (value has 7)", context.problems)
+        self.assertEquals(context.problems[1].msg,"Feature fea1.setting1 has '2' definitions in files ['conf1.confml', 'conf2.confml']", context.problems)
+
+
+class TestConfmlLenghtValidation(unittest.TestCase):
+    def test_length_constraint_validator_with_empty_context(self):
+        context = ValidationContext(api.Configuration("foo"))
+        valid = LengthConstraintValidator(context)
+        valid.validate()
+        self.assertEquals(context.problems,[])
+        
+    def test_length_constraint_validator_with_singe_feature(self):
+        conf = model.ConfmlConfiguration("foo")
+        fea = model.ConfmlStringSetting("test", length="4")
+        conf.add_feature(fea)
+        # Test lenght validation
+        fea.value= "test mee"
+        context = ValidationContext(conf)
+        valid = LengthConstraintValidator(context)
+        valid.validate()
+        self.assertEquals(context.problems[0].type,'model.confml.invalid_value.length')
+        # Test minLenght validation
+        context.problems = []
+        del fea.length
+        fea.minLength = 10
+        valid.validate()
+        self.assertEquals(context.problems[0].type,'model.confml.invalid_value.minlength', context.problems[0])
+        # Test maxLenght validation
+        context.problems = []
+        del fea.minLength
+        fea.maxLength = 4
+        valid.validate()
+        self.assertEquals(context.problems[0].type,'model.confml.invalid_value.maxlength', context.problems[0])
+        
+
+class TestConfmlDuplicateSettingValidation(unittest.TestCase):
+    def test_duplicate_setting_validator_with_no_duplicates(self):
+        conf = model.ConfmlConfiguration("dummy_conf")
+        fea = conf.create_feature("fea1")
+        set1 = model.ConfmlStringSetting("setting1", desc="description one", name="setting")
+        set2 = model.ConfmlStringSetting("setting2", desc="description two", name="setting")
+        fea.add_feature(set1)
+        fea.add_feature(set2)
+
+        context = ValidationContext(conf)
+        valid = DuplicateSettingValidator(context)
+        valid.validate()
+        self.assertEquals(context.problems,[])
+
+    def test_duplicate_setting_validator_with_duplicates(self):
+        root = model.ConfmlConfiguration("dummy_conf")
+        conf1 = root.create_configuration("conf1.confml")
+        fea = conf1.create_feature("fea1")
+        set1 = model.ConfmlStringSetting("setting1", desc="description one", name="setting")
+        fea.add_feature(set1)
+        conf2 = root.create_configuration("conf2.confml")
+        fea = conf2.create_feature("fea1")
+        set2 = model.ConfmlStringSetting("setting1", desc="description two", name="setting new")
+        fea.add_feature(set2)
+
+        context = ValidationContext(root)
+        valid = DuplicateSettingValidator(context)
+        valid.validate()
+        self.assertEquals(len(context.problems),1, context.problems)
+        self.assertEquals(context.problems[0].msg,"Feature fea1.setting1 has '2' definitions in files ['conf1.confml', 'conf2.confml']", context.problems)
+
+class TestConfmlDuplicateFeatureValidation(unittest.TestCase):
+    def test_duplicate_feature_validator_with_no_duplicates(self):
+        conf = model.ConfmlConfiguration("dummy_conf")
+        fea = conf.create_feature("fea1")
+        set1 = model.ConfmlStringSetting("setting1", desc="description one", name="setting")
+        set2 = model.ConfmlStringSetting("setting2", desc="description two", name="setting")
+        fea.add_feature(set1)
+        fea.add_feature(set2)
+
+        context = ValidationContext(conf)
+        valid = DuplicateFeatureValidator(context)
+        valid.validate()
+        self.assertEquals(context.problems,[])
+    
+    def test_duplicate_feature_validator_with_duplicates(self):
+        root = model.ConfmlConfiguration("dummy_conf")
+        conf1 = root.create_configuration("conf1.confml")
+        fea = conf1.create_feature("fea1")
+        set1 = model.ConfmlStringSetting("setting1", desc="description one", name="setting")
+        fea.add_feature(set1)
+        conf2 = root.create_configuration("conf2.confml")
+        fea = conf2.create_feature("fea1")
+        set2 = model.ConfmlStringSetting("setting2", desc="description two", name="setting new")
+        fea.add_feature(set2)
+
+        context = ValidationContext(root)
+        valid = DuplicateFeatureValidator(context)
+        valid.validate()
+        self.assertEquals(len(context.problems),1, context.problems)
+        self.assertEquals(context.problems[0].msg,"Feature fea1 has '2' definitions in files ['conf1.confml', 'conf2.confml']", context.problems)
+
+    def test_duplicate_feature_validator_with_sequence_duplicates(self):
+        root = model.ConfmlConfiguration("dummy_conf")
+        conf1 = root.create_configuration("conf1.confml")
+        fea = conf1.create_feature("fea1")
+        set1 = model.ConfmlSequenceSetting("setting1", desc="description one", name="setting")
+        set1.add_feature(model.ConfmlSetting("sub_setting1", desc="description one", name="sub_setting one"))
+        fea.add_feature(set1)
+        conf2 = root.create_configuration("conf2.confml")
+        fea = conf2.create_feature("fea1")
+        set2 = model.ConfmlSequenceSetting("setting1", desc="description one", name="setting")
+        set2.add_feature(model.ConfmlSetting("sub_setting1", desc="description two", name="sub_setting two"))
+        fea.add_feature(set2)
+
+        context = ValidationContext(root)
+        valid = DuplicateFeatureValidator(context)
+        valid.validate()
+        self.assertEquals(len(context.problems),1, context.problems)
+        self.assertEquals(context.problems[0].msg,"Feature fea1 has '2' definitions in files ['conf1.confml', 'conf2.confml']", context.problems)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/common.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,84 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+import sys
+import logging
+import inspect
+
+def load_plugin_classes(entry_point_group, base_class):
+    """
+    Load plugin classes from plug-in entry points.
+    
+    @param entry_point_group: Entry point group from which to load
+        classes. Each entry point is expected to be an iterable of
+        plugin class instances.
+    @param base_class: The base class that every loaded class must inherit.
+    @return: List of loaded plugin classes.
+    """
+    log = logging.getLogger('cone')
+    log.setLevel(logging.DEBUG)
+    validator_classes = []
+    
+    import pkg_resources
+    working_set = pkg_resources.WorkingSet(sys.path)
+    for entry_point in working_set.iter_entry_points(entry_point_group):
+        class_list = entry_point.load()
+        
+        # Make sure that the class list is a list
+        try:
+            class_list = [c for c in class_list]
+        except:
+            log.warn("Entry point %s:%s is not iterable (%r)" % (entry_point_group, entry_point.name, class_list))
+            continue
+        
+        for i, cls in enumerate(class_list):
+            if not inspect.isclass(cls):
+                log.warn("Object %d from entry point %s:%s is not a class (%r)" % (i, entry_point_group, entry_point.name, cls))
+            elif not issubclass(cls, base_class):
+                log.warn("Object %d from entry point %s:%s is not a sub-class of %s.%s (%r)" \
+                         % (i, entry_point, entry_point.name,
+                            base_class.__module__,
+                            base_class.__name__,
+                            cls))
+            else:
+                msg = "Validator class %r loaded from egg entry point %s:%s, item %d" % (cls, entry_point_group, entry_point.name, i)
+                log.debug(msg)
+                #print msg
+                validator_classes.append(cls)
+            
+    return validator_classes
+
+def filter_classes(classes, filter):
+    """
+    Filter the given list of validator by the given ProblemTypeFilter object.
+    
+    @param classes: The class list for filter. Each 
+        class is assumed to have a PROBLEM_TYPES attribute that defines
+        an iterable of the types of problems that the problem yields.
+    @param filter: The filter object to use. Can be None, in which case
+        the class list is simply returned back.
+    @return: The filtered list.
+    """
+    if filter == None:
+        return classes
+    else:
+        result = []
+        for klass in classes:
+            for problem_type in klass.PROBLEM_TYPES:
+                if filter.match(problem_type):
+                    result.append(klass)
+                    break
+        return result
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/confml_xsd/XInclude.xsd	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+           xmlns:xi="http://www.w3.org/2001/XInclude"
+           targetNamespace="http://www.w3.org/2001/XInclude"
+           finalDefault="extension">
+
+  <xs:element name="include" type="xi:includeType" />
+
+  <xs:complexType name="includeType" mixed="true">
+    <xs:choice minOccurs='0' maxOccurs='unbounded' >
+      <xs:element ref='xi:fallback' />
+      <!--<xs:any namespace='##other' processContents='lax' />
+      <xs:any namespace='##local' processContents='lax' />-->
+    </xs:choice>
+    <xs:attribute name="href" use="optional" type="xs:anyURI"/>
+    <xs:attribute name="parse" use="optional" default="xml"
+                  type="xi:parseType" />
+    <xs:attribute name="xpointer" use="optional" type="xs:string"/>
+    <xs:attribute name="encoding" use="optional" type="xs:string"/>
+    <xs:attribute name="accept" use="optional" type="xs:string"/>
+    <xs:attribute name="accept-language" use="optional" type="xs:string"/>
+    <xs:anyAttribute namespace="##other" processContents="lax"/>
+  </xs:complexType>
+
+  <xs:simpleType name="parseType">
+    <xs:restriction base="xs:token">
+      <xs:enumeration value="xml"/>
+      <xs:enumeration value="text"/>
+    </xs:restriction>
+  </xs:simpleType>
+  
+  <xs:element name="fallback" type="xi:fallbackType" />
+
+  <xs:complexType name="fallbackType" mixed="true">
+    <xs:choice minOccurs="0" maxOccurs="unbounded">
+      <xs:element ref="xi:include"/>
+      <!--<xs:any namespace="##other" processContents="lax"/>
+      <xs:any namespace="##local" processContents="lax"/>-->
+    </xs:choice>
+    <xs:anyAttribute namespace="##other" processContents="lax" />
+  </xs:complexType>
+
+</xs:schema>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/confml_xsd/XMLSchema.xsd	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,2358 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- DOCTYPE has been removed from this copy -->
+<xs:schema targetNamespace="http://www.w3.org/2001/XMLSchema" blockDefault="#all" elementFormDefault="qualified" version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xml:lang="EN" xmlns:hfp="http://www.w3.org/2001/XMLSchema-hasFacetAndProperty">
+ <xs:annotation>
+  <xs:documentation>
+    Part 1 version: Id: structures.xsd,v 1.2 2004/01/15 11:34:25 ht Exp 
+    Part 2 version: Id: datatypes.xsd,v 1.3 2004/01/23 18:11:13 ht Exp 
+  </xs:documentation>
+ </xs:annotation>
+
+ <xs:annotation>
+   <xs:documentation source="http://www.w3.org/TR/2004/PER-xmlschema-1-20040318/structures.html">
+   The schema corresponding to this document is normative,
+   with respect to the syntactic constraints it expresses in the
+   XML Schema language.  The documentation (within &lt;documentation&gt; elements)
+   below, is not normative, but rather highlights important aspects of
+   the W3C Recommendation of which this is a part</xs:documentation>
+ </xs:annotation>
+
+ <xs:annotation>
+   <xs:documentation>
+   The simpleType element and all of its members are defined
+      towards the end of this schema document</xs:documentation>
+ </xs:annotation>
+
+ <xs:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="xml.xsd">
+   <xs:annotation>
+     <xs:documentation>
+       Get access to the xml: attribute groups for xml:lang
+       as declared on 'schema' and 'documentation' below
+     </xs:documentation>
+   </xs:annotation>
+ </xs:import>
+
+ <xs:complexType name="openAttrs">
+   <xs:annotation>
+     <xs:documentation>
+       This type is extended by almost all schema types
+       to allow attributes from other namespaces to be
+       added to user schemas.
+     </xs:documentation>
+   </xs:annotation>
+   <xs:complexContent>
+     <xs:restriction base="xs:anyType">
+       <xs:anyAttribute namespace="##other" processContents="lax"/>
+     </xs:restriction>
+   </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="annotated">
+   <xs:annotation>
+     <xs:documentation>
+       This type is extended by all types which allow annotation
+       other than &lt;schema&gt; itself
+     </xs:documentation>
+   </xs:annotation>
+   <xs:complexContent>
+     <xs:extension base="xs:openAttrs">
+       <xs:sequence>
+         <xs:element ref="xs:annotation" minOccurs="0"/>
+       </xs:sequence>
+       <xs:attribute name="id" type="xs:ID"/>
+     </xs:extension>
+   </xs:complexContent>
+ </xs:complexType>
+
+ <xs:group name="schemaTop">
+  <xs:annotation>
+   <xs:documentation>
+   This group is for the
+   elements which occur freely at the top level of schemas.
+   All of their types are based on the "annotated" type by extension.</xs:documentation>
+  </xs:annotation>
+  <xs:choice>
+   <xs:group ref="xs:redefinable"/>
+   <xs:element ref="xs:element"/>
+   <xs:element ref="xs:attribute"/>
+   <xs:element ref="xs:notation"/>
+  </xs:choice>
+ </xs:group>
+ 
+ <xs:group name="redefinable">
+  <xs:annotation>
+   <xs:documentation>
+   This group is for the
+   elements which can self-redefine (see &lt;redefine&gt; below).</xs:documentation>
+  </xs:annotation>
+  <xs:choice>
+   <xs:element ref="xs:simpleType"/>
+   <xs:element ref="xs:complexType"/>
+   <xs:element ref="xs:group"/>
+   <xs:element ref="xs:attributeGroup"/>
+  </xs:choice>
+ </xs:group>
+
+ <xs:simpleType name="formChoice">
+  <xs:annotation>
+   <xs:documentation>
+   A utility type, not for public use</xs:documentation>
+  </xs:annotation>
+  <xs:restriction base="xs:NMTOKEN">
+   <xs:enumeration value="qualified"/>
+   <xs:enumeration value="unqualified"/>
+  </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="reducedDerivationControl">
+  <xs:annotation>
+   <xs:documentation>
+   A utility type, not for public use</xs:documentation>
+  </xs:annotation>
+  <xs:restriction base="xs:derivationControl">
+   <xs:enumeration value="extension"/>
+   <xs:enumeration value="restriction"/>
+  </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="derivationSet">
+  <xs:annotation>
+   <xs:documentation>
+   A utility type, not for public use</xs:documentation>
+   <xs:documentation>
+   #all or (possibly empty) subset of {extension, restriction}</xs:documentation>
+  </xs:annotation>
+  <xs:union>
+   <xs:simpleType>    
+    <xs:restriction base="xs:token">
+     <xs:enumeration value="#all"/>
+    </xs:restriction>
+   </xs:simpleType>
+   <xs:simpleType>
+    <xs:list itemType="xs:reducedDerivationControl"/>
+   </xs:simpleType>
+  </xs:union>
+ </xs:simpleType>
+
+ <xs:simpleType name="typeDerivationControl">
+  <xs:annotation>
+   <xs:documentation>
+   A utility type, not for public use</xs:documentation>
+  </xs:annotation>
+  <xs:restriction base="xs:derivationControl">
+   <xs:enumeration value="extension"/>
+   <xs:enumeration value="restriction"/>
+   <xs:enumeration value="list"/>
+   <xs:enumeration value="union"/>
+  </xs:restriction>
+ </xs:simpleType>
+
+  <xs:simpleType name="fullDerivationSet">
+  <xs:annotation>
+   <xs:documentation>
+   A utility type, not for public use</xs:documentation>
+   <xs:documentation>
+   #all or (possibly empty) subset of {extension, restriction, list, union}</xs:documentation>
+  </xs:annotation>
+  <xs:union>
+   <xs:simpleType>    
+    <xs:restriction base="xs:token">
+     <xs:enumeration value="#all"/>
+    </xs:restriction>
+   </xs:simpleType>
+   <xs:simpleType>
+    <xs:list itemType="xs:typeDerivationControl"/>
+   </xs:simpleType>
+  </xs:union>
+ </xs:simpleType>
+
+ <xs:element name="schema" id="schema">
+  <xs:annotation>
+    <xs:documentation source="http://www.w3.org/TR/xmlschema-1/#element-schema"/>
+  </xs:annotation>
+  <xs:complexType>
+   <xs:complexContent>
+    <xs:extension base="xs:openAttrs">
+     <xs:sequence>
+      <xs:choice minOccurs="0" maxOccurs="unbounded">
+       <xs:element ref="xs:include"/>
+       <xs:element ref="xs:import"/>
+       <xs:element ref="xs:redefine"/>
+       <xs:element ref="xs:annotation"/>
+      </xs:choice>
+      <xs:sequence minOccurs="0" maxOccurs="unbounded">
+       <xs:group ref="xs:schemaTop"/>
+       <xs:element ref="xs:annotation" minOccurs="0" maxOccurs="unbounded"/>
+      </xs:sequence>
+     </xs:sequence>
+     <xs:attribute name="targetNamespace" type="xs:anyURI"/>
+     <xs:attribute name="version" type="xs:token"/>
+     <xs:attribute name="finalDefault" type="xs:fullDerivationSet" use="optional" default=""/>
+     <xs:attribute name="blockDefault" type="xs:blockSet" use="optional" default=""/>
+     <xs:attribute name="attributeFormDefault" type="xs:formChoice" use="optional" default="unqualified"/>
+     <xs:attribute name="elementFormDefault" type="xs:formChoice" use="optional" default="unqualified"/>
+     <xs:attribute name="id" type="xs:ID"/>
+     <xs:attribute ref="xml:lang"/>
+    </xs:extension>
+   </xs:complexContent>
+  </xs:complexType>
+
+  <xs:key name="element">
+   <xs:selector xpath="xs:element"/>
+   <xs:field xpath="@name"/>
+  </xs:key>
+
+  <xs:key name="attribute">
+   <xs:selector xpath="xs:attribute"/>
+   <xs:field xpath="@name"/>
+  </xs:key>
+
+  <xs:key name="type">
+   <xs:selector xpath="xs:complexType|xs:simpleType"/>
+   <xs:field xpath="@name"/>
+  </xs:key>
+ 
+  <xs:key name="group">
+   <xs:selector xpath="xs:group"/>
+   <xs:field xpath="@name"/>
+  </xs:key>
+ 
+  <xs:key name="attributeGroup">
+   <xs:selector xpath="xs:attributeGroup"/>
+   <xs:field xpath="@name"/>
+  </xs:key>
+ 
+  <xs:key name="notation">
+   <xs:selector xpath="xs:notation"/>
+   <xs:field xpath="@name"/>
+  </xs:key>
+
+  <xs:key name="identityConstraint">
+   <xs:selector xpath=".//xs:key|.//xs:unique|.//xs:keyref"/>
+   <xs:field xpath="@name"/>
+  </xs:key>
+
+ </xs:element>
+
+ <xs:simpleType name="allNNI">
+  <xs:annotation><xs:documentation>
+   for maxOccurs</xs:documentation></xs:annotation>
+  <xs:union memberTypes="xs:nonNegativeInteger">
+   <xs:simpleType>
+    <xs:restriction base="xs:NMTOKEN">
+     <xs:enumeration value="unbounded"/>
+    </xs:restriction>
+   </xs:simpleType>
+  </xs:union>
+ </xs:simpleType>
+
+ <xs:attributeGroup name="occurs">
+  <xs:annotation><xs:documentation>
+   for all particles</xs:documentation></xs:annotation>
+  <xs:attribute name="minOccurs" type="xs:nonNegativeInteger" use="optional" default="1"/>
+  <xs:attribute name="maxOccurs" type="xs:allNNI" use="optional" default="1"/>
+ </xs:attributeGroup>
+
+ <xs:attributeGroup name="defRef">
+  <xs:annotation><xs:documentation>
+   for element, group and attributeGroup,
+   which both define and reference</xs:documentation></xs:annotation>
+  <xs:attribute name="name" type="xs:NCName"/>
+  <xs:attribute name="ref" type="xs:QName"/>
+ </xs:attributeGroup>
+
+ <xs:group name="typeDefParticle">
+  <xs:annotation>
+    <xs:documentation>
+   'complexType' uses this</xs:documentation></xs:annotation>
+  <xs:choice>
+   <xs:element name="group" type="xs:groupRef"/>
+   <xs:element ref="xs:all"/>
+   <xs:element ref="xs:choice"/>
+   <xs:element ref="xs:sequence"/>
+  </xs:choice>
+ </xs:group>
+ 
+ 
+
+ <xs:group name="nestedParticle">
+  <xs:choice>
+   <xs:element name="element" type="xs:localElement"/>
+   <xs:element name="group" type="xs:groupRef"/>
+   <xs:element ref="xs:choice"/>
+   <xs:element ref="xs:sequence"/>
+   <xs:element ref="xs:any"/>
+  </xs:choice>
+ </xs:group>
+ 
+ <xs:group name="particle">
+  <xs:choice>
+   <xs:element name="element" type="xs:localElement"/>
+   <xs:element name="group" type="xs:groupRef"/>
+   <xs:element ref="xs:all"/>
+   <xs:element ref="xs:choice"/>
+   <xs:element ref="xs:sequence"/>
+   <xs:element ref="xs:any"/>
+  </xs:choice>
+ </xs:group>
+ 
+ <xs:complexType name="attribute">
+  <xs:complexContent>
+   <xs:extension base="xs:annotated">
+    <xs:sequence>
+     <xs:element name="simpleType" minOccurs="0" type="xs:localSimpleType"/>
+    </xs:sequence>
+    <xs:attributeGroup ref="xs:defRef"/>
+    <xs:attribute name="type" type="xs:QName"/>
+    <xs:attribute name="use" use="optional" default="optional">
+     <xs:simpleType>
+      <xs:restriction base="xs:NMTOKEN">
+       <xs:enumeration value="prohibited"/>
+       <xs:enumeration value="optional"/>
+       <xs:enumeration value="required"/>
+      </xs:restriction>
+     </xs:simpleType>
+    </xs:attribute>
+    <xs:attribute name="default" type="xs:string"/>
+    <xs:attribute name="fixed" type="xs:string"/>
+    <xs:attribute name="form" type="xs:formChoice"/>
+   </xs:extension>
+  </xs:complexContent>
+ </xs:complexType>
+ 
+ <xs:complexType name="topLevelAttribute">
+  <xs:complexContent>
+   <xs:restriction base="xs:attribute">
+    <xs:sequence>
+     <xs:element ref="xs:annotation" minOccurs="0"/>
+     <xs:element name="simpleType" minOccurs="0" type="xs:localSimpleType"/>
+    </xs:sequence>
+    <xs:attribute name="ref" use="prohibited"/>
+    <xs:attribute name="form" use="prohibited"/>
+    <xs:attribute name="use" use="prohibited"/>
+    <xs:attribute name="name" use="required" type="xs:NCName"/>
+    <xs:anyAttribute namespace="##other" processContents="lax"/>
+   </xs:restriction>
+  </xs:complexContent>
+ </xs:complexType>
+
+ <xs:group name="attrDecls">
+  <xs:sequence>
+   <xs:choice minOccurs="0" maxOccurs="unbounded">
+    <xs:element name="attribute" type="xs:attribute"/>
+    <xs:element name="attributeGroup" type="xs:attributeGroupRef"/>
+   </xs:choice>
+   <xs:element ref="xs:anyAttribute" minOccurs="0"/>
+  </xs:sequence>
+ </xs:group>
+
+ <xs:element name="anyAttribute" type="xs:wildcard" id="anyAttribute">
+  <xs:annotation>
+   <xs:documentation source="http://www.w3.org/TR/xmlschema-1/#element-anyAttribute"/>
+  </xs:annotation>
+ </xs:element>
+
+ <xs:group name="complexTypeModel">
+  <xs:choice>
+      <xs:element ref="xs:simpleContent"/>
+      <xs:element ref="xs:complexContent"/>
+      <xs:sequence>
+       <xs:annotation>
+        <xs:documentation>
+   This branch is short for
+   &lt;complexContent&gt;
+   &lt;restriction base="xs:anyType"&gt;
+   ...
+   &lt;/restriction&gt;
+   &lt;/complexContent&gt;</xs:documentation>
+       </xs:annotation>
+       <xs:group ref="xs:typeDefParticle" minOccurs="0"/>
+       <xs:group ref="xs:attrDecls"/>
+      </xs:sequence>
+  </xs:choice>
+ </xs:group>
+
+ <xs:complexType name="complexType" abstract="true">
+  <xs:complexContent>
+   <xs:extension base="xs:annotated">
+    <xs:group ref="xs:complexTypeModel"/>
+    <xs:attribute name="name" type="xs:NCName">
+     <xs:annotation>
+      <xs:documentation>
+      Will be restricted to required or forbidden</xs:documentation>
+     </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="mixed" type="xs:boolean" use="optional" default="false">
+     <xs:annotation>
+      <xs:documentation>
+      Not allowed if simpleContent child is chosen.
+      May be overriden by setting on complexContent child.</xs:documentation>
+    </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="abstract" type="xs:boolean" use="optional" default="false"/>
+    <xs:attribute name="final" type="xs:derivationSet"/>
+    <xs:attribute name="block" type="xs:derivationSet"/>
+   </xs:extension>
+  </xs:complexContent>
+ </xs:complexType>
+ 
+ <xs:complexType name="topLevelComplexType">
+  <xs:complexContent>
+   <xs:restriction base="xs:complexType">
+    <xs:sequence>
+     <xs:element ref="xs:annotation" minOccurs="0"/>
+     <xs:group ref="xs:complexTypeModel"/>
+    </xs:sequence>
+    <xs:attribute name="name" type="xs:NCName" use="required"/>
+    <xs:anyAttribute namespace="##other" processContents="lax"/>
+   </xs:restriction>
+  </xs:complexContent>
+ </xs:complexType>
+ 
+ <xs:complexType name="localComplexType">
+  <xs:complexContent>
+   <xs:restriction base="xs:complexType">
+    <xs:sequence>
+     <xs:element ref="xs:annotation" minOccurs="0"/>
+     <xs:group ref="xs:complexTypeModel"/>
+    </xs:sequence>
+    <xs:attribute name="name" use="prohibited"/>
+    <xs:attribute name="abstract" use="prohibited"/>
+    <xs:attribute name="final" use="prohibited"/>
+    <xs:attribute name="block" use="prohibited"/>
+    <xs:anyAttribute namespace="##other" processContents="lax"/>
+   </xs:restriction>
+  </xs:complexContent>
+ </xs:complexType>
+ 
+ <xs:complexType name="restrictionType">
+  <xs:complexContent>
+   <xs:extension base="xs:annotated">
+    <xs:sequence>
+     <xs:choice minOccurs="0">
+      <xs:group ref="xs:typeDefParticle"/>
+      <xs:group ref="xs:simpleRestrictionModel"/>
+     </xs:choice>
+     <xs:group ref="xs:attrDecls"/>
+    </xs:sequence>
+    <xs:attribute name="base" type="xs:QName" use="required"/>
+   </xs:extension>
+  </xs:complexContent>       
+ </xs:complexType>
+
+ <xs:complexType name="complexRestrictionType">
+  <xs:complexContent>
+   <xs:restriction base="xs:restrictionType">
+    <xs:sequence>
+     <xs:element ref="xs:annotation" minOccurs="0"/>
+     <xs:choice minOccurs="0">
+      <xs:annotation>
+       <xs:documentation>This choice is added simply to
+                   make this a valid restriction per the REC</xs:documentation>
+      </xs:annotation>
+      <xs:group ref="xs:typeDefParticle"/>
+     </xs:choice>
+     <xs:group ref="xs:attrDecls"/>
+    </xs:sequence>
+    <xs:anyAttribute namespace="##other" processContents="lax"/>
+   </xs:restriction>
+  </xs:complexContent>       
+ </xs:complexType>
+
+ <xs:complexType name="extensionType">
+  <xs:complexContent>
+   <xs:extension base="xs:annotated">
+    <xs:sequence>
+     <xs:group ref="xs:typeDefParticle" minOccurs="0"/>
+     <xs:group ref="xs:attrDecls"/>
+    </xs:sequence>
+    <xs:attribute name="base" type="xs:QName" use="required"/>
+   </xs:extension>
+  </xs:complexContent>       
+ </xs:complexType>
+
+ <xs:element name="complexContent" id="complexContent">
+  <xs:annotation>
+   <xs:documentation source="http://www.w3.org/TR/xmlschema-1/#element-complexContent"/>
+  </xs:annotation>
+  <xs:complexType>
+   <xs:complexContent>
+    <xs:extension base="xs:annotated">
+     <xs:choice>
+      <xs:element name="restriction" type="xs:complexRestrictionType"/>
+      <xs:element name="extension" type="xs:extensionType"/>
+     </xs:choice>     
+     <xs:attribute name="mixed" type="xs:boolean">
+      <xs:annotation>
+       <xs:documentation>
+       Overrides any setting on complexType parent.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    </xs:extension>
+   </xs:complexContent>
+  </xs:complexType>
+ </xs:element>
+
+ <xs:complexType name="simpleRestrictionType">
+  <xs:complexContent>
+   <xs:restriction base="xs:restrictionType">
+    <xs:sequence>
+     <xs:element ref="xs:annotation" minOccurs="0"/>
+     <xs:choice minOccurs="0">
+      <xs:annotation>
+       <xs:documentation>This choice is added simply to
+                   make this a valid restriction per the REC</xs:documentation>
+      </xs:annotation>
+      <xs:group ref="xs:simpleRestrictionModel"/>
+     </xs:choice>
+     <xs:group ref="xs:attrDecls"/>
+    </xs:sequence>
+    <xs:anyAttribute namespace="##other" processContents="lax"/>
+   </xs:restriction>
+  </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="simpleExtensionType">
+  <xs:complexContent>
+   <xs:restriction base="xs:extensionType">
+    <xs:sequence>
+     <xs:annotation>
+      <xs:documentation>
+      No typeDefParticle group reference</xs:documentation>
+     </xs:annotation>
+     <xs:element ref="xs:annotation" minOccurs="0"/>
+     <xs:group ref="xs:attrDecls"/>
+    </xs:sequence>
+    <xs:anyAttribute namespace="##other" processContents="lax"/>
+   </xs:restriction>
+  </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="simpleContent" id="simpleContent">
+  <xs:annotation>
+   <xs:documentation source="http://www.w3.org/TR/xmlschema-1/#element-simpleContent"/>
+  </xs:annotation>
+  <xs:complexType>
+   <xs:complexContent>
+    <xs:extension base="xs:annotated">
+     <xs:choice>
+      <xs:element name="restriction" type="xs:simpleRestrictionType"/>
+      <xs:element name="extension" type="xs:simpleExtensionType"/>
+     </xs:choice>
+    </xs:extension>
+   </xs:complexContent>
+  </xs:complexType>
+ </xs:element>
+ 
+ <xs:element name="complexType" type="xs:topLevelComplexType" id="complexType">
+  <xs:annotation>
+   <xs:documentation source="http://www.w3.org/TR/xmlschema-1/#element-complexType"/>
+  </xs:annotation>
+ </xs:element>
+
+
+  <xs:simpleType name="blockSet">
+   <xs:annotation>
+    <xs:documentation>
+    A utility type, not for public use</xs:documentation>
+    <xs:documentation>
+    #all or (possibly empty) subset of {substitution, extension,
+    restriction}</xs:documentation>
+   </xs:annotation>
+   <xs:union>
+    <xs:simpleType>    
+     <xs:restriction base="xs:token">
+      <xs:enumeration value="#all"/>
+     </xs:restriction>
+    </xs:simpleType>
+    <xs:simpleType>
+     <xs:list>
+      <xs:simpleType>
+       <xs:restriction base="xs:derivationControl">
+        <xs:enumeration value="extension"/>
+        <xs:enumeration value="restriction"/>
+        <xs:enumeration value="substitution"/>
+       </xs:restriction>
+      </xs:simpleType>
+     </xs:list>
+    </xs:simpleType>
+   </xs:union>  
+  </xs:simpleType>
+
+ <xs:complexType name="element" abstract="true">
+  <xs:annotation>
+   <xs:documentation>
+   The element element can be used either
+   at the top level to define an element-type binding globally,
+   or within a content model to either reference a globally-defined
+   element or type or declare an element-type binding locally.
+   The ref form is not allowed at the top level.</xs:documentation>
+  </xs:annotation>
+
+  <xs:complexContent>
+   <xs:extension base="xs:annotated">
+    <xs:sequence>
+     <xs:choice minOccurs="0">
+      <xs:element name="simpleType" type="xs:localSimpleType"/>
+      <xs:element name="complexType" type="xs:localComplexType"/>
+     </xs:choice>
+     <xs:group ref="xs:identityConstraint" minOccurs="0" maxOccurs="unbounded"/>
+    </xs:sequence>
+    <xs:attributeGroup ref="xs:defRef"/>
+    <xs:attribute name="type" type="xs:QName"/>
+    <xs:attribute name="substitutionGroup" type="xs:QName"/>
+    <xs:attributeGroup ref="xs:occurs"/>
+    <xs:attribute name="default" type="xs:string"/>
+    <xs:attribute name="fixed" type="xs:string"/>
+    <xs:attribute name="nillable" type="xs:boolean" use="optional" default="false"/>
+    <xs:attribute name="abstract" type="xs:boolean" use="optional" default="false"/>
+    <xs:attribute name="final" type="xs:derivationSet"/>
+    <xs:attribute name="block" type="xs:blockSet"/>
+    <xs:attribute name="form" type="xs:formChoice"/>
+   </xs:extension>
+  </xs:complexContent>
+ </xs:complexType>
+ 
+ <xs:complexType name="topLevelElement">
+  <xs:complexContent>
+   <xs:restriction base="xs:element">
+    <xs:sequence>
+     <xs:element ref="xs:annotation" minOccurs="0"/>
+     <xs:choice minOccurs="0">
+      <xs:element name="simpleType" type="xs:localSimpleType"/>
+      <xs:element name="complexType" type="xs:localComplexType"/>
+     </xs:choice>
+     <xs:group ref="xs:identityConstraint" minOccurs="0" maxOccurs="unbounded"/>
+    </xs:sequence>
+    <xs:attribute name="ref" use="prohibited"/>
+    <xs:attribute name="form" use="prohibited"/>
+    <xs:attribute name="minOccurs" use="prohibited"/>
+    <xs:attribute name="maxOccurs" use="prohibited"/>
+    <xs:attribute name="name" use="required" type="xs:NCName"/>
+    <xs:anyAttribute namespace="##other" processContents="lax"/>
+   </xs:restriction>
+  </xs:complexContent>
+ </xs:complexType>
+ 
+ <xs:complexType name="localElement">
+  <xs:complexContent>
+   <xs:restriction base="xs:element">
+    <xs:sequence>
+     <xs:element ref="xs:annotation" minOccurs="0"/>
+     <xs:choice minOccurs="0">
+      <xs:element name="simpleType" type="xs:localSimpleType"/>
+      <xs:element name="complexType" type="xs:localComplexType"/>
+     </xs:choice>
+     <xs:group ref="xs:identityConstraint" minOccurs="0" maxOccurs="unbounded"/>
+    </xs:sequence>
+    <xs:attribute name="substitutionGroup" use="prohibited"/>
+    <xs:attribute name="final" use="prohibited"/>
+    <xs:attribute name="abstract" use="prohibited"/>
+    <xs:anyAttribute namespace="##other" processContents="lax"/>
+   </xs:restriction>
+  </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="element" type="xs:topLevelElement" id="element">
+  <xs:annotation>
+   <xs:documentation source="http://www.w3.org/TR/xmlschema-1/#element-element"/>
+  </xs:annotation>
+ </xs:element>
+
+ <xs:complexType name="group" abstract="true">
+  <xs:annotation>
+   <xs:documentation>
+   group type for explicit groups, named top-level groups and
+   group references</xs:documentation>
+  </xs:annotation>
+  <xs:complexContent>
+   <xs:extension base="xs:annotated">
+    <xs:group ref="xs:particle" minOccurs="0" maxOccurs="unbounded"/>
+    <xs:attributeGroup ref="xs:defRef"/>
+    <xs:attributeGroup ref="xs:occurs"/>
+   </xs:extension>
+  </xs:complexContent>
+ </xs:complexType>
+ 
+ <xs:complexType name="realGroup">
+  <xs:complexContent>
+   <xs:restriction base="xs:group">
+    <xs:sequence>
+     <xs:element ref="xs:annotation" minOccurs="0"/>
+     <xs:choice minOccurs="0" maxOccurs="1">
+      <xs:element ref="xs:all"/>
+      <xs:element ref="xs:choice"/>
+      <xs:element ref="xs:sequence"/>
+     </xs:choice>
+    </xs:sequence>
+    <xs:anyAttribute namespace="##other" processContents="lax"/>
+   </xs:restriction>
+  </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="namedGroup">
+  <xs:complexContent>
+   <xs:restriction base="xs:realGroup">
+    <xs:sequence>
+     <xs:element ref="xs:annotation" minOccurs="0"/>
+     <xs:choice minOccurs="1" maxOccurs="1">
+      <xs:element name="all">
+       <xs:complexType>
+        <xs:complexContent>
+         <xs:restriction base="xs:all">
+          <xs:group ref="xs:allModel"/>
+          <xs:attribute name="minOccurs" use="prohibited"/>
+          <xs:attribute name="maxOccurs" use="prohibited"/>
+          <xs:anyAttribute namespace="##other" processContents="lax"/>
+         </xs:restriction>
+        </xs:complexContent>
+       </xs:complexType>
+      </xs:element>
+      <xs:element name="choice" type="xs:simpleExplicitGroup"/>
+      <xs:element name="sequence" type="xs:simpleExplicitGroup"/>
+     </xs:choice>
+    </xs:sequence>
+    <xs:attribute name="name" use="required" type="xs:NCName"/>
+    <xs:attribute name="ref" use="prohibited"/>
+    <xs:attribute name="minOccurs" use="prohibited"/>
+    <xs:attribute name="maxOccurs" use="prohibited"/>
+    <xs:anyAttribute namespace="##other" processContents="lax"/>
+   </xs:restriction>
+  </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="groupRef">
+  <xs:complexContent>
+   <xs:restriction base="xs:realGroup">
+    <xs:sequence>
+     <xs:element ref="xs:annotation" minOccurs="0"/>
+    </xs:sequence>
+    <xs:attribute name="ref" use="required" type="xs:QName"/>
+    <xs:attribute name="name" use="prohibited"/>
+    <xs:anyAttribute namespace="##other" processContents="lax"/>
+   </xs:restriction>
+  </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="explicitGroup">
+  <xs:annotation>
+   <xs:documentation>
+   group type for the three kinds of group</xs:documentation>
+  </xs:annotation>
+  <xs:complexContent>
+   <xs:restriction base="xs:group">
+    <xs:sequence>
+     <xs:element ref="xs:annotation" minOccurs="0"/>
+     <xs:group ref="xs:nestedParticle" minOccurs="0" maxOccurs="unbounded"/>
+    </xs:sequence>
+    <xs:attribute name="name" type="xs:NCName" use="prohibited"/>
+    <xs:attribute name="ref" type="xs:QName" use="prohibited"/>
+    <xs:anyAttribute namespace="##other" processContents="lax"/>
+   </xs:restriction>
+  </xs:complexContent>
+ </xs:complexType>
+ 
+ <xs:complexType name="simpleExplicitGroup">
+  <xs:complexContent>
+   <xs:restriction base="xs:explicitGroup">
+    <xs:sequence>
+     <xs:element ref="xs:annotation" minOccurs="0"/>
+     <xs:group ref="xs:nestedParticle" minOccurs="0" maxOccurs="unbounded"/>
+    </xs:sequence>
+    <xs:attribute name="minOccurs" use="prohibited"/>
+    <xs:attribute name="maxOccurs" use="prohibited"/>
+    <xs:anyAttribute namespace="##other" processContents="lax"/>
+   </xs:restriction>
+  </xs:complexContent>
+ </xs:complexType>
+ 
+ <xs:group name="allModel">
+  <xs:sequence>
+      <xs:element ref="xs:annotation" minOccurs="0"/>
+      <xs:choice minOccurs="0" maxOccurs="unbounded">
+       <xs:annotation>
+        <xs:documentation>This choice with min/max is here to
+                          avoid a pblm with the Elt:All/Choice/Seq
+                          Particle derivation constraint</xs:documentation>
+       </xs:annotation>
+       <xs:element name="element" type="xs:narrowMaxMin"/>
+      </xs:choice>
+     </xs:sequence>
+ </xs:group>
+ 
+ 
+ <xs:complexType name="narrowMaxMin">
+  <xs:annotation>
+   <xs:documentation>restricted max/min</xs:documentation>
+  </xs:annotation>
+  <xs:complexContent>
+   <xs:restriction base="xs:localElement">
+    <xs:sequence>
+     <xs:element ref="xs:annotation" minOccurs="0"/>
+     <xs:choice minOccurs="0">
+      <xs:element name="simpleType" type="xs:localSimpleType"/>
+      <xs:element name="complexType" type="xs:localComplexType"/>
+     </xs:choice>
+     <xs:group ref="xs:identityConstraint" minOccurs="0" maxOccurs="unbounded"/>
+    </xs:sequence>
+    <xs:attribute name="minOccurs" use="optional" default="1">
+     <xs:simpleType>
+      <xs:restriction base="xs:nonNegativeInteger">
+       <xs:enumeration value="0"/>
+       <xs:enumeration value="1"/>
+      </xs:restriction>
+     </xs:simpleType>
+    </xs:attribute>
+    <xs:attribute name="maxOccurs" use="optional" default="1">
+     <xs:simpleType>
+      <xs:restriction base="xs:allNNI">
+       <xs:enumeration value="0"/>
+       <xs:enumeration value="1"/>
+      </xs:restriction>
+     </xs:simpleType>
+    </xs:attribute>
+    <xs:anyAttribute namespace="##other" processContents="lax"/>
+   </xs:restriction>
+  </xs:complexContent>
+ </xs:complexType>
+
+  <xs:complexType name="all">
+   <xs:annotation>
+    <xs:documentation>
+   Only elements allowed inside</xs:documentation>
+   </xs:annotation>
+   <xs:complexContent>
+    <xs:restriction base="xs:explicitGroup">
+     <xs:group ref="xs:allModel"/>
+     <xs:attribute name="minOccurs" use="optional" default="1">
+      <xs:simpleType>
+       <xs:restriction base="xs:nonNegativeInteger">
+        <xs:enumeration value="0"/>
+        <xs:enumeration value="1"/>
+       </xs:restriction>
+      </xs:simpleType>
+     </xs:attribute>
+     <xs:attribute name="maxOccurs" use="optional" default="1">
+      <xs:simpleType>
+       <xs:restriction base="xs:allNNI">
+        <xs:enumeration value="1"/>
+       </xs:restriction>
+      </xs:simpleType>
+     </xs:attribute>
+     <xs:anyAttribute namespace="##other" processContents="lax"/>
+    </xs:restriction>
+   </xs:complexContent>
+  </xs:complexType>
+
+ <xs:element name="all" id="all" type="xs:all">
+  <xs:annotation>
+   <xs:documentation source="http://www.w3.org/TR/xmlschema-1/#element-all"/>
+  </xs:annotation>
+ </xs:element>
+
+ <xs:element name="choice" type="xs:explicitGroup" id="choice">
+  <xs:annotation>
+   <xs:documentation source="http://www.w3.org/TR/xmlschema-1/#element-choice"/>
+  </xs:annotation>
+ </xs:element>
+
+ <xs:element name="sequence" type="xs:explicitGroup" id="sequence">
+  <xs:annotation>
+   <xs:documentation source="http://www.w3.org/TR/xmlschema-1/#element-sequence"/>
+  </xs:annotation>
+ </xs:element>
+
+ <xs:element name="group" type="xs:namedGroup" id="group">
+  <xs:annotation>
+   <xs:documentation source="http://www.w3.org/TR/xmlschema-1/#element-group"/>
+  </xs:annotation>
+ </xs:element>
+
+ <xs:complexType name="wildcard">
+  <xs:complexContent>
+   <xs:extension base="xs:annotated">
+    <xs:attribute name="namespace" type="xs:namespaceList" use="optional" default="##any"/>
+    <xs:attribute name="processContents" use="optional" default="strict">
+     <xs:simpleType>
+      <xs:restriction base="xs:NMTOKEN">
+       <xs:enumeration value="skip"/>
+       <xs:enumeration value="lax"/>
+       <xs:enumeration value="strict"/>
+      </xs:restriction>
+     </xs:simpleType>
+    </xs:attribute>
+   </xs:extension>
+  </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="any" id="any">
+  <xs:annotation>
+   <xs:documentation source="http://www.w3.org/TR/xmlschema-1/#element-any"/>
+  </xs:annotation>
+  <xs:complexType>
+   <xs:complexContent>
+    <xs:extension base="xs:wildcard">
+     <xs:attributeGroup ref="xs:occurs"/>
+    </xs:extension>
+   </xs:complexContent>
+  </xs:complexType>
+ </xs:element>
+
+  <xs:annotation>
+   <xs:documentation>
+   simple type for the value of the 'namespace' attr of
+   'any' and 'anyAttribute'</xs:documentation>
+  </xs:annotation>
+  <xs:annotation>
+   <xs:documentation>
+   Value is
+              ##any      - - any non-conflicting WFXML/attribute at all
+
+              ##other    - - any non-conflicting WFXML/attribute from
+                              namespace other than targetNS
+
+              ##local    - - any unqualified non-conflicting WFXML/attribute 
+
+              one or     - - any non-conflicting WFXML/attribute from
+              more URI        the listed namespaces
+              references
+              (space separated)
+
+    ##targetNamespace or ##local may appear in the above list, to
+        refer to the targetNamespace of the enclosing
+        schema or an absent targetNamespace respectively</xs:documentation>
+  </xs:annotation>
+
+ <xs:simpleType name="namespaceList">
+  <xs:annotation>
+   <xs:documentation>
+   A utility type, not for public use</xs:documentation>
+  </xs:annotation>
+  <xs:union>
+   <xs:simpleType>
+    <xs:restriction base="xs:token">
+     <xs:enumeration value="##any"/>
+     <xs:enumeration value="##other"/>
+    </xs:restriction>
+   </xs:simpleType>
+   <xs:simpleType>
+    <xs:list>
+     <xs:simpleType>
+      <xs:union memberTypes="xs:anyURI">
+       <xs:simpleType>
+        <xs:restriction base="xs:token">
+         <xs:enumeration value="##targetNamespace"/>
+         <xs:enumeration value="##local"/>
+        </xs:restriction>
+       </xs:simpleType>
+      </xs:union>
+     </xs:simpleType>
+    </xs:list>
+   </xs:simpleType>
+  </xs:union>
+ </xs:simpleType>
+
+ <xs:element name="attribute" type="xs:topLevelAttribute" id="attribute">
+  <xs:annotation>
+   <xs:documentation source="http://www.w3.org/TR/xmlschema-1/#element-attribute"/>
+  </xs:annotation>
+ </xs:element>
+
+ <xs:complexType name="attributeGroup" abstract="true">
+  <xs:complexContent>
+   <xs:extension base="xs:annotated">
+    <xs:group ref="xs:attrDecls"/>
+    <xs:attributeGroup ref="xs:defRef"/>
+   </xs:extension>
+  </xs:complexContent>
+ </xs:complexType>
+ 
+ <xs:complexType name="namedAttributeGroup">
+  <xs:complexContent>
+   <xs:restriction base="xs:attributeGroup">
+    <xs:sequence>
+     <xs:element ref="xs:annotation" minOccurs="0"/>
+     <xs:group ref="xs:attrDecls"/>
+    </xs:sequence>
+    <xs:attribute name="name" use="required" type="xs:NCName"/>
+    <xs:attribute name="ref" use="prohibited"/>
+    <xs:anyAttribute namespace="##other" processContents="lax"/>
+   </xs:restriction>
+  </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="attributeGroupRef">
+  <xs:complexContent>
+   <xs:restriction base="xs:attributeGroup">
+    <xs:sequence>
+     <xs:element ref="xs:annotation" minOccurs="0"/>
+    </xs:sequence>
+    <xs:attribute name="ref" use="required" type="xs:QName"/>
+    <xs:attribute name="name" use="prohibited"/>
+    <xs:anyAttribute namespace="##other" processContents="lax"/>
+   </xs:restriction>
+  </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="attributeGroup" type="xs:namedAttributeGroup" id="attributeGroup">
+  <xs:annotation>
+   <xs:documentation source="http://www.w3.org/TR/xmlschema-1/#element-attributeGroup"/>
+  </xs:annotation>
+ </xs:element>
+
+ <xs:element name="include" id="include">
+  <xs:annotation>
+   <xs:documentation source="http://www.w3.org/TR/xmlschema-1/#element-include"/>
+  </xs:annotation>
+  <xs:complexType>
+   <xs:complexContent>
+    <xs:extension base="xs:annotated">
+     <xs:attribute name="schemaLocation" type="xs:anyURI" use="required"/>
+    </xs:extension>
+   </xs:complexContent>
+  </xs:complexType>
+ </xs:element>
+
+ <xs:element name="redefine" id="redefine">
+  <xs:annotation>
+   <xs:documentation source="http://www.w3.org/TR/xmlschema-1/#element-redefine"/>
+  </xs:annotation>
+  <xs:complexType>
+   <xs:complexContent>
+    <xs:extension base="xs:openAttrs">
+     <xs:choice minOccurs="0" maxOccurs="unbounded">
+      <xs:element ref="xs:annotation"/>
+      <xs:group ref="xs:redefinable"/>
+     </xs:choice>
+     <xs:attribute name="schemaLocation" type="xs:anyURI" use="required"/>
+     <xs:attribute name="id" type="xs:ID"/>
+    </xs:extension>
+   </xs:complexContent>
+  </xs:complexType>
+ </xs:element>
+
+ <xs:element name="import" id="import">
+  <xs:annotation>
+   <xs:documentation source="http://www.w3.org/TR/xmlschema-1/#element-import"/>
+  </xs:annotation>
+  <xs:complexType>
+   <xs:complexContent>
+    <xs:extension base="xs:annotated">
+     <xs:attribute name="namespace" type="xs:anyURI"/>
+     <xs:attribute name="schemaLocation" type="xs:anyURI"/>
+    </xs:extension>
+   </xs:complexContent>
+  </xs:complexType>
+ </xs:element>
+
+ <xs:element name="selector" id="selector">
+  <xs:annotation>
+   <xs:documentation source="http://www.w3.org/TR/xmlschema-1/#element-selector"/>
+  </xs:annotation>
+  <xs:complexType>
+  <xs:complexContent>
+   <xs:extension base="xs:annotated">
+     <xs:attribute name="xpath" use="required">
+      <xs:simpleType>
+       <xs:annotation>
+        <xs:documentation>A subset of XPath expressions for use
+in selectors</xs:documentation>
+        <xs:documentation>A utility type, not for public
+use</xs:documentation>
+       </xs:annotation>
+       <xs:restriction base="xs:token">
+        <xs:annotation>
+         <xs:documentation>The following pattern is intended to allow XPath
+                           expressions per the following EBNF:
+          Selector    ::=    Path ( '|' Path )*  
+          Path    ::=    ('.//')? Step ( '/' Step )*  
+          Step    ::=    '.' | NameTest  
+          NameTest    ::=    QName | '*' | NCName ':' '*'  
+                           child:: is also allowed
+         </xs:documentation>
+        </xs:annotation>
+        <xs:pattern value="(\.//)?(((child::)?((\i\c*:)?(\i\c*|\*)))|\.)(/(((child::)?((\i\c*:)?(\i\c*|\*)))|\.))*(\|(\.//)?(((child::)?((\i\c*:)?(\i\c*|\*)))|\.)(/(((child::)?((\i\c*:)?(\i\c*|\*)))|\.))*)*">
+        </xs:pattern>
+       </xs:restriction>
+      </xs:simpleType>
+     </xs:attribute>
+   </xs:extension>
+  </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="field" id="field">
+  <xs:annotation>
+   <xs:documentation source="http://www.w3.org/TR/xmlschema-1/#element-field"/>
+  </xs:annotation>
+  <xs:complexType>
+  <xs:complexContent>
+   <xs:extension base="xs:annotated">
+     <xs:attribute name="xpath" use="required">
+      <xs:simpleType>
+       <xs:annotation>
+        <xs:documentation>A subset of XPath expressions for use
+in fields</xs:documentation>
+        <xs:documentation>A utility type, not for public
+use</xs:documentation>
+       </xs:annotation>
+       <xs:restriction base="xs:token">
+        <xs:annotation>
+         <xs:documentation>The following pattern is intended to allow XPath
+                           expressions per the same EBNF as for selector,
+                           with the following change:
+          Path    ::=    ('.//')? ( Step '/' )* ( Step | '@' NameTest ) 
+         </xs:documentation>
+        </xs:annotation>
+        <xs:pattern value="(\.//)?((((child::)?((\i\c*:)?(\i\c*|\*)))|\.)/)*((((child::)?((\i\c*:)?(\i\c*|\*)))|\.)|((attribute::|@)((\i\c*:)?(\i\c*|\*))))(\|(\.//)?((((child::)?((\i\c*:)?(\i\c*|\*)))|\.)/)*((((child::)?((\i\c*:)?(\i\c*|\*)))|\.)|((attribute::|@)((\i\c*:)?(\i\c*|\*)))))*">
+        </xs:pattern>
+       </xs:restriction>
+      </xs:simpleType>
+     </xs:attribute>
+   </xs:extension>
+  </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:complexType name="keybase">
+  <xs:complexContent>
+   <xs:extension base="xs:annotated">
+    <xs:sequence>
+     <xs:element ref="xs:selector"/>
+     <xs:element ref="xs:field" minOccurs="1" maxOccurs="unbounded"/>
+    </xs:sequence>
+    <xs:attribute name="name" type="xs:NCName" use="required"/>
+   </xs:extension>
+  </xs:complexContent>
+ </xs:complexType>
+
+ <xs:group name="identityConstraint">
+  <xs:annotation>
+   <xs:documentation>The three kinds of identity constraints, all with
+                     type of or derived from 'keybase'.
+   </xs:documentation>
+  </xs:annotation>
+  <xs:choice>
+   <xs:element ref="xs:unique"/>
+   <xs:element ref="xs:key"/>
+   <xs:element ref="xs:keyref"/>
+  </xs:choice>
+ </xs:group>
+
+ <xs:element name="unique" type="xs:keybase" id="unique">
+  <xs:annotation>
+   <xs:documentation source="http://www.w3.org/TR/xmlschema-1/#element-unique"/>
+  </xs:annotation>
+ </xs:element>
+ <xs:element name="key" type="xs:keybase" id="key">
+  <xs:annotation>
+   <xs:documentation source="http://www.w3.org/TR/xmlschema-1/#element-key"/>
+  </xs:annotation>
+ </xs:element>
+ <xs:element name="keyref" id="keyref">
+  <xs:annotation>
+   <xs:documentation source="http://www.w3.org/TR/xmlschema-1/#element-keyref"/>
+  </xs:annotation>
+  <xs:complexType>
+   <xs:complexContent>
+    <xs:extension base="xs:keybase">
+     <xs:attribute name="refer" type="xs:QName" use="required"/>
+    </xs:extension>
+   </xs:complexContent>
+  </xs:complexType>
+ </xs:element>
+
+ <xs:element name="notation" id="notation">
+  <xs:annotation>
+   <xs:documentation source="http://www.w3.org/TR/xmlschema-1/#element-notation"/>
+  </xs:annotation>
+  <xs:complexType>
+   <xs:complexContent>
+    <xs:extension base="xs:annotated">
+     <xs:attribute name="name" type="xs:NCName" use="required"/>
+     <xs:attribute name="public" type="xs:public"/>
+     <xs:attribute name="system" type="xs:anyURI"/>
+    </xs:extension>
+   </xs:complexContent>
+  </xs:complexType>
+ </xs:element>
+
+ <xs:simpleType name="public">
+  <xs:annotation>
+   <xs:documentation>
+   A utility type, not for public use</xs:documentation>
+   <xs:documentation>
+   A public identifier, per ISO 8879</xs:documentation>
+  </xs:annotation>
+  <xs:restriction base="xs:token"/>
+ </xs:simpleType>
+
+ <xs:element name="appinfo" id="appinfo">
+   <xs:annotation>
+     <xs:documentation source="http://www.w3.org/TR/xmlschema-1/#element-appinfo"/>
+   </xs:annotation>
+   <xs:complexType mixed="true">
+    <xs:sequence minOccurs="0" maxOccurs="unbounded">
+     <xs:any processContents="lax"/>
+    </xs:sequence>
+    <xs:attribute name="source" type="xs:anyURI"/>
+    <xs:anyAttribute namespace="##other" processContents="lax"/>
+   </xs:complexType>
+ </xs:element>
+
+ <xs:element name="documentation" id="documentation">
+   <xs:annotation>
+     <xs:documentation source="http://www.w3.org/TR/xmlschema-1/#element-documentation"/>
+   </xs:annotation>
+   <xs:complexType mixed="true">
+    <xs:sequence minOccurs="0" maxOccurs="unbounded">
+     <xs:any processContents="lax"/>
+    </xs:sequence>
+    <xs:attribute name="source" type="xs:anyURI"/>
+    <xs:attribute ref="xml:lang"/>
+    <xs:anyAttribute namespace="##other" processContents="lax"/>
+   </xs:complexType>
+ </xs:element>
+
+ <xs:element name="annotation" id="annotation">
+   <xs:annotation>
+     <xs:documentation source="http://www.w3.org/TR/xmlschema-1/#element-annotation"/>
+   </xs:annotation>
+   <xs:complexType>
+    <xs:complexContent>
+     <xs:extension base="xs:openAttrs">
+      <xs:choice minOccurs="0" maxOccurs="unbounded">
+       <xs:element ref="xs:appinfo"/>
+       <xs:element ref="xs:documentation"/>
+      </xs:choice>
+      <xs:attribute name="id" type="xs:ID"/>
+     </xs:extension>
+    </xs:complexContent>
+   </xs:complexType>
+ </xs:element>
+
+ <xs:annotation>
+  <xs:documentation>
+   notations for use within XML Schema schemas</xs:documentation>
+ </xs:annotation>
+
+ <xs:notation name="XMLSchemaStructures" public="structures" system="http://www.w3.org/2000/08/XMLSchema.xsd"/>
+ <xs:notation name="XML" public="REC-xml-19980210" system="http://www.w3.org/TR/1998/REC-xml-19980210"/>
+  
+ <xs:complexType name="anyType" mixed="true">
+  <xs:annotation>
+   <xs:documentation>
+   Not the real urType, but as close an approximation as we can
+   get in the XML representation</xs:documentation>
+  </xs:annotation>
+  <xs:sequence>
+   <xs:any minOccurs="0" maxOccurs="unbounded" processContents="lax"/>
+  </xs:sequence>
+  <xs:anyAttribute processContents="lax"/>
+ </xs:complexType>
+
+  <xs:annotation>
+    <xs:documentation>
+      First the built-in primitive datatypes.  These definitions are for
+      information only, the real built-in definitions are magic.
+    </xs:documentation>
+
+    <xs:documentation>
+      For each built-in datatype in this schema (both primitive and
+      derived) can be uniquely addressed via a URI constructed
+      as follows:
+        1) the base URI is the URI of the XML Schema namespace
+        2) the fragment identifier is the name of the datatype
+
+      For example, to address the int datatype, the URI is:
+
+        http://www.w3.org/2001/XMLSchema#int
+
+      Additionally, each facet definition element can be uniquely
+      addressed via a URI constructed as follows:
+        1) the base URI is the URI of the XML Schema namespace
+        2) the fragment identifier is the name of the facet
+
+      For example, to address the maxInclusive facet, the URI is:
+
+        http://www.w3.org/2001/XMLSchema#maxInclusive
+
+      Additionally, each facet usage in a built-in datatype definition
+      can be uniquely addressed via a URI constructed as follows:
+        1) the base URI is the URI of the XML Schema namespace
+        2) the fragment identifier is the name of the datatype, followed
+           by a period (".") followed by the name of the facet
+
+      For example, to address the usage of the maxInclusive facet in
+      the definition of int, the URI is:
+
+        http://www.w3.org/2001/XMLSchema#int.maxInclusive
+
+    </xs:documentation>
+  </xs:annotation>
+
+  <xs:simpleType name="string" id="string">
+    <xs:annotation>
+      <xs:appinfo>
+        <hfp:hasFacet name="length"/>
+        <hfp:hasFacet name="minLength"/>
+        <hfp:hasFacet name="maxLength"/>
+        <hfp:hasFacet name="pattern"/>
+        <hfp:hasFacet name="enumeration"/>
+        <hfp:hasFacet name="whiteSpace"/>
+        <hfp:hasProperty name="ordered" value="false"/>
+        <hfp:hasProperty name="bounded" value="false"/>
+        <hfp:hasProperty name="cardinality" value="countably infinite"/>
+        <hfp:hasProperty name="numeric" value="false"/>
+      </xs:appinfo>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#string"/>
+    </xs:annotation>
+    <xs:restriction base="xs:anySimpleType">
+      <xs:whiteSpace value="preserve" id="string.preserve"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:simpleType name="boolean" id="boolean">
+    <xs:annotation>
+      <xs:appinfo>
+        <hfp:hasFacet name="pattern"/>
+        <hfp:hasFacet name="whiteSpace"/>
+        <hfp:hasProperty name="ordered" value="false"/>
+        <hfp:hasProperty name="bounded" value="false"/>
+        <hfp:hasProperty name="cardinality" value="finite"/>
+        <hfp:hasProperty name="numeric" value="false"/>
+      </xs:appinfo>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#boolean"/>
+    </xs:annotation>
+    <xs:restriction base="xs:anySimpleType">
+      <xs:whiteSpace value="collapse" fixed="true" id="boolean.whiteSpace"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:simpleType name="float" id="float">
+    <xs:annotation>
+      <xs:appinfo>
+        <hfp:hasFacet name="pattern"/>
+        <hfp:hasFacet name="enumeration"/>
+        <hfp:hasFacet name="whiteSpace"/>
+        <hfp:hasFacet name="maxInclusive"/>
+        <hfp:hasFacet name="maxExclusive"/>
+        <hfp:hasFacet name="minInclusive"/>
+        <hfp:hasFacet name="minExclusive"/>
+        <hfp:hasProperty name="ordered" value="total"/>
+        <hfp:hasProperty name="bounded" value="true"/>
+        <hfp:hasProperty name="cardinality" value="finite"/>
+        <hfp:hasProperty name="numeric" value="true"/>
+      </xs:appinfo>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#float"/>
+    </xs:annotation>
+    <xs:restriction base="xs:anySimpleType">
+      <xs:whiteSpace value="collapse" fixed="true" id="float.whiteSpace"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:simpleType name="double" id="double">
+    <xs:annotation>
+      <xs:appinfo>
+        <hfp:hasFacet name="pattern"/>
+        <hfp:hasFacet name="enumeration"/>
+        <hfp:hasFacet name="whiteSpace"/>
+        <hfp:hasFacet name="maxInclusive"/>
+        <hfp:hasFacet name="maxExclusive"/>
+        <hfp:hasFacet name="minInclusive"/>
+        <hfp:hasFacet name="minExclusive"/>
+        <hfp:hasProperty name="ordered" value="total"/>
+        <hfp:hasProperty name="bounded" value="true"/>
+        <hfp:hasProperty name="cardinality" value="finite"/>
+        <hfp:hasProperty name="numeric" value="true"/>
+      </xs:appinfo>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#double"/>
+    </xs:annotation>
+    <xs:restriction base="xs:anySimpleType">
+      <xs:whiteSpace value="collapse" fixed="true" id="double.whiteSpace"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:simpleType name="decimal" id="decimal">
+    <xs:annotation>
+      <xs:appinfo>
+        <hfp:hasFacet name="totalDigits"/>
+        <hfp:hasFacet name="fractionDigits"/>
+        <hfp:hasFacet name="pattern"/>
+        <hfp:hasFacet name="whiteSpace"/>
+        <hfp:hasFacet name="enumeration"/>
+        <hfp:hasFacet name="maxInclusive"/>
+        <hfp:hasFacet name="maxExclusive"/>
+        <hfp:hasFacet name="minInclusive"/>
+        <hfp:hasFacet name="minExclusive"/>
+        <hfp:hasProperty name="ordered" value="total"/>
+        <hfp:hasProperty name="bounded" value="false"/>
+        <hfp:hasProperty name="cardinality" value="countably infinite"/>
+        <hfp:hasProperty name="numeric" value="true"/>
+      </xs:appinfo>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#decimal"/>
+    </xs:annotation>
+    <xs:restriction base="xs:anySimpleType">
+      <xs:whiteSpace value="collapse" fixed="true" id="decimal.whiteSpace"/>
+    </xs:restriction>
+   </xs:simpleType>
+
+   <xs:simpleType name="duration" id="duration">
+    <xs:annotation>
+      <xs:appinfo>
+        <hfp:hasFacet name="pattern"/>
+        <hfp:hasFacet name="enumeration"/>
+        <hfp:hasFacet name="whiteSpace"/>
+        <hfp:hasFacet name="maxInclusive"/>
+        <hfp:hasFacet name="maxExclusive"/>
+        <hfp:hasFacet name="minInclusive"/>
+        <hfp:hasFacet name="minExclusive"/>
+        <hfp:hasProperty name="ordered" value="partial"/>
+        <hfp:hasProperty name="bounded" value="false"/>
+        <hfp:hasProperty name="cardinality" value="countably infinite"/>
+        <hfp:hasProperty name="numeric" value="false"/>
+      </xs:appinfo>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#duration"/>
+    </xs:annotation>
+    <xs:restriction base="xs:anySimpleType">
+      <xs:whiteSpace value="collapse" fixed="true" id="duration.whiteSpace"/>
+    </xs:restriction>
+   </xs:simpleType>
+
+ <xs:simpleType name="dateTime" id="dateTime">
+    <xs:annotation>
+    <xs:appinfo>
+        <hfp:hasFacet name="pattern"/>
+        <hfp:hasFacet name="enumeration"/>
+        <hfp:hasFacet name="whiteSpace"/>
+        <hfp:hasFacet name="maxInclusive"/>
+        <hfp:hasFacet name="maxExclusive"/>
+        <hfp:hasFacet name="minInclusive"/>
+        <hfp:hasFacet name="minExclusive"/>
+        <hfp:hasProperty name="ordered" value="partial"/>
+        <hfp:hasProperty name="bounded" value="false"/>
+        <hfp:hasProperty name="cardinality" value="countably infinite"/>
+        <hfp:hasProperty name="numeric" value="false"/>
+      </xs:appinfo>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#dateTime"/>
+    </xs:annotation>
+    <xs:restriction base="xs:anySimpleType">
+      <xs:whiteSpace value="collapse" fixed="true" id="dateTime.whiteSpace"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:simpleType name="time" id="time">
+    <xs:annotation>
+    <xs:appinfo>
+        <hfp:hasFacet name="pattern"/>
+        <hfp:hasFacet name="enumeration"/>
+        <hfp:hasFacet name="whiteSpace"/>
+        <hfp:hasFacet name="maxInclusive"/>
+        <hfp:hasFacet name="maxExclusive"/>
+        <hfp:hasFacet name="minInclusive"/>
+        <hfp:hasFacet name="minExclusive"/>
+        <hfp:hasProperty name="ordered" value="partial"/>
+        <hfp:hasProperty name="bounded" value="false"/>
+        <hfp:hasProperty name="cardinality" value="countably infinite"/>
+        <hfp:hasProperty name="numeric" value="false"/>
+      </xs:appinfo>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#time"/>
+    </xs:annotation>
+    <xs:restriction base="xs:anySimpleType">
+      <xs:whiteSpace value="collapse" fixed="true" id="time.whiteSpace"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:simpleType name="date" id="date">
+   <xs:annotation>
+    <xs:appinfo>
+        <hfp:hasFacet name="pattern"/>
+        <hfp:hasFacet name="enumeration"/>
+        <hfp:hasFacet name="whiteSpace"/>
+        <hfp:hasFacet name="maxInclusive"/>
+        <hfp:hasFacet name="maxExclusive"/>
+        <hfp:hasFacet name="minInclusive"/>
+        <hfp:hasFacet name="minExclusive"/>
+        <hfp:hasProperty name="ordered" value="partial"/>
+        <hfp:hasProperty name="bounded" value="false"/>
+        <hfp:hasProperty name="cardinality" value="countably infinite"/>
+        <hfp:hasProperty name="numeric" value="false"/>
+      </xs:appinfo>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#date"/>
+    </xs:annotation>
+    <xs:restriction base="xs:anySimpleType">
+      <xs:whiteSpace value="collapse" fixed="true" id="date.whiteSpace"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:simpleType name="gYearMonth" id="gYearMonth">
+   <xs:annotation>
+    <xs:appinfo>
+        <hfp:hasFacet name="pattern"/>
+        <hfp:hasFacet name="enumeration"/>
+        <hfp:hasFacet name="whiteSpace"/>
+        <hfp:hasFacet name="maxInclusive"/>
+        <hfp:hasFacet name="maxExclusive"/>
+        <hfp:hasFacet name="minInclusive"/>
+        <hfp:hasFacet name="minExclusive"/>
+        <hfp:hasProperty name="ordered" value="partial"/>
+        <hfp:hasProperty name="bounded" value="false"/>
+        <hfp:hasProperty name="cardinality" value="countably infinite"/>
+        <hfp:hasProperty name="numeric" value="false"/>
+      </xs:appinfo>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#gYearMonth"/>
+    </xs:annotation>
+    <xs:restriction base="xs:anySimpleType">
+      <xs:whiteSpace value="collapse" fixed="true" id="gYearMonth.whiteSpace"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:simpleType name="gYear" id="gYear">
+    <xs:annotation>
+    <xs:appinfo>
+        <hfp:hasFacet name="pattern"/>
+        <hfp:hasFacet name="enumeration"/>
+        <hfp:hasFacet name="whiteSpace"/>
+        <hfp:hasFacet name="maxInclusive"/>
+        <hfp:hasFacet name="maxExclusive"/>
+        <hfp:hasFacet name="minInclusive"/>
+        <hfp:hasFacet name="minExclusive"/>
+        <hfp:hasProperty name="ordered" value="partial"/>
+        <hfp:hasProperty name="bounded" value="false"/>
+        <hfp:hasProperty name="cardinality" value="countably infinite"/>
+        <hfp:hasProperty name="numeric" value="false"/>
+      </xs:appinfo>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#gYear"/>
+    </xs:annotation>
+    <xs:restriction base="xs:anySimpleType">
+      <xs:whiteSpace value="collapse" fixed="true" id="gYear.whiteSpace"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+ <xs:simpleType name="gMonthDay" id="gMonthDay">
+    <xs:annotation>
+      <xs:appinfo>
+        <hfp:hasFacet name="pattern"/>
+        <hfp:hasFacet name="enumeration"/>
+        <hfp:hasFacet name="whiteSpace"/>
+        <hfp:hasFacet name="maxInclusive"/>
+        <hfp:hasFacet name="maxExclusive"/>
+        <hfp:hasFacet name="minInclusive"/>
+        <hfp:hasFacet name="minExclusive"/>
+        <hfp:hasProperty name="ordered" value="partial"/>
+        <hfp:hasProperty name="bounded" value="false"/>
+        <hfp:hasProperty name="cardinality" value="countably infinite"/>
+        <hfp:hasProperty name="numeric" value="false"/>
+      </xs:appinfo>
+       <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#gMonthDay"/>
+    </xs:annotation>
+    <xs:restriction base="xs:anySimpleType">
+         <xs:whiteSpace value="collapse" fixed="true" id="gMonthDay.whiteSpace"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:simpleType name="gDay" id="gDay">
+    <xs:annotation>
+  <xs:appinfo>
+        <hfp:hasFacet name="pattern"/>
+        <hfp:hasFacet name="enumeration"/>
+        <hfp:hasFacet name="whiteSpace"/>
+        <hfp:hasFacet name="maxInclusive"/>
+        <hfp:hasFacet name="maxExclusive"/>
+        <hfp:hasFacet name="minInclusive"/>
+        <hfp:hasFacet name="minExclusive"/>
+        <hfp:hasProperty name="ordered" value="partial"/>
+        <hfp:hasProperty name="bounded" value="false"/>
+        <hfp:hasProperty name="cardinality" value="countably infinite"/>
+        <hfp:hasProperty name="numeric" value="false"/>
+      </xs:appinfo>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#gDay"/>
+    </xs:annotation>
+    <xs:restriction base="xs:anySimpleType">
+         <xs:whiteSpace value="collapse" fixed="true" id="gDay.whiteSpace"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+ <xs:simpleType name="gMonth" id="gMonth">
+    <xs:annotation>
+  <xs:appinfo>
+        <hfp:hasFacet name="pattern"/>
+        <hfp:hasFacet name="enumeration"/>
+        <hfp:hasFacet name="whiteSpace"/>
+        <hfp:hasFacet name="maxInclusive"/>
+        <hfp:hasFacet name="maxExclusive"/>
+        <hfp:hasFacet name="minInclusive"/>
+        <hfp:hasFacet name="minExclusive"/>
+        <hfp:hasProperty name="ordered" value="partial"/>
+        <hfp:hasProperty name="bounded" value="false"/>
+        <hfp:hasProperty name="cardinality" value="countably infinite"/>
+        <hfp:hasProperty name="numeric" value="false"/>
+      </xs:appinfo>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#gMonth"/>
+    </xs:annotation>
+    <xs:restriction base="xs:anySimpleType">
+         <xs:whiteSpace value="collapse" fixed="true" id="gMonth.whiteSpace"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+   <xs:simpleType name="hexBinary" id="hexBinary">
+    <xs:annotation>
+      <xs:appinfo>
+        <hfp:hasFacet name="length"/>
+        <hfp:hasFacet name="minLength"/>
+        <hfp:hasFacet name="maxLength"/>
+        <hfp:hasFacet name="pattern"/>
+        <hfp:hasFacet name="enumeration"/>
+        <hfp:hasFacet name="whiteSpace"/>
+        <hfp:hasProperty name="ordered" value="false"/>
+        <hfp:hasProperty name="bounded" value="false"/>
+        <hfp:hasProperty name="cardinality" value="countably infinite"/>
+        <hfp:hasProperty name="numeric" value="false"/>
+      </xs:appinfo>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#binary"/>
+    </xs:annotation>
+    <xs:restriction base="xs:anySimpleType">
+      <xs:whiteSpace value="collapse" fixed="true" id="hexBinary.whiteSpace"/>
+    </xs:restriction>
+   </xs:simpleType>
+
+ <xs:simpleType name="base64Binary" id="base64Binary">
+    <xs:annotation>
+      <xs:appinfo>
+        <hfp:hasFacet name="length"/>
+        <hfp:hasFacet name="minLength"/>
+        <hfp:hasFacet name="maxLength"/>
+        <hfp:hasFacet name="pattern"/>
+        <hfp:hasFacet name="enumeration"/>
+        <hfp:hasFacet name="whiteSpace"/>
+        <hfp:hasProperty name="ordered" value="false"/>
+        <hfp:hasProperty name="bounded" value="false"/>
+        <hfp:hasProperty name="cardinality" value="countably infinite"/>
+        <hfp:hasProperty name="numeric" value="false"/>
+      </xs:appinfo>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#base64Binary"/>
+    </xs:annotation>
+    <xs:restriction base="xs:anySimpleType">
+      <xs:whiteSpace value="collapse" fixed="true" id="base64Binary.whiteSpace"/>
+    </xs:restriction>
+   </xs:simpleType>
+
+   <xs:simpleType name="anyURI" id="anyURI">
+    <xs:annotation>
+      <xs:appinfo>
+        <hfp:hasFacet name="length"/>
+        <hfp:hasFacet name="minLength"/>
+        <hfp:hasFacet name="maxLength"/>
+        <hfp:hasFacet name="pattern"/>
+        <hfp:hasFacet name="enumeration"/>
+        <hfp:hasFacet name="whiteSpace"/>
+        <hfp:hasProperty name="ordered" value="false"/>
+        <hfp:hasProperty name="bounded" value="false"/>
+        <hfp:hasProperty name="cardinality" value="countably infinite"/>
+        <hfp:hasProperty name="numeric" value="false"/>
+      </xs:appinfo>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#anyURI"/>
+    </xs:annotation>
+    <xs:restriction base="xs:anySimpleType">
+      <xs:whiteSpace value="collapse" fixed="true" id="anyURI.whiteSpace"/>
+    </xs:restriction>
+   </xs:simpleType>
+
+  <xs:simpleType name="QName" id="QName">
+    <xs:annotation>
+        <xs:appinfo>
+        <hfp:hasFacet name="length"/>
+        <hfp:hasFacet name="minLength"/>
+        <hfp:hasFacet name="maxLength"/>
+        <hfp:hasFacet name="pattern"/>
+        <hfp:hasFacet name="enumeration"/>
+        <hfp:hasFacet name="whiteSpace"/>
+        <hfp:hasProperty name="ordered" value="false"/>
+        <hfp:hasProperty name="bounded" value="false"/>
+        <hfp:hasProperty name="cardinality" value="countably infinite"/>
+        <hfp:hasProperty name="numeric" value="false"/>
+      </xs:appinfo>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#QName"/>
+    </xs:annotation>
+    <xs:restriction base="xs:anySimpleType">
+      <xs:whiteSpace value="collapse" fixed="true" id="QName.whiteSpace"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+   <xs:simpleType name="NOTATION" id="NOTATION">
+    <xs:annotation>
+        <xs:appinfo>
+        <hfp:hasFacet name="length"/>
+        <hfp:hasFacet name="minLength"/>
+        <hfp:hasFacet name="maxLength"/>
+        <hfp:hasFacet name="pattern"/>
+        <hfp:hasFacet name="enumeration"/>
+        <hfp:hasFacet name="whiteSpace"/>
+        <hfp:hasProperty name="ordered" value="false"/>
+        <hfp:hasProperty name="bounded" value="false"/>
+        <hfp:hasProperty name="cardinality" value="countably infinite"/>
+        <hfp:hasProperty name="numeric" value="false"/>
+      </xs:appinfo>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#NOTATION"/>
+      <xs:documentation>
+        NOTATION cannot be used directly in a schema; rather a type
+        must be derived from it by specifying at least one enumeration
+        facet whose value is the name of a NOTATION declared in the
+        schema.
+      </xs:documentation>
+    </xs:annotation>
+    <xs:restriction base="xs:anySimpleType">
+      <xs:whiteSpace value="collapse" fixed="true" id="NOTATION.whiteSpace"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:annotation>
+    <xs:documentation>
+      Now the derived primitive types
+    </xs:documentation>
+  </xs:annotation>
+
+  <xs:simpleType name="normalizedString" id="normalizedString">
+    <xs:annotation>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#normalizedString"/>
+    </xs:annotation>
+    <xs:restriction base="xs:string">
+      <xs:whiteSpace value="replace" id="normalizedString.whiteSpace"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:simpleType name="token" id="token">
+    <xs:annotation>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#token"/>
+    </xs:annotation>
+    <xs:restriction base="xs:normalizedString">
+      <xs:whiteSpace value="collapse" id="token.whiteSpace"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:simpleType name="language" id="language">
+    <xs:annotation>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#language"/>
+    </xs:annotation>
+    <xs:restriction base="xs:token">
+      <xs:pattern value="[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*" id="language.pattern">
+        <xs:annotation>
+          <xs:documentation source="http://www.ietf.org/rfc/rfc3066.txt">
+            pattern specifies the content of section 2.12 of XML 1.0e2
+            and RFC 3066 (Revised version of RFC 1766).
+          </xs:documentation>
+        </xs:annotation>
+      </xs:pattern>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:simpleType name="IDREFS" id="IDREFS">
+    <xs:annotation>
+      <xs:appinfo>
+        <hfp:hasFacet name="length"/>
+        <hfp:hasFacet name="minLength"/>
+        <hfp:hasFacet name="maxLength"/>
+        <hfp:hasFacet name="enumeration"/>
+        <hfp:hasFacet name="whiteSpace"/>
+        <hfp:hasFacet name="pattern"/>
+        <hfp:hasProperty name="ordered" value="false"/>
+        <hfp:hasProperty name="bounded" value="false"/>
+        <hfp:hasProperty name="cardinality" value="countably infinite"/>
+        <hfp:hasProperty name="numeric" value="false"/>
+      </xs:appinfo>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#IDREFS"/>
+    </xs:annotation>
+    <xs:restriction>
+      <xs:simpleType>
+        <xs:list itemType="xs:IDREF"/>
+      </xs:simpleType>
+        <xs:minLength value="1" id="IDREFS.minLength"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:simpleType name="ENTITIES" id="ENTITIES">
+    <xs:annotation>
+      <xs:appinfo>
+        <hfp:hasFacet name="length"/>
+        <hfp:hasFacet name="minLength"/>
+        <hfp:hasFacet name="maxLength"/>
+        <hfp:hasFacet name="enumeration"/>
+        <hfp:hasFacet name="whiteSpace"/>
+        <hfp:hasFacet name="pattern"/>
+        <hfp:hasProperty name="ordered" value="false"/>
+        <hfp:hasProperty name="bounded" value="false"/>
+        <hfp:hasProperty name="cardinality" value="countably infinite"/>
+        <hfp:hasProperty name="numeric" value="false"/>
+      </xs:appinfo>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#ENTITIES"/>
+    </xs:annotation>
+    <xs:restriction>
+      <xs:simpleType>
+        <xs:list itemType="xs:ENTITY"/>
+      </xs:simpleType>
+        <xs:minLength value="1" id="ENTITIES.minLength"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:simpleType name="NMTOKEN" id="NMTOKEN">
+    <xs:annotation>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#NMTOKEN"/>
+    </xs:annotation>
+    <xs:restriction base="xs:token">
+      <xs:pattern value="\c+" id="NMTOKEN.pattern">
+        <xs:annotation>
+          <xs:documentation source="http://www.w3.org/TR/REC-xml#NT-Nmtoken">
+            pattern matches production 7 from the XML spec
+          </xs:documentation>
+        </xs:annotation>
+      </xs:pattern>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:simpleType name="NMTOKENS" id="NMTOKENS">
+    <xs:annotation>
+      <xs:appinfo>
+        <hfp:hasFacet name="length"/>
+        <hfp:hasFacet name="minLength"/>
+        <hfp:hasFacet name="maxLength"/>
+        <hfp:hasFacet name="enumeration"/>
+        <hfp:hasFacet name="whiteSpace"/>
+        <hfp:hasFacet name="pattern"/>
+        <hfp:hasProperty name="ordered" value="false"/>
+        <hfp:hasProperty name="bounded" value="false"/>
+        <hfp:hasProperty name="cardinality" value="countably infinite"/>
+        <hfp:hasProperty name="numeric" value="false"/>
+      </xs:appinfo>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#NMTOKENS"/>
+    </xs:annotation>
+    <xs:restriction>
+      <xs:simpleType>
+        <xs:list itemType="xs:NMTOKEN"/>
+      </xs:simpleType>
+        <xs:minLength value="1" id="NMTOKENS.minLength"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:simpleType name="Name" id="Name">
+    <xs:annotation>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#Name"/>
+    </xs:annotation>
+    <xs:restriction base="xs:token">
+      <xs:pattern value="\i\c*" id="Name.pattern">
+        <xs:annotation>
+          <xs:documentation source="http://www.w3.org/TR/REC-xml#NT-Name">
+            pattern matches production 5 from the XML spec
+          </xs:documentation>
+        </xs:annotation>
+      </xs:pattern>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:simpleType name="NCName" id="NCName">
+    <xs:annotation>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#NCName"/>
+    </xs:annotation>
+    <xs:restriction base="xs:Name">
+      <xs:pattern value="[\i-[:]][\c-[:]]*" id="NCName.pattern">
+        <xs:annotation>
+          <xs:documentation source="http://www.w3.org/TR/REC-xml-names/#NT-NCName">
+            pattern matches production 4 from the Namespaces in XML spec
+          </xs:documentation>
+        </xs:annotation>
+      </xs:pattern>
+    </xs:restriction>
+  </xs:simpleType>
+
+   <xs:simpleType name="ID" id="ID">
+    <xs:annotation>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#ID"/>
+    </xs:annotation>
+    <xs:restriction base="xs:NCName"/>
+   </xs:simpleType>
+
+   <xs:simpleType name="IDREF" id="IDREF">
+    <xs:annotation>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#IDREF"/>
+    </xs:annotation>
+    <xs:restriction base="xs:NCName"/>
+   </xs:simpleType>
+
+   <xs:simpleType name="ENTITY" id="ENTITY">
+    <xs:annotation>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#ENTITY"/>
+    </xs:annotation>
+    <xs:restriction base="xs:NCName"/>
+   </xs:simpleType>
+
+  <xs:simpleType name="integer" id="integer">
+    <xs:annotation>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#integer"/>
+    </xs:annotation>
+    <xs:restriction base="xs:decimal">
+      <xs:fractionDigits value="0" fixed="true" id="integer.fractionDigits"/>
+      <xs:pattern value="[\-+]?[0-9]+"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:simpleType name="nonPositiveInteger" id="nonPositiveInteger">
+    <xs:annotation>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#nonPositiveInteger"/>
+    </xs:annotation>
+    <xs:restriction base="xs:integer">
+      <xs:maxInclusive value="0" id="nonPositiveInteger.maxInclusive"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:simpleType name="negativeInteger" id="negativeInteger">
+    <xs:annotation>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#negativeInteger"/>
+    </xs:annotation>
+    <xs:restriction base="xs:nonPositiveInteger">
+      <xs:maxInclusive value="-1" id="negativeInteger.maxInclusive"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:simpleType name="long" id="long">
+    <xs:annotation>
+      <xs:appinfo>
+        <hfp:hasProperty name="bounded" value="true"/>
+        <hfp:hasProperty name="cardinality" value="finite"/>
+      </xs:appinfo>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#long"/>
+    </xs:annotation>
+    <xs:restriction base="xs:integer">
+      <xs:minInclusive value="-9223372036854775808" id="long.minInclusive"/>
+      <xs:maxInclusive value="9223372036854775807" id="long.maxInclusive"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:simpleType name="int" id="int">
+    <xs:annotation>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#int"/>
+    </xs:annotation>
+    <xs:restriction base="xs:long">
+      <xs:minInclusive value="-2147483648" id="int.minInclusive"/>
+      <xs:maxInclusive value="2147483647" id="int.maxInclusive"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:simpleType name="short" id="short">
+    <xs:annotation>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#short"/>
+    </xs:annotation>
+    <xs:restriction base="xs:int">
+      <xs:minInclusive value="-32768" id="short.minInclusive"/>
+      <xs:maxInclusive value="32767" id="short.maxInclusive"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:simpleType name="byte" id="byte">
+    <xs:annotation>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#byte"/>
+    </xs:annotation>
+    <xs:restriction base="xs:short">
+      <xs:minInclusive value="-128" id="byte.minInclusive"/>
+      <xs:maxInclusive value="127" id="byte.maxInclusive"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:simpleType name="nonNegativeInteger" id="nonNegativeInteger">
+    <xs:annotation>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#nonNegativeInteger"/>
+    </xs:annotation>
+    <xs:restriction base="xs:integer">
+      <xs:minInclusive value="0" id="nonNegativeInteger.minInclusive"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:simpleType name="unsignedLong" id="unsignedLong">
+    <xs:annotation>
+      <xs:appinfo>
+        <hfp:hasProperty name="bounded" value="true"/>
+        <hfp:hasProperty name="cardinality" value="finite"/>
+      </xs:appinfo>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#unsignedLong"/>
+    </xs:annotation>
+    <xs:restriction base="xs:nonNegativeInteger">
+      <xs:maxInclusive value="18446744073709551615" id="unsignedLong.maxInclusive"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:simpleType name="unsignedInt" id="unsignedInt">
+    <xs:annotation>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#unsignedInt"/>
+    </xs:annotation>
+    <xs:restriction base="xs:unsignedLong">
+      <xs:maxInclusive value="4294967295" id="unsignedInt.maxInclusive"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:simpleType name="unsignedShort" id="unsignedShort">
+    <xs:annotation>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#unsignedShort"/>
+    </xs:annotation>
+    <xs:restriction base="xs:unsignedInt">
+      <xs:maxInclusive value="65535" id="unsignedShort.maxInclusive"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:simpleType name="unsignedByte" id="unsignedByte">
+    <xs:annotation>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#unsignedByte"/>
+    </xs:annotation>
+    <xs:restriction base="xs:unsignedShort">
+      <xs:maxInclusive value="255" id="unsignedByte.maxInclusive"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:simpleType name="positiveInteger" id="positiveInteger">
+    <xs:annotation>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#positiveInteger"/>
+    </xs:annotation>
+    <xs:restriction base="xs:nonNegativeInteger">
+      <xs:minInclusive value="1" id="positiveInteger.minInclusive"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+ <xs:simpleType name="derivationControl">
+  <xs:annotation>
+   <xs:documentation>
+   A utility type, not for public use</xs:documentation>
+  </xs:annotation>
+  <xs:restriction base="xs:NMTOKEN">
+   <xs:enumeration value="substitution"/>
+   <xs:enumeration value="extension"/>
+   <xs:enumeration value="restriction"/>
+   <xs:enumeration value="list"/>
+   <xs:enumeration value="union"/>
+  </xs:restriction>
+ </xs:simpleType>
+
+ <xs:group name="simpleDerivation">
+  <xs:choice>
+    <xs:element ref="xs:restriction"/>
+    <xs:element ref="xs:list"/>
+    <xs:element ref="xs:union"/>
+  </xs:choice>
+ </xs:group>
+
+ <xs:simpleType name="simpleDerivationSet">
+  <xs:annotation>
+   <xs:documentation>
+   #all or (possibly empty) subset of {restriction, union, list}
+   </xs:documentation>
+   <xs:documentation>
+   A utility type, not for public use</xs:documentation>
+  </xs:annotation>
+  <xs:union>
+   <xs:simpleType>
+    <xs:restriction base="xs:token">
+     <xs:enumeration value="#all"/>
+    </xs:restriction>
+   </xs:simpleType>
+   <xs:simpleType>
+    <xs:list>
+     <xs:simpleType>
+      <xs:restriction base="xs:derivationControl">
+       <xs:enumeration value="list"/>
+       <xs:enumeration value="union"/>
+       <xs:enumeration value="restriction"/>
+      </xs:restriction>
+     </xs:simpleType>
+    </xs:list>
+   </xs:simpleType>
+  </xs:union>
+ </xs:simpleType>
+
+  <xs:complexType name="simpleType" abstract="true">
+    <xs:complexContent>
+      <xs:extension base="xs:annotated">
+        <xs:group ref="xs:simpleDerivation"/>
+        <xs:attribute name="final" type="xs:simpleDerivationSet"/>
+        <xs:attribute name="name" type="xs:NCName">
+          <xs:annotation>
+            <xs:documentation>
+              Can be restricted to required or forbidden
+            </xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+
+  <xs:complexType name="topLevelSimpleType">
+    <xs:complexContent>
+      <xs:restriction base="xs:simpleType">
+        <xs:sequence>
+          <xs:element ref="xs:annotation" minOccurs="0"/>
+          <xs:group ref="xs:simpleDerivation"/>
+        </xs:sequence>
+        <xs:attribute name="name" use="required" type="xs:NCName">
+          <xs:annotation>
+            <xs:documentation>
+              Required at the top level
+            </xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+       <xs:anyAttribute namespace="##other" processContents="lax"/>
+      </xs:restriction>
+    </xs:complexContent>
+  </xs:complexType>
+
+  <xs:complexType name="localSimpleType">
+    <xs:complexContent>
+      <xs:restriction base="xs:simpleType">
+        <xs:sequence>
+          <xs:element ref="xs:annotation" minOccurs="0"/>
+          <xs:group ref="xs:simpleDerivation"/>
+        </xs:sequence>
+        <xs:attribute name="name" use="prohibited">
+          <xs:annotation>
+            <xs:documentation>
+              Forbidden when nested
+            </xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="final" use="prohibited"/>
+       <xs:anyAttribute namespace="##other" processContents="lax"/>
+      </xs:restriction>
+    </xs:complexContent>
+  </xs:complexType>
+
+  <xs:element name="simpleType" type="xs:topLevelSimpleType" id="simpleType">
+    <xs:annotation>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#element-simpleType"/>
+    </xs:annotation>
+  </xs:element>
+
+  <xs:group name="facets">
+   <xs:annotation>
+    <xs:documentation>
+       We should use a substitution group for facets, but
+       that's ruled out because it would allow users to
+       add their own, which we're not ready for yet.
+    </xs:documentation>
+   </xs:annotation>
+   <xs:choice>
+    <xs:element ref="xs:minExclusive"/>
+    <xs:element ref="xs:minInclusive"/>
+    <xs:element ref="xs:maxExclusive"/>
+    <xs:element ref="xs:maxInclusive"/>
+    <xs:element ref="xs:totalDigits"/>
+    <xs:element ref="xs:fractionDigits"/>
+    <xs:element ref="xs:length"/>
+    <xs:element ref="xs:minLength"/>
+    <xs:element ref="xs:maxLength"/>
+    <xs:element ref="xs:enumeration"/>
+    <xs:element ref="xs:whiteSpace"/>
+    <xs:element ref="xs:pattern"/>
+   </xs:choice>
+  </xs:group>
+
+  <xs:group name="simpleRestrictionModel">
+   <xs:sequence>
+    <xs:element name="simpleType" type="xs:localSimpleType" minOccurs="0"/>
+    <xs:group ref="xs:facets" minOccurs="0" maxOccurs="unbounded"/>
+   </xs:sequence>
+  </xs:group>
+
+  <xs:element name="restriction" id="restriction">
+   <xs:complexType>
+    <xs:annotation>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#element-restriction">
+          base attribute and simpleType child are mutually
+          exclusive, but one or other is required
+        </xs:documentation>
+      </xs:annotation>
+      <xs:complexContent>
+        <xs:extension base="xs:annotated">
+         <xs:group ref="xs:simpleRestrictionModel"/>
+         <xs:attribute name="base" type="xs:QName" use="optional"/>
+        </xs:extension>
+      </xs:complexContent>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="list" id="list">
+   <xs:complexType>
+    <xs:annotation>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#element-list">
+          itemType attribute and simpleType child are mutually
+          exclusive, but one or other is required
+        </xs:documentation>
+      </xs:annotation>
+      <xs:complexContent>
+        <xs:extension base="xs:annotated">
+          <xs:sequence>
+            <xs:element name="simpleType" type="xs:localSimpleType" minOccurs="0"/>
+          </xs:sequence>
+          <xs:attribute name="itemType" type="xs:QName" use="optional"/>
+        </xs:extension>
+      </xs:complexContent>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="union" id="union">
+   <xs:complexType>
+    <xs:annotation>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#element-union">
+          memberTypes attribute must be non-empty or there must be
+          at least one simpleType child
+        </xs:documentation>
+      </xs:annotation>
+      <xs:complexContent>
+        <xs:extension base="xs:annotated">
+          <xs:sequence>
+            <xs:element name="simpleType" type="xs:localSimpleType" minOccurs="0" maxOccurs="unbounded"/>
+          </xs:sequence>
+          <xs:attribute name="memberTypes" use="optional">
+            <xs:simpleType>
+              <xs:list itemType="xs:QName"/>
+            </xs:simpleType>
+          </xs:attribute>
+        </xs:extension>
+      </xs:complexContent>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:complexType name="facet">
+    <xs:complexContent>
+      <xs:extension base="xs:annotated">
+        <xs:attribute name="value" use="required"/>
+        <xs:attribute name="fixed" type="xs:boolean" use="optional" default="false"/>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+
+ <xs:complexType name="noFixedFacet">
+  <xs:complexContent>
+   <xs:restriction base="xs:facet">
+    <xs:sequence>
+     <xs:element ref="xs:annotation" minOccurs="0"/>
+    </xs:sequence>
+    <xs:attribute name="fixed" use="prohibited"/>
+    <xs:anyAttribute namespace="##other" processContents="lax"/>
+   </xs:restriction>
+  </xs:complexContent>
+ </xs:complexType>
+
+  <xs:element name="minExclusive" id="minExclusive" type="xs:facet">
+    <xs:annotation>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#element-minExclusive"/>
+    </xs:annotation>
+  </xs:element>
+  <xs:element name="minInclusive" id="minInclusive" type="xs:facet">
+    <xs:annotation>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#element-minInclusive"/>
+    </xs:annotation>
+  </xs:element>
+
+  <xs:element name="maxExclusive" id="maxExclusive" type="xs:facet">
+    <xs:annotation>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#element-maxExclusive"/>
+    </xs:annotation>
+  </xs:element>
+  <xs:element name="maxInclusive" id="maxInclusive" type="xs:facet">
+    <xs:annotation>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#element-maxInclusive"/>
+    </xs:annotation>
+  </xs:element>
+
+  <xs:complexType name="numFacet">
+    <xs:complexContent>
+      <xs:restriction base="xs:facet">
+       <xs:sequence>
+         <xs:element ref="xs:annotation" minOccurs="0"/>
+       </xs:sequence>
+       <xs:attribute name="value" type="xs:nonNegativeInteger" use="required"/>
+       <xs:anyAttribute namespace="##other" processContents="lax"/>
+      </xs:restriction>
+    </xs:complexContent>
+  </xs:complexType>
+
+  <xs:element name="totalDigits" id="totalDigits">
+    <xs:annotation>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#element-totalDigits"/>
+    </xs:annotation>
+    <xs:complexType>
+      <xs:complexContent>
+        <xs:restriction base="xs:numFacet">
+          <xs:sequence>
+            <xs:element ref="xs:annotation" minOccurs="0"/>
+          </xs:sequence>
+          <xs:attribute name="value" type="xs:positiveInteger" use="required"/>
+         <xs:anyAttribute namespace="##other" processContents="lax"/>
+        </xs:restriction>
+      </xs:complexContent>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="fractionDigits" id="fractionDigits" type="xs:numFacet">
+    <xs:annotation>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#element-fractionDigits"/>
+    </xs:annotation>
+  </xs:element>
+
+  <xs:element name="length" id="length" type="xs:numFacet">
+    <xs:annotation>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#element-length"/>
+    </xs:annotation>
+  </xs:element>
+  <xs:element name="minLength" id="minLength" type="xs:numFacet">
+    <xs:annotation>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#element-minLength"/>
+    </xs:annotation>
+  </xs:element>
+  <xs:element name="maxLength" id="maxLength" type="xs:numFacet">
+    <xs:annotation>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#element-maxLength"/>
+    </xs:annotation>
+  </xs:element>
+
+  <xs:element name="enumeration" id="enumeration" type="xs:noFixedFacet">
+    <xs:annotation>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#element-enumeration"/>
+    </xs:annotation>
+  </xs:element>
+
+  <xs:element name="whiteSpace" id="whiteSpace">
+    <xs:annotation>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#element-whiteSpace"/>
+    </xs:annotation>
+    <xs:complexType>
+      <xs:complexContent>
+        <xs:restriction base="xs:facet">
+          <xs:sequence>
+            <xs:element ref="xs:annotation" minOccurs="0"/>
+          </xs:sequence>
+          <xs:attribute name="value" use="required">
+            <xs:simpleType>
+              <xs:restriction base="xs:NMTOKEN">
+                <xs:enumeration value="preserve"/>
+                <xs:enumeration value="replace"/>
+                <xs:enumeration value="collapse"/>
+              </xs:restriction>
+            </xs:simpleType>
+          </xs:attribute>
+         <xs:anyAttribute namespace="##other" processContents="lax"/>
+        </xs:restriction>
+      </xs:complexContent>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="pattern" id="pattern">
+    <xs:annotation>
+      <xs:documentation source="http://www.w3.org/TR/xmlschema-2/#element-pattern"/>
+    </xs:annotation>
+    <xs:complexType>
+      <xs:complexContent>
+        <xs:restriction base="xs:noFixedFacet">
+          <xs:sequence>
+            <xs:element ref="xs:annotation" minOccurs="0"/>
+          </xs:sequence>
+          <xs:attribute name="value" type="xs:string" use="required"/>
+         <xs:anyAttribute namespace="##other" processContents="lax"/>
+        </xs:restriction>
+      </xs:complexContent>
+    </xs:complexType>
+  </xs:element>
+</xs:schema>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/confml_xsd/confml.xsd	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,273 @@
+<?xml version="1.0" encoding="utf-8"?>
+	<!--
+		Scheme according to 0.83 2.6.2008 Draft s60configurationml.doc 11.08.
+		2008 initial version hajduivo 2008-08-14 hajduivo update: xlink
+		added,but generated xml files contains wrong prefix at xlink
+		attributes 2008-08-15 hajduivo update: XInclude added
+	-->
+	<!--
+		DOCTYPE schema [ <!ENTITY ncname "[^:\I][^:\C]*"> <!ENTITY qname
+		"(&ncname;:)?&ncname;"> <!ENTITY aname "@&qname;"> <!ENTITY pos_t
+		"\[\d+\]"> <!ENTITY attr_t "\[&aname;=('|&quot;)(.)*('|&quot;)\]">
+		<!ENTITY name_t "\[(&qname;|\.)=('|&quot;)(.)*('|&quot;)\]"> <!ENTITY
+		cond "(&attr_t;|&name_t;)?(&pos_t;)?| (&pos_t;)?(&attr_t;|&name_t;)?">
+		<!ENTITY step "(&qname;|\*)(&cond;)?"> <!ENTITY pi
+		"processing-instruction\ ((('|&quot;)&qname;('|&quot;))?\)"> <!ENTITY
+		id "id\((('|&quot;)&ncname;('|&quot;))?\)"> <!ENTITY comm
+		"comment\(\)"> <!ENTITY text "text\(\)"> <!ENTITY nspace
+		"namespace::&ncname;"> <!ENTITY last
+		"&step;|&aname;|&nspace;|(&comm;(&pos_t;)?)|&text;(&pos_t;)?|&pi;(&pos_t;)?">
+		] <xs:import id="xi" namespace="http://www.w3.org/2001/xinclude"
+		schemaLocation="XInclude.xsd"/>
+	-->
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+	xmlns:tns="http://www.s60.com/xml/confml/1" xmlns:xlink="http://www.w3.org/1999/xlink"
+	xmlns:xi="http://www.w3.org/2001/XInclude" targetNamespace="http://www.s60.com/xml/confml/1"
+	elementFormDefault="qualified" attributeFormDefault="unqualified">
+	<xs:import id="xlink" namespace="http://www.w3.org/1999/xlink"
+		schemaLocation="xlink.xsd" />
+	<xs:import id="xs" namespace="http://www.w3.org/2001/XMLSchema"
+		schemaLocation="XMLSchema.xsd" />
+	<xs:import namespace="http://www.w3.org/2001/XInclude"
+		schemaLocation="XInclude.xsd" />
+	<xs:import namespace="http://www.s60.com/xml/confml/2"
+		schemaLocation="confml2.xsd" />
+		
+	<!-- Fixed Elements -->
+	<xs:element name="configuration" type="tns:configurationType" />
+	<xs:element name="meta" type="tns:metaType" />
+	<xs:element name="desc" type="tns:descType" />
+	<xs:element name="icon" type="tns:iconType" />
+	<xs:element name="view" type="tns:viewType" />
+	<xs:element name="group" type="tns:groupType" />
+	<xs:element name="feature" type="tns:featureType" />
+	<xs:element name="setting" type="tns:settingType" />
+	<xs:element name="data" type="tns:dataType" />
+	<xs:element name="rfs" type="tns:rfsType" />
+	<xs:element name="link" type="tns:linkType" />
+	<xs:element name="option" type="tns:optionType" />
+	<xs:element name="property" type="tns:propertyType" />
+	<xs:complexType name="configurationType">
+		<xs:choice minOccurs="0" maxOccurs="unbounded">
+			<xs:element ref="tns:meta" />
+			<xs:element ref="tns:desc" />
+			<xs:element ref="tns:icon" />
+			<xs:element ref="tns:view" />
+			<xs:element ref="tns:feature" />
+			<xs:element ref="tns:link" />
+			<xs:element ref="tns:data" />
+			<xs:element ref="tns:rfs" />
+			<xs:element ref="tns:configuration" />
+			<xs:element ref="xi:include"/>
+		</xs:choice>
+		<xs:attribute name="version" type="xs:NMTOKEN" />
+		<xs:attribute name="name" type="xs:string" />
+		<xs:attributeGroup ref="tns:CommonAttrs"></xs:attributeGroup>
+	</xs:complexType>
+	<xs:complexType name="metaType">
+		<xs:all>
+			<xs:element name="id" type="tns:idType" minOccurs="0" />
+			<xs:element name="date" type="tns:dateType" maxOccurs="1"
+				minOccurs="0" />
+			<xs:element name="owner" type="tns:ownerType" maxOccurs="1"
+				minOccurs="0" />
+			<xs:element name="editor" type="tns:editorType" maxOccurs="1"
+				minOccurs="0" />
+			<xs:element name="product" type="tns:productType"
+				maxOccurs="1" minOccurs="0" />
+			<xs:element name="status" type="tns:statusType" maxOccurs="1"
+				minOccurs="0" />
+			<xs:element name="platform" type="tns:platformType"
+				maxOccurs="1" minOccurs="0" />
+			<xs:element name="version" minOccurs="0" type="tns:versionType" />
+			<xs:element name="release" minOccurs="0" type="tns:releaseType" />
+			<xs:element name="customer" minOccurs="0" type="tns:customerType" />
+			<xs:element name="desc" minOccurs="0" type="tns:descType" />
+			<xs:element name="icon" minOccurs="0" type="tns:iconType" />
+			<xs:element ref="tns:link" maxOccurs="1" minOccurs="0"></xs:element>
+		</xs:all>
+	</xs:complexType>
+	<xs:complexType name="descType" mixed="true">
+		<xs:attribute ref="xlink:href" />
+		<xs:attribute ref="xlink:title" />
+		<xs:attributeGroup ref="tns:CommonAttrs"></xs:attributeGroup>
+	</xs:complexType>
+	<xs:complexType name="iconType">
+		<xs:attribute ref="xlink:href" use="optional" />
+		<xs:attribute ref="xlink:title" />
+		<xs:attributeGroup ref="tns:CommonAttrs"></xs:attributeGroup>
+	</xs:complexType>
+	<xs:complexType name="linkType">
+		<xs:attribute ref="xlink:href" use="optional" />
+		<xs:attribute ref="xlink:title" />
+		<xs:attributeGroup ref="tns:CommonAttrs"></xs:attributeGroup>
+	</xs:complexType>
+	<xs:complexType name="propertyType">
+		<xs:choice minOccurs="0" maxOccurs="unbounded">
+			<xs:element ref="tns:desc" />
+			<xs:element ref="tns:icon" />
+			<xs:element ref="tns:link" />
+		</xs:choice>
+		<xs:attributeGroup ref="tns:CommonAttrs"></xs:attributeGroup>
+		<xs:attribute name="name" type="xs:NMTOKEN" use="optional"></xs:attribute>
+		<xs:attribute name="value" type="xs:string"></xs:attribute>
+		<xs:attribute name="unit" type="xs:token"></xs:attribute>
+	</xs:complexType>
+	<xs:complexType name="settingType">
+		<xs:choice minOccurs="0" maxOccurs="unbounded">
+			<xs:element ref="tns:desc" />
+			<xs:element ref="tns:icon" />
+			<xs:element ref="tns:link" />
+			<xs:element ref="tns:option" />
+			<xs:element ref="tns:property" />
+			<xs:element ref="tns:setting" />
+			<xs:element ref="xs:minInclusive"></xs:element>
+			<xs:element ref="xs:maxInclusive"></xs:element>
+			<xs:element ref="xs:minExclusive"></xs:element>
+			<xs:element ref="xs:maxExclusive"></xs:element>
+			<xs:element ref="xs:pattern"></xs:element>
+			<xs:element ref="xs:length"></xs:element>
+			<xs:element ref="xs:minLength"></xs:element>
+			<xs:element ref="xs:maxLength"></xs:element>
+			<xs:element ref="xs:totalDigits"></xs:element>
+		</xs:choice>
+		<xs:attributeGroup ref="tns:CommonAttrs"></xs:attributeGroup>
+		<xs:attribute name="relevant" type="xs:token" default="true"></xs:attribute>
+		<xs:attribute name="constraint" type="xs:token" default="true">
+		</xs:attribute>
+		<xs:attribute name="readOnly" type="xs:NMTOKEN" default="true">
+		</xs:attribute>
+		<xs:attribute name="name" type="xs:string"></xs:attribute>
+		<xs:attribute name="type" type="tns:typeType" use="optional"></xs:attribute>
+		<xs:attribute name="ref" type="xs:string" use="optional"></xs:attribute>
+		<!--
+			TODO inconsistent defaults: for generic settings this does not have a
+			sense
+		-->
+		<xs:attribute name="minOccurs" type="xs:nonNegativeInteger"
+			default="0"></xs:attribute>
+		<xs:attribute name="maxOccurs" type="xs:allNNI" default="unbounded"></xs:attribute>
+		<xs:attribute name="mapKey" type="xs:string"></xs:attribute>
+		<xs:attribute name="mapValue" type="xs:string"></xs:attribute>
+		<xs:attribute name="required" type="xs:boolean" default="false"></xs:attribute>
+	</xs:complexType>
+	<xs:complexType name="featureType">
+		<xs:choice minOccurs="0" maxOccurs="unbounded">
+			<xs:element ref="tns:desc" />
+			<xs:element ref="tns:icon" />
+			<xs:element ref="tns:link" />
+			<xs:element ref="tns:setting"></xs:element>
+		</xs:choice>
+		<xs:attribute name="name" type="xs:string" />
+		<xs:attribute name="relevant" type="xs:string"></xs:attribute>
+		<xs:attribute name="ref" type="xs:NMTOKEN" use="required" />
+		<xs:attributeGroup ref="tns:CommonAttrs"></xs:attributeGroup>
+	</xs:complexType>
+	<xs:complexType name="optionType">
+		<xs:choice minOccurs="0" maxOccurs="unbounded">
+			<xs:element ref="tns:desc" />
+			<xs:element ref="tns:icon" />
+			<xs:element ref="tns:link" />
+		</xs:choice>
+		<xs:attributeGroup ref="tns:CommonAttrs"></xs:attributeGroup>
+		<xs:attribute name="name" type="xs:token" use="optional"></xs:attribute>
+		<xs:attribute name="value" type="xs:string" use="optional"></xs:attribute>
+		<xs:attribute name="relevant" type="xs:token" default="true"></xs:attribute>
+		<xs:attribute name="map" type="xs:string"></xs:attribute>
+	</xs:complexType>
+	<xs:complexType name="groupType">
+		<xs:choice minOccurs="0" maxOccurs="unbounded">
+			<xs:element ref="tns:desc" />
+			<xs:element ref="tns:icon" />
+			<xs:element ref="tns:link" />
+			<xs:element ref="tns:group" />
+			<xs:element ref="tns:setting" />
+		</xs:choice>
+		<xs:attributeGroup ref="tns:CommonAttrs"></xs:attributeGroup>
+		<xs:attribute name="name" type="xs:string" use="required"></xs:attribute>
+	</xs:complexType>
+	<xs:complexType name="viewType">
+		<xs:choice minOccurs="0" maxOccurs="unbounded">
+			<xs:element ref="tns:meta" />
+			<xs:element ref="tns:desc" />
+			<xs:element ref="tns:icon" />
+			<xs:element ref="tns:link" />
+			<xs:element ref="tns:group"></xs:element>
+		</xs:choice>
+		<xs:attributeGroup ref="tns:CommonAttrs"></xs:attributeGroup>
+		<xs:attribute name="name" type="xs:token" use="optional"></xs:attribute>
+	</xs:complexType>
+	<xs:simpleType name="idType">
+		<xs:restriction base="xs:NMTOKEN"></xs:restriction>
+	</xs:simpleType>
+	<xs:simpleType name="dateType">
+		<xs:restriction base="xs:date"></xs:restriction>
+	</xs:simpleType>
+	<xs:simpleType name="ownerType">
+		<xs:restriction base="xs:string"></xs:restriction>
+	</xs:simpleType>
+	<xs:simpleType name="editorType">
+		<xs:restriction base="xs:string"></xs:restriction>
+	</xs:simpleType>
+	<xs:simpleType name="productType">
+		<xs:restriction base="xs:string"></xs:restriction>
+	</xs:simpleType>
+	<xs:simpleType name="statusType">
+		<xs:restriction base="xs:string"></xs:restriction>
+	</xs:simpleType>
+	<xs:simpleType name="platformType">
+		<xs:restriction base="xs:string"></xs:restriction>
+	</xs:simpleType>
+	<xs:simpleType name="versionType">
+		<xs:restriction base="xs:string"></xs:restriction>
+	</xs:simpleType>
+	<xs:simpleType name="releaseType">
+		<xs:restriction base="xs:string"></xs:restriction>
+	</xs:simpleType>
+	<xs:simpleType name="customerType">
+		<xs:restriction base="xs:string"></xs:restriction>
+	</xs:simpleType>
+<!-- <xs:attribute name="id" type="xs:NMTOKEN" />-->
+	<!--
+		<xs:attribute name="href" type="xs:anyURI" /> <xs:attribute
+		name="title" type="xs:string" />
+	-->
+	<xs:attributeGroup name="CommonAttrs">
+		<xs:attribute name="id" type="xs:ID"></xs:attribute>
+	</xs:attributeGroup>
+	<xs:complexType name="dataType">
+		<xs:sequence>
+			<xs:any namespace="##any" processContents="skip" minOccurs="0"
+				maxOccurs="unbounded"></xs:any>
+		</xs:sequence>
+		<xs:attributeGroup ref="tns:CommonAttrs"></xs:attributeGroup>
+		<xs:attribute name="extensionPolicy" type="xs:NMTOKEN"
+			default="replace">
+		</xs:attribute>
+		<xs:attribute name="template" type="xs:NMTOKEN" default="false"></xs:attribute>
+	</xs:complexType>
+	<xs:complexType name="rfsType">
+		<xs:sequence>
+			<xs:any namespace="##any" processContents="skip" minOccurs="0"
+				maxOccurs="unbounded"></xs:any>
+		</xs:sequence>
+		<xs:attributeGroup ref="tns:CommonAttrs"></xs:attributeGroup>
+	</xs:complexType>
+	<xs:simpleType name="typeType">
+		<xs:restriction base="xs:string">
+			<xs:enumeration id="int" value="int"></xs:enumeration>
+			<xs:enumeration value="boolean"></xs:enumeration>
+			<xs:enumeration value="real"></xs:enumeration>
+			<xs:enumeration value="string"></xs:enumeration>
+			<xs:enumeration value="file"></xs:enumeration>
+			<xs:enumeration value="folder"></xs:enumeration>
+			<xs:enumeration value="sequence"></xs:enumeration>
+			<xs:enumeration value="selection"></xs:enumeration>
+			<xs:enumeration value="multiSelection"></xs:enumeration>
+			<xs:enumeration value="date"></xs:enumeration>
+			<xs:enumeration value="time"></xs:enumeration>
+			<xs:enumeration value="dateTime"></xs:enumeration>
+			<xs:enumeration value="duration"></xs:enumeration>
+		</xs:restriction>
+	</xs:simpleType>
+</xs:schema>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/confml_xsd/confml2.xsd	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,272 @@
+<?xml version="1.0" encoding="utf-8"?>
+	<!--
+		Scheme according to 0.84 2.6.2008 Draft s60configurationml.doc 11.08.
+		2008 initial version hajduivo 2008-08-14 hajduivo update: xlink
+		added,but generated xml files contains wrong prefix at xlink
+		attributes 2008-08-15 hajduivo update: XInclude added
+	-->
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+	xmlns:tns="http://www.s60.com/xml/confml/2" xmlns:xlink="http://www.w3.org/1999/xlink"
+	xmlns:xi="http://www.w3.org/2001/XInclude" targetNamespace="http://www.s60.com/xml/confml/2"
+	elementFormDefault="qualified" attributeFormDefault="unqualified">
+	<xs:import id="xlink" namespace="http://www.w3.org/1999/xlink"
+		schemaLocation="xlink.xsd" />
+	<xs:import id="xs" namespace="http://www.w3.org/2001/XMLSchema"
+		schemaLocation="XMLSchema.xsd" />
+	<xs:import namespace="http://www.w3.org/2001/XInclude"
+		schemaLocation="XInclude.xsd" />
+		
+	<!-- Fixed Elements -->
+	<xs:element name="configuration" type="tns:configurationType" />
+	<xs:element name="meta" type="tns:metaType" />
+	<xs:element name="desc" type="tns:descType" />
+	<xs:element name="icon" type="tns:iconType" />
+	<xs:element name="view" type="tns:viewType" />
+	<xs:element name="group" type="tns:groupType" />
+	<xs:element name="feature" type="tns:featureType" />
+	<xs:element name="setting" type="tns:settingType" />
+	<xs:element name="data" type="tns:dataType" />
+	<xs:element name="rfs" type="tns:rfsType" />
+	<xs:element name="link" type="tns:linkType" />
+	<xs:element name="option" type="tns:optionType" />
+	<xs:element name="property" type="tns:propertyType" />
+	<xs:element name="localPath" type="tns:localTargetPathType"/>
+	<xs:element name="targetPath" type="tns:localTargetPathType"/>
+	<xs:complexType name="configurationType">
+		<xs:choice minOccurs="0" maxOccurs="unbounded">
+			<xs:element ref="tns:meta" />
+			<xs:element ref="tns:desc" />
+			<xs:element ref="tns:icon" />
+			<xs:element ref="tns:view" />
+			<xs:element ref="tns:feature" />
+			<xs:element ref="tns:link" />
+			<xs:element ref="tns:data" />
+			<xs:element ref="tns:rfs" />
+			<xs:element	ref="tns:configuration" />
+			<xs:element ref="xi:include"/>
+		</xs:choice>
+		<xs:attribute name="version" type="xs:NMTOKEN" />
+		<xs:attribute name="name" type="xs:string" />
+		<xs:attributeGroup ref="tns:CommonAttrs"></xs:attributeGroup>
+	</xs:complexType>
+	<xs:complexType name="metaType">
+		<xs:all>
+			<xs:element name="id" type="tns:idType" minOccurs="0" />
+			<xs:element name="date" type="tns:dateType" maxOccurs="1"
+				minOccurs="0" />
+			<xs:element name="owner" type="tns:ownerType" maxOccurs="1"
+				minOccurs="0" />
+			<xs:element name="editor" type="tns:editorType" maxOccurs="1"
+				minOccurs="0" />
+			<xs:element name="status" type="tns:statusType" maxOccurs="1"
+				minOccurs="0" />
+			<xs:element name="version" minOccurs="0" type="tns:versionType" />
+			<xs:element name="platform" type="tns:platformType"
+				maxOccurs="1" minOccurs="0" />
+			<xs:element name="product" type="tns:productType"
+				maxOccurs="1" minOccurs="0" />
+			<xs:element name="release" minOccurs="0" type="tns:releaseType" />
+			<xs:element name="customer" minOccurs="0" type="tns:customerType" />
+			<xs:element name="origin" minOccurs="0" type="tns:customerType" />
+			<xs:element name="target" minOccurs="0" type="tns:customerType" />
+			<xs:element name="desc" minOccurs="0" type="tns:descType" />
+			<xs:element name="icon" minOccurs="0" type="tns:iconType" />
+			<xs:element ref="tns:link" maxOccurs="1" minOccurs="0"></xs:element>
+		</xs:all>
+	</xs:complexType>
+	<xs:complexType name="descType" mixed="true">
+		<xs:attribute ref="xlink:href" />
+		<xs:attribute ref="xlink:title" />
+		<xs:attributeGroup ref="tns:CommonAttrs"></xs:attributeGroup>
+	</xs:complexType>
+	<xs:complexType name="iconType">
+		<xs:attribute ref="xlink:href" use="optional" />
+		<xs:attribute ref="xlink:title" />
+		<xs:attributeGroup ref="tns:CommonAttrs"></xs:attributeGroup>
+	</xs:complexType>
+	<xs:complexType name="linkType">
+		<xs:attribute ref="xlink:href" use="optional" />
+		<xs:attribute ref="xlink:title" />
+		<xs:attributeGroup ref="tns:CommonAttrs"></xs:attributeGroup>
+	</xs:complexType>
+	<xs:complexType name="propertyType">
+		<xs:choice minOccurs="0" maxOccurs="unbounded">
+			<xs:element ref="tns:desc" />
+			<xs:element ref="tns:icon" />
+			<xs:element ref="tns:link" />
+		</xs:choice>
+		<xs:attributeGroup ref="tns:CommonAttrs"></xs:attributeGroup>
+		<xs:attribute name="name" type="xs:NMTOKEN" use="optional"></xs:attribute>
+		<xs:attribute name="value" type="xs:string"></xs:attribute>
+		<xs:attribute name="unit" type="xs:token"></xs:attribute>
+	</xs:complexType>
+	<xs:complexType name="settingType">
+		<xs:choice minOccurs="0" maxOccurs="unbounded">
+			<xs:element ref="tns:desc" />
+			<xs:element ref="tns:icon" />
+			<xs:element ref="tns:link" />
+			<xs:element ref="tns:option" />
+			<xs:element ref="tns:property" />
+			<xs:element ref="tns:setting" />
+			<xs:element ref="tns:localPath" />
+			<xs:element ref="tns:targetPath" />
+			<xs:element ref="xs:minInclusive"></xs:element>
+			<xs:element ref="xs:maxInclusive"></xs:element>
+			<xs:element ref="xs:minExclusive"></xs:element>
+			<xs:element ref="xs:maxExclusive"></xs:element>
+			<xs:element ref="xs:pattern"></xs:element>
+			<xs:element ref="xs:length"></xs:element>
+			<xs:element ref="xs:minLength"></xs:element>
+			<xs:element ref="xs:maxLength"></xs:element>
+			<xs:element ref="xs:totalDigits"></xs:element>
+		</xs:choice>
+		<xs:attributeGroup ref="tns:CommonAttrs"></xs:attributeGroup>
+		<xs:attribute name="relevant" type="xs:token" default="true"/>
+		<xs:attribute name="constraint" type="xs:token" default="true"/>
+		<xs:attribute name="readOnly" type="xs:NMTOKEN" default="true"/>
+		<xs:attribute name="name" type="xs:string"></xs:attribute>
+		<xs:attribute name="type" type="tns:typeType" use="optional"></xs:attribute>
+		<xs:attribute name="ref" type="xs:string" use="optional"></xs:attribute>
+		<!--
+			TODO inconsistent defaults: for generic settings this does not have a
+			sense
+		-->
+		<xs:attribute name="minOccurs" type="xs:nonNegativeInteger"
+			default="0"></xs:attribute>
+		<xs:attribute name="maxOccurs" type="xs:allNNI" default="unbounded"></xs:attribute>
+		<xs:attribute name="mapKey" type="xs:string"></xs:attribute>
+		<xs:attribute name="mapValue" type="xs:string"></xs:attribute>
+		<xs:attribute name="required" type="xs:boolean" default="false"></xs:attribute>
+	</xs:complexType>
+	<xs:complexType name="featureType">
+		<xs:choice minOccurs="0" maxOccurs="unbounded">
+			<xs:element ref="tns:desc" />
+			<xs:element ref="tns:icon" />
+			<xs:element ref="tns:link" />
+			<xs:element ref="tns:setting"></xs:element>
+		</xs:choice>
+		<xs:attribute name="name" type="xs:string" />
+		<xs:attribute name="relevant" type="xs:string"></xs:attribute>
+		<xs:attribute name="ref" type="xs:NMTOKEN" use="required" />
+		<xs:attributeGroup ref="tns:CommonAttrs"></xs:attributeGroup>
+	</xs:complexType>
+	<xs:complexType name="optionType">
+		<xs:choice minOccurs="0" maxOccurs="unbounded">
+			<xs:element ref="tns:desc" />
+			<xs:element ref="tns:icon" />
+			<xs:element ref="tns:link" />
+		</xs:choice>
+		<xs:attributeGroup ref="tns:CommonAttrs"></xs:attributeGroup>
+		<xs:attribute name="name" type="xs:token" use="optional"></xs:attribute>
+		<xs:attribute name="value" type="xs:string" use="optional"></xs:attribute>
+		<xs:attribute name="relevant" type="xs:token" default="true"></xs:attribute>
+		<xs:attribute name="map" type="xs:string"></xs:attribute>
+	</xs:complexType>
+	<xs:complexType name="groupType">
+		<xs:choice minOccurs="0" maxOccurs="unbounded">
+			<xs:element ref="tns:desc" />
+			<xs:element ref="tns:icon" />
+			<xs:element ref="tns:link" />
+			<xs:element ref="tns:group" />
+			<xs:element ref="tns:setting" />
+		</xs:choice>
+		<xs:attributeGroup ref="tns:CommonAttrs"></xs:attributeGroup>
+		<xs:attribute name="name" type="xs:string" use="required"></xs:attribute>
+	</xs:complexType>
+	<xs:complexType name="viewType">
+		<xs:choice minOccurs="0" maxOccurs="unbounded">
+			<xs:element ref="tns:meta" />
+			<xs:element ref="tns:desc" />
+			<xs:element ref="tns:icon" />
+			<xs:element ref="tns:link" />
+			<xs:element ref="tns:group"></xs:element>
+		</xs:choice>
+		<xs:attributeGroup ref="tns:CommonAttrs"></xs:attributeGroup>
+		<xs:attribute name="name" type="xs:token" use="optional"></xs:attribute>
+	</xs:complexType>
+	<xs:complexType name="localTargetPathType">
+		<xs:choice minOccurs="0" maxOccurs="unbounded">
+			<xs:element ref="tns:desc" />
+			<xs:element ref="tns:icon" />
+			<xs:element ref="tns:link" />
+		</xs:choice>
+		<xs:attributeGroup ref="tns:CommonAttrs"></xs:attributeGroup>
+		<xs:attribute name="constraint" type="xs:token"/>
+		<xs:attribute name="readOnly" type="xs:NMTOKEN"/>
+		<xs:attribute name="required" type="xs:NMTOKEN"/>
+		<xs:attribute name="map" type="xs:string"></xs:attribute>
+	</xs:complexType>
+	<xs:simpleType name="idType">
+		<xs:restriction base="xs:NMTOKEN"></xs:restriction>
+	</xs:simpleType>
+	<xs:simpleType name="dateType">
+		<xs:restriction base="xs:date"></xs:restriction>
+	</xs:simpleType>
+	<xs:simpleType name="ownerType">
+		<xs:restriction base="xs:string"></xs:restriction>
+	</xs:simpleType>
+	<xs:simpleType name="editorType">
+		<xs:restriction base="xs:string"></xs:restriction>
+	</xs:simpleType>
+	<xs:simpleType name="productType">
+		<xs:restriction base="xs:string"></xs:restriction>
+	</xs:simpleType>
+	<xs:simpleType name="statusType">
+		<xs:restriction base="xs:string"></xs:restriction>
+	</xs:simpleType>
+	<xs:simpleType name="platformType">
+		<xs:restriction base="xs:string"></xs:restriction>
+	</xs:simpleType>
+	<xs:simpleType name="versionType">
+		<xs:restriction base="xs:string"></xs:restriction>
+	</xs:simpleType>
+	<xs:simpleType name="releaseType">
+		<xs:restriction base="xs:string"></xs:restriction>
+	</xs:simpleType>
+	<xs:simpleType name="customerType">
+		<xs:restriction base="xs:string"></xs:restriction>
+	</xs:simpleType>
+<!-- <xs:attribute name="id" type="xs:NMTOKEN" />-->
+	<!--
+		<xs:attribute name="href" type="xs:anyURI" /> <xs:attribute
+		name="title" type="xs:string" />
+	-->
+	<xs:attributeGroup name="CommonAttrs">
+		<xs:attribute name="id" type="xs:ID"></xs:attribute>
+	</xs:attributeGroup>
+	<xs:complexType name="dataType">
+		<xs:sequence>
+			<xs:any namespace="##any" processContents="skip" minOccurs="0"
+				maxOccurs="unbounded"></xs:any>
+		</xs:sequence>
+		<xs:attributeGroup ref="tns:CommonAttrs"></xs:attributeGroup>
+		<xs:attribute name="extensionPolicy" type="xs:NMTOKEN"
+			default="replace">
+		</xs:attribute>
+		<xs:attribute name="template" type="xs:NMTOKEN" default="false"></xs:attribute>
+	</xs:complexType>
+	<xs:complexType name="rfsType">
+		<xs:sequence>
+			<xs:any namespace="##any" processContents="skip" minOccurs="0"
+				maxOccurs="unbounded"></xs:any>
+		</xs:sequence>
+		<xs:attributeGroup ref="tns:CommonAttrs"></xs:attributeGroup>
+	</xs:complexType>
+	<xs:simpleType name="typeType">
+		<xs:restriction base="xs:string">
+			<xs:enumeration id="int" value="int"></xs:enumeration>
+			<xs:enumeration value="boolean"></xs:enumeration>
+			<xs:enumeration value="real"></xs:enumeration>
+			<xs:enumeration value="string"></xs:enumeration>
+			<xs:enumeration value="file"></xs:enumeration>
+			<xs:enumeration value="folder"></xs:enumeration>
+			<xs:enumeration value="sequence"></xs:enumeration>
+			<xs:enumeration value="selection"></xs:enumeration>
+			<xs:enumeration value="multiSelection"></xs:enumeration>
+			<xs:enumeration value="date"></xs:enumeration>
+			<xs:enumeration value="time"></xs:enumeration>
+			<xs:enumeration value="dateTime"></xs:enumeration>
+			<xs:enumeration value="duration"></xs:enumeration>
+		</xs:restriction>
+	</xs:simpleType>
+</xs:schema>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/confml_xsd/xlink.xsd	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- $Date: 2008/08/14 07:59:30 $ -->
+	<!--
+		Copyright (c) 2002 World Wide Web Consortium, (Massachusetts Institute
+		of Technology, Institut National de Recherche en Informatique et en
+		Automatique, Keio University). All Rights Reserved. This document is
+		distributed under the W3C's Software Intellectual Property License.
+		This document is distributed in the hope that it will be useful, but
+		WITHOUT ANY WARRANTY; without even the implied warranty of
+		MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See W3C License
+		http://www.w3.org/Consortium/Legal/ for more details.
+	-->
+<xs:schema targetNamespace="http://www.w3.org/1999/xlink"
+	xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
+	attributeFormDefault="unqualified" version="$Date: 2008/08/14 07:59:30 $">
+	<xs:annotation>
+		<xs:documentation source="http://www.w3.org/TR/2000/REC-xlink-20010627"
+			xml:lang="en"> Note this schema is NOT a normative schema - - It contains
+			attribute types derived from all the attribute definitions found in
+			the XLink Recommendation available at
+			http://www.w3.org/TR/2001/REC-xlink-20010627 Section 4.1
+			(http://www.w3.org/TR/2001/REC-xlink-20010627/#N1238) provides a
+			summary of the element types on which the global attributes are
+			allowed, with an indication of whether a value is required or
+			optional. </xs:documentation>
+	</xs:annotation>
+	<xs:attribute name="type">
+		<xs:annotation>
+			<xs:documentation
+				source="http://www.w3.org/TR/2000/REC-xlink-20010627/#link-types"
+				xml:lang="en"> The XLink Element Type Attribute. Note: xml:lang is not
+				required if the value of the type attribute is "title", but provides
+				much of the motivation for title elements in addition to attributes.
+				A W3C XML Schema definition of the xml:lang attribute can be found
+				at: http://www.w3.org/2001/xml.xsd </xs:documentation>
+		</xs:annotation>
+		<xs:simpleType>
+			<xs:restriction base="xs:string">
+				<xs:enumeration value="simple" />
+				<xs:enumeration value="extended" />
+				<xs:enumeration value="locator" />
+				<xs:enumeration value="arc" />
+				<xs:enumeration value="resource" />
+				<xs:enumeration value="title" />
+				<xs:enumeration value="none" />
+			</xs:restriction>
+		</xs:simpleType>
+	</xs:attribute>
+	<xs:attribute name="href" type="xs:anyURI">
+		<xs:annotation>
+			<xs:documentation
+				source="http://www.w3.org/TR/2000/REC-xlink-20010627/#link-locators"
+				xml:lang="en"> The Locator Attribute. </xs:documentation>
+		</xs:annotation>
+	</xs:attribute>
+	<xs:attribute name="arcrole" type="xs:anyURI">
+		<xs:annotation>
+			<xs:documentation
+				source="http://www.w3.org/TR/2001/REC-xlink-20010627/#link-semantics"
+				xml:lang="en"> The Arcrole Semantic Attribute. </xs:documentation>
+		</xs:annotation>
+	</xs:attribute>
+	<xs:attribute name="role" type="xs:anyURI">
+		<xs:annotation>
+			<xs:documentation
+				source="http://www.w3.org/TR/2001/REC-xlink-20010627/#link-semantics"
+				xml:lang="en"> The Role Semantic Attribute. </xs:documentation>
+		</xs:annotation>
+	</xs:attribute>
+	<xs:attribute name="title" type="xs:string">
+		<xs:annotation>
+			<xs:documentation
+				source="http://www.w3.org/TR/2001/REC-xlink-20010627/#link-semantics"
+				xml:lang="en"> The Title Semantic Attribute. </xs:documentation>
+		</xs:annotation>
+	</xs:attribute>
+	<xs:attribute name="show">
+		<xs:annotation>
+			<xs:documentation
+				source="http://www.w3.org/TR/2001/REC-xlink-20010627/#show-att"
+				xml:lang="en"> The Show Behavior Attribute. </xs:documentation>
+		</xs:annotation>
+		<xs:simpleType>
+			<xs:restriction base="xs:string">
+				<xs:enumeration value="new" />
+				<xs:enumeration value="replace" />
+				<xs:enumeration value="embed" />
+				<xs:enumeration value="other" />
+				<xs:enumeration value="none" />
+			</xs:restriction>
+		</xs:simpleType>
+	</xs:attribute>
+	<xs:attribute name="actuate">
+		<xs:annotation>
+			<xs:documentation
+				source="http://www.w3.org/TR/2001/REC-xlink-20010627/#actuate-att"
+				xml:lang="en"> The Actuate Behavior Attribute. </xs:documentation>
+		</xs:annotation>
+		<xs:simpleType>
+			<xs:restriction base="xs:string">
+				<xs:enumeration value="onLoad" />
+				<xs:enumeration value="onRequest" />
+				<xs:enumeration value="other" />
+				<xs:enumeration value="none" />
+			</xs:restriction>
+		</xs:simpleType>
+	</xs:attribute>
+	<xs:attribute name="label" type="xs:NCName">
+		<xs:annotation>
+			<xs:documentation
+				source="http://www.w3.org/TR/2001/REC-xlink-20010627/#traversal-atts"
+				xml:lang="en"> The Label Traversal Attribute. </xs:documentation>
+		</xs:annotation>
+	</xs:attribute>
+	<xs:attribute name="from" type="xs:NCName">
+		<xs:annotation>
+			<xs:documentation
+				source="http://www.w3.org/TR/2001/REC-xlink-20010627/#traversal-atts"
+				xml:lang="en"> The From Traversal Attribute. </xs:documentation>
+		</xs:annotation>
+	</xs:attribute>
+	<xs:attribute name="to" type="xs:NCName">
+		<xs:annotation>
+			<xs:documentation
+				source="http://www.w3.org/TR/2001/REC-xlink-20010627/#traversal-atts"
+				xml:lang="en"> The To Traversal Attribute. </xs:documentation>
+		</xs:annotation>
+	</xs:attribute>
+</xs:schema>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/confml_xsd/xml.xsd	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,145 @@
+<?xml version="1.0"?>
+<xs:schema targetNamespace="http://www.w3.org/XML/1998/namespace" xmlns:xs="http://www.w3.org/2001/XMLSchema" xml:lang="en">
+
+ <xs:annotation>
+  <xs:documentation>
+   See http://www.w3.org/XML/1998/namespace.html and
+   http://www.w3.org/TR/REC-xml for information about this namespace.
+
+    This schema document describes the XML namespace, in a form
+    suitable for import by other schema documents.  
+
+    Note that local names in this namespace are intended to be defined
+    only by the World Wide Web Consortium or its subgroups.  The
+    following names are currently defined in this namespace and should
+    not be used with conflicting semantics by any Working Group,
+    specification, or document instance:
+
+    base (as an attribute name): denotes an attribute whose value
+         provides a URI to be used as the base for interpreting any
+         relative URIs in the scope of the element on which it
+         appears; its value is inherited.  This name is reserved
+         by virtue of its definition in the XML Base specification.
+
+    id   (as an attribute name): denotes an attribute whose value
+         should be interpreted as if declared to be of type ID.
+         This name is reserved by virtue of its definition in the
+         xml:id specification.
+
+    lang (as an attribute name): denotes an attribute whose value
+         is a language code for the natural language of the content of
+         any element; its value is inherited.  This name is reserved
+         by virtue of its definition in the XML specification.
+  
+    space (as an attribute name): denotes an attribute whose
+         value is a keyword indicating what whitespace processing
+         discipline is intended for the content of the element; its
+         value is inherited.  This name is reserved by virtue of its
+         definition in the XML specification.
+
+    Father (in any context at all): denotes Jon Bosak, the chair of 
+         the original XML Working Group.  This name is reserved by 
+         the following decision of the W3C XML Plenary and 
+         XML Coordination groups:
+
+             In appreciation for his vision, leadership and dedication
+             the W3C XML Plenary on this 10th day of February, 2000
+             reserves for Jon Bosak in perpetuity the XML name
+             xml:Father
+  </xs:documentation>
+ </xs:annotation>
+
+ <xs:annotation>
+  <xs:documentation>This schema defines attributes and an attribute group
+        suitable for use by
+        schemas wishing to allow xml:base, xml:lang, xml:space or xml:id
+        attributes on elements they define.
+
+        To enable this, such a schema must import this schema
+        for the XML namespace, e.g. as follows:
+        &lt;schema . . .&gt;
+         . . .
+         &lt;import namespace="http://www.w3.org/XML/1998/namespace"
+                    schemaLocation="http://www.w3.org/2001/xml.xsd"/&gt;
+
+        Subsequently, qualified reference to any of the attributes
+        or the group defined below will have the desired effect, e.g.
+
+        &lt;type . . .&gt;
+         . . .
+         &lt;attributeGroup ref="xml:specialAttrs"/&gt;
+ 
+         will define a type which will schema-validate an instance
+         element with any of those attributes</xs:documentation>
+ </xs:annotation>
+
+ <xs:annotation>
+  <xs:documentation>In keeping with the XML Schema WG's standard versioning
+   policy, this schema document will persist at
+   http://www.w3.org/2007/08/xml.xsd.
+   At the date of issue it can also be found at
+   http://www.w3.org/2001/xml.xsd.
+   The schema document at that URI may however change in the future,
+   in order to remain compatible with the latest version of XML Schema
+   itself, or with the XML namespace itself.  In other words, if the XML
+   Schema or XML namespaces change, the version of this document at
+   http://www.w3.org/2001/xml.xsd will change
+   accordingly; the version at
+   http://www.w3.org/2007/08/xml.xsd will not change.
+  </xs:documentation>
+ </xs:annotation>
+
+ <xs:attribute name="lang">
+  <xs:annotation>
+   <xs:documentation>Attempting to install the relevant ISO 2- and 3-letter
+         codes as the enumerated possible values is probably never
+         going to be a realistic possibility.  See
+         RFC 3066 at http://www.ietf.org/rfc/rfc3066.txt and the IANA registry
+         at http://www.iana.org/assignments/lang-tag-apps.htm for
+         further information.
+
+         The union allows for the 'un-declaration' of xml:lang with
+         the empty string.</xs:documentation>
+  </xs:annotation>
+  <xs:simpleType>
+   <xs:union memberTypes="xs:language">
+    <xs:simpleType>    
+     <xs:restriction base="xs:string">
+      <xs:enumeration value=""/>
+     </xs:restriction>
+    </xs:simpleType>
+   </xs:union>
+  </xs:simpleType>
+ </xs:attribute>
+
+ <xs:attribute name="space">
+  <xs:simpleType>
+   <xs:restriction base="xs:NCName">
+    <xs:enumeration value="default"/>
+    <xs:enumeration value="preserve"/>
+   </xs:restriction>
+  </xs:simpleType>
+ </xs:attribute>
+
+ <xs:attribute name="base" type="xs:anyURI">
+  <xs:annotation>
+   <xs:documentation>See http://www.w3.org/TR/xmlbase/ for
+                     information about this attribute.</xs:documentation>
+  </xs:annotation>
+ </xs:attribute>
+ 
+ <xs:attribute name="id" type="xs:ID">
+  <xs:annotation>
+   <xs:documentation>See http://www.w3.org/TR/xml-id/ for
+                     information about this attribute.</xs:documentation>
+  </xs:annotation>
+ </xs:attribute>
+
+ <xs:attributeGroup name="specialAttrs">
+  <xs:attribute ref="xml:base"/>
+  <xs:attribute ref="xml:lang"/>
+  <xs:attribute ref="xml:space"/>
+  <xs:attribute ref="xml:id"/>
+ </xs:attributeGroup>
+
+</xs:schema>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/confmlvalidation.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,190 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+import logging
+
+import cone.validation.common
+
+class ValidationContext(object):
+    def __init__(self, configuration):
+        #: The configuration being validated
+        self.configuration = configuration
+        
+        self._dview = None
+        #: The list of validation problems
+        self.problems = []
+        #: The list of fixes executed in the context
+        self.fixes = []
+        
+
+    @property
+    def dview(self):
+        """ 
+        The configuration's default view 
+        """
+        if not self._dview:
+            self._dview = self.configuration.get_default_view()
+        return self._dview
+        
+    @property
+    def feature_dict(self):
+        """
+        All the configuration's features as a ref -> feature dictionary. 
+        """
+        if not hasattr(self, '_feature_dict'):
+            self._feature_dict = {}
+            for fea in self.dview.get_features('**'):
+                self._feature_dict[fea.fqr] = fea
+        return self._feature_dict
+
+class ValidatorBase(object):
+    #: Types of the problems this validator produces
+    PROBLEM_TYPES = None
+    
+    def __init__(self, context):
+        self.context = context
+    
+    def validate(self):
+        """
+        Method called to validate a configuration.
+        """
+        raise NotImplementedError()
+
+class FixerBase(object):
+    def fix(self, context):
+        """
+        The fix functions takes ValidationContext that is expected to contain a 
+        list of Problem objects that it will traverse through and it will try to 
+        fix any problem that matches its category.
+        @param context: The ValidationContext object from which problems should be fixed.  
+        """
+        raise NotImplementedError()
+
+    def filter_problems(self, problems, problem_type):
+        """
+        A filtering function that returns a list of problems that match to the 
+        given problem_type.
+        @param problems: a list of api.Problem objects
+        @param problem_type: a string that represents the problem name. e
+        .g. 'model.confml.duplicate.setting'.
+        """
+        return [problem for problem in problems if problem.type == problem_type]
+
+def get_validator_classes(problem_type_filter=None):
+    """
+    Return a list of all ConfML validator classes that match the given
+    problem type filter (i.e. all validator classes that yield problems
+    that will not be filtered out).
+    
+    @param problem_type_filter: The filter, if None, all validator
+        classes will be returned.
+    """
+    classes = []
+    
+    # Validators from plug-in entry points
+    classes.extend(cone.validation.common.load_plugin_classes(
+        'cone.plugins.confmlvalidators',
+        ValidatorBase))
+    
+    # Built-in validators
+    from cone.validation.builtinvalidators.confml import VALIDATOR_CLASSES
+    classes.extend(VALIDATOR_CLASSES)
+    
+    return cone.validation.common.filter_classes(classes, problem_type_filter)
+
+def get_fixer_classes(problem_type_filter=None):
+    """
+    Return a list of all ConfML fixer classes that match the given
+    problem type filter (i.e. all fixer classes that yield problems
+    that will not be filtered out).
+    
+    @param problem_type_filter: The filter, if None, all fixer
+        classes will be returned.
+    """
+    classes = []
+    
+    # Validators from plug-in entry points 
+    classes.extend(cone.validation.common.load_plugin_classes(
+        'cone.plugins.confmlfixers',
+        FixerBase))
+    
+    # Built-in validators 
+    from cone.validation.builtinvalidators.confml import FIXER_CLASSES
+    classes.extend(FIXER_CLASSES)
+    
+    return cone.validation.common.filter_classes(classes, problem_type_filter)
+
+def validate_configuration(configuration, validator_classes=None):
+    """
+    Validate the given configuration.
+    @param configuration: The configuration to validate.
+    @param validator_classes: The validator classes to use for the validation.
+        If None, all validator classes will be used.
+    @return: A ValidationContext objects, which contains a list of Problem objects in 
+    member variable problems.
+    """
+    
+    if validator_classes is None:
+        validator_classes = get_validator_classes()
+    
+    context = ValidationContext(configuration)
+    validators = [vc(context) for vc in validator_classes]
+    for validator in validators:
+        try:
+            validator.validate()
+        except Exception, e:
+            from cone.public import utils
+            utils.log_exception(logging.getLogger('cone'),
+                                "Error validating configuration: %s: %s" \
+                                % (e.__class__.__name__, e))
+    return context
+
+def fix_configuration(configuration, context=None, fixer_classes=None):
+    """
+    Validate the given configuration.
+    @param configuration: The configuration to validate.
+    @param context:  The ValidationContext if it has been alread created. With value None
+        The ValidationContext will be created and validated fisrt
+    @param fixer_classes: The fixer classes to use for the validation.
+        If None, all fixer classes will be used.
+    @return:  A ValidationContext objects, which contains a list of messaages of fixes that
+    were executed.
+    """
+    
+    try:
+        conf = configuration.get_configuration('duplicate_settings1.confml')
+        data1 = conf.data
+    except Exception:
+        pass
+    if context is None:
+        context = validate_configuration(configuration)
+    if fixer_classes is None:
+        fixer_classes = get_fixer_classes()
+
+    try:
+        conf = configuration.get_configuration('duplicate_settings1.confml')
+        data2 = conf.data
+    except Exception:
+        pass
+    for fixer in fixer_classes:
+        try:
+            fixer().fix(context)
+        except Exception, e:
+            from cone.public import utils
+            utils.log_exception(logging.getLogger('cone'),
+                                "Error fixing configuration: %s: %s" \
+                                % (e.__class__.__name__, e))
+    return context
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/implml_xsd/default-impl-schema-template.xsd	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- This is an automatically generated default XML schema file -->
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+           targetNamespace="{{entry.namespace}}"
+           elementFormDefault="qualified">
+    
+    <xs:element name="{{entry.root_elem_name}}">
+        <xs:complexType>
+            <xs:choice minOccurs="0" maxOccurs="unbounded">
+                <xs:any processContents="skip"/>
+            </xs:choice>
+            <xs:anyAttribute processContents="skip"/>
+        </xs:complexType>
+    </xs:element>
+</xs:schema>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/implml_xsd/implml-template.xsd	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,271 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+           targetNamespace="http://www.symbianfoundation.org/xml/implml/1"
+           xmlns:implml="http://www.symbianfoundation.org/xml/implml/1"
+           {% for entry in data -%}
+           xmlns:{{entry.id}}="{{entry.namespace}}"
+           {% endfor -%}
+           elementFormDefault="qualified">
+    
+    {% for entry in data -%}
+    <xs:import namespace="{{entry.namespace}}"
+               schemaLocation="{{entry.filename}}" />
+    {% endfor %}
+    
+    <xs:element type="implml:containerType" name="container">
+        <xs:annotation>
+            <xs:documentation>
+                Defines the root implementation container for a multi-implementation ImplML file.
+            </xs:documentation>
+        </xs:annotation>
+    </xs:element>
+    
+    
+    <!-- ======================== -->
+    <!-- Implementation container -->
+    <!-- ======================== -->
+    <xs:complexType name="containerType">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+            <xs:element ref="implml:phase"/>
+            <xs:element ref="implml:tag"/>
+            <xs:element ref="implml:settingRefsOverride"/>
+            <xs:element ref="implml:tempVariable"/>
+            <xs:element ref="implml:tempVariableSequence"/>
+            <xs:element ref="implml:outputRootDir"/>
+            <xs:element ref="implml:outputSubDir"/>
+            
+            <xs:element name="container" type="implml:containerType">
+            <xs:annotation>
+                <xs:documentation>
+                    <![CDATA[
+                    Defines an implementation container that can contain implementations and other containers.<br/>
+                    <br/>
+                    A container element can also contain other common elements affect all implementations defined
+                    inside the container.
+                    ]]>
+                </xs:documentation>
+            </xs:annotation>
+            </xs:element>
+            
+            {% for entry in data -%}
+            <xs:element ref="{{entry.id}}:{{entry.root_elem_name}}"/>
+            {% endfor -%}
+        </xs:choice>
+        <xs:attribute name="condition" type="xs:string" use="optional">
+            <xs:annotation>
+                <xs:documentation>
+                    <![CDATA[
+                    Specifies a condition that determines whether the implementation container is
+                    entered during execution.<br/>
+                    <br/>
+                    The condition should be a simple ConfML setting reference enclosed with ${},
+                    e.g. '${MyFeature.MySetting}'. If the value of the setting is equal to the
+                    expected value (defined using the 'value' attribute), the implementation
+                    container will be entered and the implementations inside executed. Note that
+                    the condition is evaluated at the moment the decision to enter the container
+                    or not is made.
+                    ]]>
+                </xs:documentation>
+            </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="value" type="xs:string" use="optional">
+            <xs:annotation>
+                <xs:documentation>
+                    Defines the expected value for the 'condition' attribute, defaults to 'true'.
+                </xs:documentation>
+            </xs:annotation>
+        </xs:attribute>
+    </xs:complexType>
+    
+    
+    <!-- ===== -->
+    <!-- Phase -->
+    <!-- ===== -->
+    <xs:element name="phase">
+        <xs:annotation>
+            <xs:documentation>
+                Overrides the execution phase of the implementations inside the container.
+            </xs:documentation>
+        </xs:annotation>
+        <xs:complexType>
+            <xs:attribute name="name" type="xs:string" use="required"/>
+        </xs:complexType>
+    </xs:element>
+    
+    
+    <!-- === -->
+    <!-- Tag -->
+    <!-- === -->
+    <xs:element name="tag">
+        <xs:annotation>
+            <xs:documentation>
+                Defines an implementation tag for the implementations inside the container.
+            </xs:documentation>
+        </xs:annotation>
+        <xs:complexType>
+            <xs:attribute name="name" type="xs:string" use="required"/>
+            <xs:attribute name="value" type="xs:string" use="required"/>
+        </xs:complexType>
+    </xs:element>
+    
+    
+    <!-- =============================== -->
+    <!-- Temporary variable and sequence -->
+    <!-- =============================== -->
+    <xs:element name="tempVariable">
+        <xs:annotation>
+            <xs:documentation>
+                <![CDATA[
+                Defines a global temporary variable that can be used in all implementations.<br/>
+                <br/>
+                A temporary variable is an ordinary ConfML setting that can be used normally
+                in implementations. Only the most basic ConfML setting types are supported.
+                ]]>
+            </xs:documentation>
+        </xs:annotation>
+        <xs:complexType>
+            <xs:attribute name="ref" type="xs:string" use="required">
+                <xs:annotation>
+                    <xs:documentation>
+                        The ConfML setting reference of the temporary variable, e.g. 'TempFeature.SomeSetting'.
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
+            <xs:attribute name="type" type="implml:tempVariableTypeType" use="optional">
+                <xs:annotation>
+                    <xs:documentation>
+                        The type of the temporary variable, defaults to 'string'.
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
+            <xs:attribute name="value" type="xs:string" use="optional">
+                <xs:annotation>
+                    <xs:documentation>
+                        The initial value of the temporary variable, defaults to an empty string.
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
+        </xs:complexType>
+    </xs:element>
+    
+    <xs:simpleType name="tempVariableTypeType">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="string"/>
+            <xs:enumeration value="int"/>
+            <xs:enumeration value="real"/>
+            <xs:enumeration value="boolean"/>
+        </xs:restriction>
+    </xs:simpleType>
+    
+    <xs:element name="tempVariableSequence">
+        <xs:annotation>
+            <xs:documentation>
+                Defines a global temporary variable sequence that can be used in all implementations.
+            </xs:documentation>
+        </xs:annotation>
+        <xs:complexType>
+            <xs:sequence>
+                <xs:element name="tempVariable" type="implml:tempVariableSequenceSubType"
+                            minOccurs="1" maxOccurs="unbounded">
+                    <xs:annotation>
+                        <xs:documentation>
+                            Defines a sub-setting for the temporary variable sequence.
+                        </xs:documentation>
+                    </xs:annotation>
+                </xs:element>
+            </xs:sequence>
+            <xs:attribute name="ref" type="xs:string" use="required"/>
+        </xs:complexType>
+    </xs:element>
+    
+    <xs:complexType name="tempVariableSequenceSubType">
+        <xs:attribute name="ref" type="xs:string" use="required">
+            <xs:annotation>
+                <xs:documentation>
+                    The ConfML setting reference of the temporary variable, e.g. 'SomeSubSetting'.
+                </xs:documentation>
+            </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="type" type="implml:tempVariableTypeType" use="optional">
+            <xs:annotation>
+                <xs:documentation>
+                    The type of the sub-setting, defaults to 'string'.
+                </xs:documentation>
+            </xs:annotation>
+        </xs:attribute>
+    </xs:complexType>
+    
+    
+    <!-- =========================== -->
+    <!-- Setting references override -->
+    <!-- =========================== -->
+    <xs:element name="settingRefsOverride">
+        <xs:annotation>
+            <xs:documentation>
+                <![CDATA[
+                Defines setting reference overrides for the implementations inside the container.<br/>
+                <br/>
+                The override can either be a list of setting refences, or it can specify that setting
+                references are irrelevant for implementation execution.
+                ]]>
+            </xs:documentation>
+        </xs:annotation>
+        <xs:complexType>
+            <xs:sequence>
+                <xs:element name="settingRef" type="implml:settingRefType"
+                            minOccurs="0" maxOccurs="unbounded">
+                    <xs:annotation>
+                        <xs:documentation>
+                            Specifies a single setting reference in the setting reference list.
+                        </xs:documentation>
+                    </xs:annotation>
+                </xs:element>
+            </xs:sequence>
+            <xs:attribute name="refsIrrelevant" use="optional">
+                <xs:annotation>
+                    <xs:documentation>
+                        Specifies that setting references are irrelevant for the execution of the
+                        implementation inside the container (i.e. they are never filtered out
+                        based on setting references).
+                    </xs:documentation>
+                </xs:annotation>
+                <xs:simpleType>
+                    <xs:restriction base="xs:string">
+                        <xs:enumeration value="true"/>
+                    </xs:restriction>
+                </xs:simpleType>
+            </xs:attribute>
+        </xs:complexType>
+    </xs:element>
+    
+    <xs:complexType name="settingRefType">
+        <xs:attribute name="value" type="xs:string" use="required"/>
+    </xs:complexType>
+    
+    
+    <!-- ========================== -->
+    <!-- Output directory overrides -->
+    <!-- ========================== -->
+    <xs:element name="outputRootDir">
+        <xs:annotation>
+            <xs:documentation>
+                Overrides the output root directory of the implementations inside the container.
+                This can be used e.g. to always generate output under \epoc32\data\
+            </xs:documentation>
+        </xs:annotation>
+        <xs:complexType>
+            <xs:attribute name="value" use="required"/>
+        </xs:complexType>
+    </xs:element>
+    <xs:element name="outputSubDir">
+        <xs:annotation>
+            <xs:documentation>
+                Overrides the output sub-directory of the implementations inside the container.
+            </xs:documentation>
+        </xs:annotation>
+        <xs:complexType>
+            <xs:attribute name="value" use="required"/>
+        </xs:complexType>
+    </xs:element>
+    
+</xs:schema>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/implmlvalidation.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,176 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+import logging
+
+from cone.public import api, exceptions, plugin, utils, parsecontext
+from cone.validation.parsecontext import ValidationParseContext
+import cone.validation.common
+
+class ValidationContext(object):
+    def __init__(self, configuration):
+        self.configuration = configuration
+        self.problems = []
+        
+        #: Flat list of all implementations, including containers
+        self.all_impls = []
+
+class ValidatorBase(object):
+    """
+    Base class for implementation validators.
+    
+    NOTE THAT THIS CLASS SHOULD NOT BE DIRECTLY SUB-CLASSED.
+    Sub-class either ImplValidatorBase or GlobalValidatorBase
+    instead.
+    """
+    PROBLEM_TYPES = None
+    
+    def __init__(self, context):
+        self.context = context
+
+class ImplValidatorBase(ValidatorBase):
+    """
+    Base class for validators that validate only a single implementation.
+    """
+    SUPPORTED_IMPL_CLASSES = []
+    
+    def __init__(self, context, impl):
+        self.context = context
+        self.impl = impl
+    
+    def validate(self):
+        """
+        Called to validate an implementation instance.
+        """
+        pass
+
+    def check_feature_reference(self, ref, line, problem_type):
+        """
+        Check that a feature with the given reference exists, and if
+        not, add a problem.
+        
+        @param ref: The feature reference to check.
+        @param line: The line number to set to the created problem.
+        @param line: The problem type to set to the created problem.
+        """
+        dview = self.context.configuration.get_default_view()
+        try:
+            dview.get_feature(ref)
+        except exceptions.NotFound:
+            prob = api.Problem(
+                msg = u"Setting '%s' not found in configuration" % ref,
+                type = problem_type,
+                line = line,
+                file = self.impl.ref)
+            self.context.problems.append(prob)
+
+class GlobalValidatorBase(ValidatorBase):
+    """
+    Base class for validators that validate the entire implementation set at once.
+    """
+    def validate(self):
+        pass
+
+def get_validator_classes(problem_type_filter=None):
+    """
+    Return a list of all ImplML validator classes that match the given
+    problem type filter (i.e. all validator classes that yield problems
+    that will not be filtered out).
+    
+    @param problem_type_filter: The filter, if None, all validator
+        classes will be returned.
+    """
+    classes = []
+    
+    # Validators from plug-in entry points 
+    classes.extend(cone.validation.common.load_plugin_classes(
+        'cone.plugins.implvalidators',
+        ValidatorBase))
+    
+    # Built-in validators
+    from cone.validation.builtinvalidators.implml import VALIDATOR_CLASSES
+    classes.extend(VALIDATOR_CLASSES)
+    
+    return cone.validation.common.filter_classes(classes, problem_type_filter)
+
+def validate_impl_set(impl_set, configuration, validator_classes=None):
+    """
+    Validate the given implementation set.
+    @param impl_set: The implementations to validate.
+    @param configuration: The configuration used in the validation.
+    @param validator_classes: The validator classes to use for the validation.
+        If None, all validator classes will be used.
+    @return: A list of Problem objects.
+    """
+    context = ValidationContext(configuration)
+    context.all_impls = _get_flat_impl_list(impl_set)
+    
+    if validator_classes is None:
+        validator_classes = get_validator_classes()
+    
+    # Run global validation first
+    for vc in validator_classes:
+        if issubclass(vc, GlobalValidatorBase):
+            try:
+                validator = vc(context)
+                validator.validate()
+            except Exception, e:
+                utils.log_exception(logging.getLogger('cone'),
+                                    "Error while validating: %s: %s" \
+                                    % (e.__class__.__name__, e))
+    
+    # Then run validation for individual implementations
+    for impl in context.all_impls:
+        for vc in validator_classes:
+            if issubclass(vc, ImplValidatorBase) and isinstance(impl, vc.SUPPORTED_IMPL_CLASSES):
+                try:
+                    validator = vc(context, impl)
+                    validator.validate()
+                except Exception, e:
+                    utils.log_exception(logging.getLogger('cone'),
+                                        "Error validating '%s': %s: %s" \
+                                        % (impl, e.__class__.__name__, e))
+    return context.problems
+
+def _get_flat_impl_list(impl_set):
+    """
+    Return a flat list of all implementations in the given set.
+    """
+    result = []
+    def add_to_result(impl):
+        result.append(impl)
+        if isinstance(impl, plugin.ImplContainer):
+            for sub_impl in impl.impls:
+                add_to_result(sub_impl)
+    for impl in impl_set:
+        add_to_result(impl)
+    return result
+
+def validate_impls(configuration, filter='.*', validator_classes=None):
+    """
+    Validate all implementations in the given configuration.
+    @param filter: Regex for filtering the implementations to validate.
+    @param validator_classes: The validator classes to use for the validation.
+        If None, all validator classes will be used.
+    """
+    # Set up the parse context to collect problems from the parsing phase
+    context = ValidationParseContext()
+    parsecontext.set_implml_context(context)
+    
+    impl_set = plugin.get_impl_set(configuration, filter=filter)
+    problems = validate_impl_set(impl_set, configuration, validator_classes)
+    
+    return context.problems + problems
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/parsecontext.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,35 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+from cone.public import api, parsecontext
+
+class ValidationParseContext(parsecontext.ParseContext):
+    """
+    Parse context that collects all exceptions and problems that
+    occur during parsing into a problem list.
+    """
+    def __init__(self):
+        parsecontext.ParseContext.__init__(self)
+        self.problems = []
+        
+    def _handle_exception(self, exception, file_path):
+        problem = api.Problem.from_exception(exception)
+        problem.file = file_path
+        self.problems.append(problem)
+    
+    def _handle_problem(self, problem, file_path):
+        problem.file = file_path
+        self.problems.append(problem)
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/problem_type_filter.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,88 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+class ProblemTypeFilter(object):
+    """
+    Class for filtering problem types.
+    
+    An instance of this class can be constructed with includes
+    and excludes, and then it can be asked if a certain problem
+    type matches and should be included.
+    """
+    def __init__(self, includes, excludes):
+        self._includes = [Pattern(expr) for expr in includes]
+        self._excludes = [Pattern(expr) for expr in excludes]
+    
+    def match(self, problem_type):
+        """
+        Check whether the given problem type matches the filter or not.
+        @return: True if matches (should be included), False if not.
+        """
+        # No filters: always match
+        if not self._includes and not self._excludes:
+            return True
+        
+        # Filter out entries that don't match includes
+        if self._includes and not self._match(self._includes, problem_type):
+            return False
+        
+        # Filter out entries that match excludes
+        if self._excludes and self._match(self._excludes, problem_type):
+            return False
+        
+        return True
+    
+    def filter(self, lst, key=lambda item: item.type):
+        result = []
+        for item in lst:
+            if self.match(key(item)):
+                result.append(item)
+        return result
+    
+    def _match(self, patterns, problem_type):
+        for p in patterns:
+            if p.match(problem_type):
+                return True
+        return False
+
+class Pattern(object):
+    def __init__(self, pattern):
+        self.elements = pattern.split('.')
+    
+    def match(self, problem_type):
+        type_elements = problem_type.split('.')
+        for i in xrange(max(len(type_elements), len(self.elements))):
+            if i < len(type_elements):
+                type_elem = type_elements[i]
+            else:
+                # The pattern is longer than the type, so it cannot
+                # possibly match.
+                # E.g. type = 'foo', pattern = 'foo.bar.baz'
+                return False
+            
+            if i < len(self.elements):
+                pattern_elem = self.elements[i]
+            else:
+                # The pattern ends and we have matched so far, so the
+                # type is a sub-type of an included one.
+                # E.g. type = 'foo.bar.baz', pattern = 'foo.bar'
+                return True
+            
+            if pattern_elem != '*' and type_elem != pattern_elem:
+                return False
+        
+        return True
+        
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/schemavalidation.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,495 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+import sys, os
+import logging
+import StringIO
+import pkg_resources
+import jinja2
+from cone.public import api, utils, exceptions
+import cone.public.plugin
+
+log = logging.getLogger('cone.schemavalidation')
+
+ROOT_PATH = os.path.abspath(os.path.dirname(__file__))
+
+CONFML_SCHEMA_DIR = 'confml_xsd'
+
+SCHEMA_FILES_BY_NAMESPACE = {'http://www.s60.com/xml/confml/1': 'confml.xsd',
+                             'http://www.s60.com/xml/confml/2': 'confml2.xsd'}
+
+_schema_cache = {}
+
+# ============================================================================
+
+def validate_confml_file(config, ref):
+    """
+    Schema-validate the given ConfML file in a configuration.
+    @param config: The configuration.
+    @param ref: The resource reference of the file to validate.
+    @return: A list of api.Problem objects.
+    """
+    return _validate_file(config, ref, validate_confml_data)
+
+def validate_implml_file(config, ref):
+    """
+    Schema-validate the given ImplML file in a configuration.
+    @param config: The configuration.
+    @param ref: The resource reference of the file to validate.
+    @return: A list of api.Problem objects.
+    """
+    return _validate_file(config, ref, validate_implml_data)
+
+def validate_confml_data(data):
+    """
+    Schema-validate the given ConfML data.
+    
+    @raise ParseError: Something is wrong with the data (invalid XML,
+        unsupported ConfML namespace or not conforming to the schema)
+    """
+    _validate_data(data, _get_confml_schema_for_namespace, 'xml.confml')
+
+def validate_implml_data(data):
+    """
+    Schema-validate the given ImplML data.
+    
+    @raise ParseError: Something is wrong with the data (invalid XML,
+        unsupported ImplML namespace or not conforming to the schema)
+    """
+    _validate_data(data, _get_implml_schema_for_namespace, 'xml.implml')
+
+# ============================================================================
+
+def _validate_file(config, ref, data_validator_func):
+    res = config.get_resource(ref)
+    try:        data = res.read()
+    finally:    res.close()
+    
+    problem = None
+    try:
+        data_validator_func(data)
+    except exceptions.ParseError, e:
+        problem = api.Problem.from_exception(e)
+
+    if problem:
+        problem.file = ref
+        return [problem]
+    else:
+        return []
+
+def _parse_schema(filename, file_data_dict):
+    """
+    Parse a schema using a filename-data dictionary as the source.
+    @param filename: Name of the schema file to parse.
+    @param file_data_dict: Dictionary mapping file names to file data.
+    @return: The parsed schema object.
+    """
+    if filename not in file_data_dict:
+        raise RuntimeError("Could not parse XML schema file '%s', no such file" % filename)
+    
+    schema_data = file_data_dict[filename]
+    
+    import lxml.etree
+    
+    parser = lxml.etree.XMLParser()
+    class Resolver(lxml.etree.Resolver):
+        def resolve(self, url, id, context):
+            if url not in file_data_dict:
+                log.error("Could not resolve schema file '%s', no such file" % url)
+                raise RuntimeError("No file named '%s'" % url)
+            data = file_data_dict[url]
+            return self.resolve_string(data, context)
+    parser.resolvers.add(Resolver())
+    
+    try:
+        schema_doc = lxml.etree.fromstring(schema_data, parser=parser)
+        schema = lxml.etree.XMLSchema(schema_doc)
+    except lxml.etree.LxmlError, e:
+        raise RuntimeError(
+            "Error parsing schema file '%s': %s: %s" \
+            % (filename, e.__class__.__name__, str(e)))
+    return schema
+
+def _validate_data(data, schema_resolver_func, xml_parse_problem_type):
+    """
+    Validate the given XML data.
+    @param data: The raw binary data to validate.
+    @param schema_resolver_func: The function used to resolve the
+        schema used for validation. The function is given the namespace
+        of the root element and is supposed to return the schema object
+        and problem type to use, or raise a ParseError.
+    @param xml_parse_problem_type: Problem type to use if XML parsing
+        fails of the data fails.
+    
+    @raise ParseError: Something is wrong with the data (invalid XML
+        or not conforming to the schema)
+    """
+    # Find out the XML namespace in the root element
+    try:
+        namespace, _ = utils.xml.get_xml_root(StringIO.StringIO(data))
+    except exceptions.XmlParseError, e:
+        e.problem_type = xml_parse_problem_type
+        raise e
+    
+    schema, problem_type = schema_resolver_func(namespace)
+    
+    # Parse the XML document
+    import lxml.etree
+    try:
+        doc = lxml.etree.fromstring(data)
+    except lxml.etree.XMLSyntaxError, e:
+        raise exceptions.XmlParseError(
+            "XML parse error on line %d: %s" % (e.position[0], e),
+            problem_lineno  = e.position[0],
+            problem_msg     = str(e),
+            problem_type    = xml_parse_problem_type)
+    
+    # Validate the document against the schema
+    if not schema.validate(doc):
+        error = schema.error_log.last_error
+        raise exceptions.XmlSchemaValidationError(
+            "Line %d: %s" % (error.line, error.message),
+            problem_lineno  = error.line,
+            problem_msg     = error.message,
+            problem_type    = problem_type)
+    
+
+class UnsupportedNamespaceError(exceptions.ParseError):
+    pass
+
+_confml_schema_file_cache = None
+def get_confml_schema_files():
+    global _confml_schema_file_cache
+    if _confml_schema_file_cache is None:
+        _confml_schema_file_cache = _load_confml_schema_files()
+    return _confml_schema_file_cache
+
+def get_schema_file_data(file):
+    """
+    Return the data of the given XML schema file.
+    
+    @raise ValueError: No such schema file exists.
+    """
+    resource_path = CONFML_SCHEMA_DIR + '/' + file
+    if pkg_resources.resource_exists('cone.validation', resource_path):
+        data = pkg_resources.resource_string('cone.validation', resource_path)
+        return data
+    else:
+        msg = "Could not get schema file '%s': Package resource '%s' does not exist" \
+            % (file, resource_path)
+        raise ValueError(msg)
+
+def get_schema_file_for_namespace(namespace):
+    """
+    Return the correct schema file name for the given namespace.
+    
+    @param namespace: The namespace for which to get the schema file.
+    @return: The name of the schema file (suitable for calling
+        get_schema_file_data() with), or None if no schema is associated
+        with the namespace.
+    """
+    return SCHEMA_FILES_BY_NAMESPACE.get(namespace, None)
+
+
+def _get_confml_schema_for_namespace(namespace):
+    """
+    Return the correct XML schema and problem type ID for
+    the given ConfML namespace.
+    @return: Tuple (schema, problem_type).
+    """
+    PROBLEM_TYPE = 'schema.confml'
+    
+    # Return a cached schema if possible
+    if namespace in _schema_cache:
+        return _schema_cache[namespace], PROBLEM_TYPE
+    
+    # Get the schema file and its raw byte data
+    schema_file = get_schema_file_for_namespace(namespace)
+    if schema_file is None:
+        raise exceptions.ConfmlParseError(
+            "Unsupported ConfML namespace '%s'" % namespace)
+    schema_data = get_schema_file_data(schema_file)
+    
+    # Parse the schema
+    import lxml.etree
+    parser = lxml.etree.XMLParser()
+    class PackageDataResolver(lxml.etree.Resolver):
+        def resolve(self, url, id, context):
+            data = get_schema_file_data(url)
+            return self.resolve_string(data, context)
+    parser.resolvers.add(PackageDataResolver())
+    schema_doc = lxml.etree.fromstring(schema_data, parser=parser)
+    schema = lxml.etree.XMLSchema(schema_doc)
+    
+    _schema_cache[namespace] = schema
+    return schema, PROBLEM_TYPE
+
+def _load_confml_schema_files():
+    files = {}
+    for name in pkg_resources.resource_listdir('cone.validation', CONFML_SCHEMA_DIR):
+        path = CONFML_SCHEMA_DIR + '/' + name
+        if path.lower().endswith('.xsd'):
+            files[name] = pkg_resources.resource_string('cone.validation', path)
+    return files
+
+# ============================================================================
+#
+#
+# ============================================================================
+
+# Reader class list stored here so that it can be used to check if the reader
+# class list changes, and reload the schema files in that case
+_implml_reader_class_list = None
+
+_implml_schema_file_cache = None
+_implml_schema_cache = {}
+
+def _check_reader_class_list():
+    """
+    Check if the reader class list has changed, and clear all caches if so.
+    """
+    global _implml_reader_class_list
+    global _implml_schema_file_cache
+    global _implml_schema_cache
+    
+    rc_list = cone.public.plugin.ImplFactory.get_reader_classes()
+    if _implml_reader_class_list is not rc_list:
+        _implml_reader_class_list = rc_list
+        _implml_schema_file_cache = None
+        _implml_schema_cache = {}
+
+def dump_schema_files(dump_dir):
+    CONFML_SCHEMA_DIR = os.path.join(dump_dir, 'confml')
+    IMPLML_SCHEMA_DIR = os.path.join(dump_dir, 'implml')
+    if not os.path.exists(CONFML_SCHEMA_DIR):
+        os.makedirs(CONFML_SCHEMA_DIR)
+    if not os.path.exists(IMPLML_SCHEMA_DIR):
+        os.makedirs(IMPLML_SCHEMA_DIR)
+    
+    def dump_files(files, dir):
+        for name, data in files.iteritems():
+            path = os.path.join(dir, name)
+            f = open(path, 'wb')
+            try:        f.write(data)
+            finally:    f.close()
+    
+    dump_files(get_confml_schema_files(), CONFML_SCHEMA_DIR)
+    dump_files(get_implml_schema_files(), IMPLML_SCHEMA_DIR)
+
+class _ImplmlReaderEntry(object):
+    def __init__(self, id, namespace, data, root_elem_name, schema_problem_sub_id):
+        self.id = id
+        self.filename = id + '.xsd'
+        self.namespace = namespace
+        self.data = data
+        self.root_elem_name = root_elem_name
+        self.schema_problem_sub_id = schema_problem_sub_id
+
+def get_implml_schema_files():
+    """
+    Return a dictionary of ImplML schema file data by file name.
+    """
+    global _implml_schema_file_cache
+    
+    _check_reader_class_list()
+    if _implml_schema_file_cache is None:
+        _implml_schema_file_cache = _load_implml_schema_files()
+    return _implml_schema_file_cache
+
+def _load_implml_schema_files():
+    result = {}
+    result['implml.xsd'] = _generate_implml_schema_data()
+    
+    result['XInclude.xsd'] = pkg_resources.resource_string(
+        'cone.validation', CONFML_SCHEMA_DIR + '/XInclude.xsd')
+    
+    for entry in _get_implml_reader_entries():
+        if entry.data is not None:
+            result[entry.filename] = entry.data
+        else:
+            result[entry.filename] = _generate_default_schema_data(entry)
+    return result
+
+def _get_implml_reader_entries():
+    entries = []
+    for rc in cone.public.plugin.ImplFactory.get_reader_classes():
+        # Skip ImplContainerReader
+        if rc is cone.public.plugin.ImplContainerReader:
+            continue
+        
+        entry = _ImplmlReaderEntry(rc.NAMESPACE_ID,
+                                   rc.NAMESPACE,
+                                   rc.get_schema_data(),
+                                   rc.ROOT_ELEMENT_NAME,
+                                   rc.SCHEMA_PROBLEM_SUB_ID)
+        entries.append(entry)
+    return entries
+
+def _generate_implml_schema_data():
+    template_data = pkg_resources.resource_string('cone.validation', 'implml_xsd/implml-template.xsd')
+    template = jinja2.Template(template_data)
+    data = template.render(data=_get_implml_reader_entries()).encode('utf-8')
+    return data
+
+def _generate_default_schema_data(entry):
+    template_data = pkg_resources.resource_string('cone.validation', 'implml_xsd/default-impl-schema-template.xsd')
+    template = jinja2.Template(template_data)
+    data = template.render(entry=entry).encode('utf-8')
+    return data
+
+def _get_implml_schema_for_namespace(namespace):
+    """
+    Return the correct XML schema and problem type ID for
+    the given ImplML namespace.
+    @return: Tuple (schema, problem_type).
+    """
+    global _implml_schema_cache
+    
+    problem_type_sub_id = None
+    filename = None
+    if namespace == 'http://www.symbianfoundation.org/xml/implml/1':
+        filename = 'implml.xsd'
+        problem_type_sub_id = 'implml'
+    else:
+        for entry in _get_implml_reader_entries():
+            if entry.namespace == namespace:
+                filename = entry.filename
+                problem_type_sub_id = entry.schema_problem_sub_id
+                break
+    if filename is None:
+        raise exceptions.ImplmlParseError(
+            "Unsupported ImplML namespace: %s" % namespace)
+    
+    # Check reader classes before trying to use the schema cache
+    _check_reader_class_list()
+    
+    # Get the schema from cache if possible
+    if filename in _implml_schema_cache:
+        return _implml_schema_cache[filename]
+    
+    file_data_dict = get_implml_schema_files()
+    if filename not in file_data_dict:
+        raise exceptions.ImplmlParseError(
+            "ImplML schema file '%s' does not exist!" % filename)
+    
+    schema = _parse_schema(filename, file_data_dict)
+    problem_type = 'schema.implml'
+    if problem_type_sub_id:
+        problem_type += '.' + problem_type_sub_id
+    return schema, problem_type
+
+# ============================================================================
+#
+#
+# ============================================================================
+
+class SchemaValidationTestMixin(object):
+    """
+    Mix-in class for providing assertion methods for unittest.TestCase sub-classes
+    testing schema validation.
+    """
+    
+    def assert_schemavalidation_succeeds(self, type, dir, namespace=None):
+        """
+        Assert that schema validation succeeds for all the files in the given directory.
+        @param type: Type of the schema validation to perform, can be 'confml' or 'implml'.
+        @param dir: The directory containing the files to validate
+        @param namespace: If not None, specifies the namespace that the root element
+            in all the must have. If any of the files has a different namespace, the
+            assertion fails.
+        """
+        errors = []
+        for file in self._get_files(dir):
+            f = open(file, 'rb')
+            try:        data = f.read()
+            finally:    f.close()
+            
+            if namespace is not None:
+                self._check_root_element_namespace(file, data, namespace)
+            
+            validate_data = self._get_validator_function_for_type(type)
+            try:
+                validate_data(data)
+            except Exception, e:
+                errors.append(file)
+                errors.append("Raised: %r" % e)
+        
+        if errors:
+            self.fail('\n'.join(errors))
+    
+    def assert_schemavalidation_fails(self, type, dir, namespace=None, problem_type=None):
+        """
+        Assert that schema validation fails for all the files in the given directory.
+        @param type: Type of the schema validation to perform, can be 'confml' or 'implml'.
+        @param dir: The directory containing the files to validate
+        @param namespace: If not None, specifies the namespace that the root element
+            in all the must have. If any of the files has a different namespace, the
+            assertion fails.
+        @param: problem_type: If not None, specifies the problem type that the
+            SchemaValidationError raised from validation must contain.
+        """
+        errors = []
+        for file in self._get_files(dir):
+            f = open(file, 'rb')
+            try:        data = f.read()
+            finally:    f.close()
+            
+            if namespace is not None:
+                self._check_root_element_namespace(file, data, namespace)
+            
+            validate_data = self._get_validator_function_for_type(type)
+            try:
+                validate_data(data)
+                errors.append(file)
+            except exceptions.XmlSchemaValidationError, e:
+                if problem_type is not None:
+                    if e.problem_type != problem_type:
+                        errors.append(file)
+                        errors.append("Problem type was '%s', expected '%s'" % (e.problem_type, problem_type))
+        
+        if errors:
+            self.fail('The following files were reported as valid when they should not have been:\n%s' % '\n'.join(errors))
+    
+    
+    def _get_files(self, dir):
+        """
+        Return a list of all files in the given directory.
+        @param dir: The directory.
+        @return: List of all files in the dir. Each entry has the
+            also the directory joined to it.
+        """
+        files = []
+        for name in os.listdir(dir):
+            path = os.path.join(dir, name)
+            if os.path.isfile(path):
+                files.append(path)
+        return files
+    
+    def _check_root_element_namespace(self, file_path, data, expected_namespace):
+        file_namespace, _ = utils.xml.get_xml_root(StringIO.StringIO(data))
+        if file_namespace != expected_namespace:
+            msg = "Error testing schema validation with file '%s': "\
+                  "Root element namespace is not what was expected (expected '%s', got '%s')"\
+                  % (file_path, expected_namespace, file_namespace)
+            self.fail(msg)
+    
+    def _get_validator_function_for_type(self, type):
+        if type == 'implml':
+            return validate_implml_data
+        elif type == 'confml':
+            return validate_confml_data
+        else:
+            raise ValueError("Invalid schema validation type '%s', should be 'implml' or 'confml'" % type)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/__init__.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,15 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/runtests.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,19 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+if __name__ == '__main__':
+    import nose
+    nose.core.run(argv=['collector','--include=unittest', '--verbosity=3'])
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/testdata/model/confml/fixed_expected/duplicate_root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<configuration name="test" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+  <xi:include href="duplicate_settings1.confml" />
+<xi:include href="duplicate_settings2.confml" />
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/testdata/model/confml/fixed_expected/duplicate_settings1.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,37 @@
+<configuration name="test1" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+  <feature name="SampleFea" ref="Feature">
+    <setting name="One new" ref="One" type="string">
+      <xs:maxLength value="3" />
+    </setting>
+  <setting name="Two new" ref="Two" type="int">
+      <desc>Testing desc</desc>
+    </setting>
+  <setting name="Three new" ref="Three" type="selection">
+      <option name="FooBar" value="1" />
+    <option name="Jee" value="2" />
+    <option name="Man" value="3" />
+    </setting>
+  <setting name="No data" ref="NoData" type="string" />
+  <setting name="Test Sequence" ref="TestSequence" type="sequence">
+      <setting name="number two of sequence Two" ref="SeqTwo" type="int" />
+    <setting name="one two three" ref="SeqThree" type="selection">
+        <option name="seqone" value="1" />
+      </setting>
+    </setting>
+  </feature>
+<data>
+    <Feature>
+      <One>fo</One>
+    <Two>1</Two>
+    <Three>1</Three>
+    <TestSequence template="true">
+        <SeqTwo />
+      <SeqThree />
+      </TestSequence>
+    <TestSequence>
+        <SeqTwo>123</SeqTwo>
+      <SeqThree />
+      </TestSequence>
+    </Feature>
+  </data>
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/testdata/model/confml/fixed_expected/duplicate_settings2.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,1 @@
+<configuration name="test1" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema" />
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/testdata/model/confml/single_files/data_without_feature.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/1" name="DataWithoutFeature">
+    <data>
+        <Foo>
+            <Bar>foobar</Bar>
+        </Foo>
+    </data>
+</configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/testdata/model/confml/single_files/duplicate_root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/2" name="test" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xi="http://www.w3.org/2001/XInclude">
+  <xi:include href="duplicate_settings1.confml"/>
+  <xi:include href="duplicate_settings2.confml"/>
+</configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/testdata/model/confml/single_files/duplicate_settings1.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/1" name="test1"  xmlns:xs="http://www.w3.org/2001/XMLSchema">
+    <feature ref="Feature" name="SampleFea">
+        <setting ref="One" name="One" type="string">
+        </setting>
+        <setting ref="Two" name="Two" type="int">
+        </setting>
+        <setting ref="Three" name="Three" type="selection">
+            <option name="1" value="1"/>
+        </setting>
+        <setting ref="NoData" name="No data" type="string">
+        </setting>
+        <setting ref="TestSequence" name="Test Sequence" type="sequence">
+            <setting ref="SeqTwo" name="SeqTwo" type="int">
+            </setting>
+            <setting ref="SeqThree" name="SeqThree" type="selection">
+                <option name="seqone" value="1"/>
+            </setting>
+        </setting>
+    </feature>
+    
+    
+    <data>
+        <Feature>
+            <One>fo</One>
+            <Two>1</Two>
+            <Three>1</Three>
+            <TestSequence template="true" />
+            <TestSequence>
+                <SeqTwo>123</SeqTwo>
+            </TestSequence>
+        </Feature>
+    </data>
+</configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/testdata/model/confml/single_files/duplicate_settings2.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/1" name="test1"  xmlns:xs="http://www.w3.org/2001/XMLSchema">
+    <feature ref="Feature" name="SampleFea">
+        <setting ref="One" name="One new" type="string">
+            <xs:maxLength value="3"/>
+        </setting>
+        <setting ref="Two" name="Two new" type="int">
+            <desc>Testing desc</desc>
+        </setting>
+        <setting ref="Three" name="Three new" type="selection">
+            <option name="FooBar" value="1"/>
+            <option name="Jee" value="2"/>
+            <option name="Man" value="3"/>
+        </setting>
+        <setting ref="NoData" name="No data" type="string">
+        </setting>
+        <setting ref="TestSequence" name="Test Sequence" type="sequence">
+            <setting ref="SeqTwo" name="number two of sequence Two" type="int">
+            </setting>
+            <setting ref="SeqThree" name="one two three" type="selection">
+                <option name="seqone" value="1"/>
+            </setting>
+        </setting>
+    </feature>
+</configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/testdata/model/confml/single_files/min_max_length.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/1" name="MinMaxLength"  xmlns:xs="http://www.w3.org/2001/XMLSchema">
+    <feature ref="MinMaxLengthOk" name="Min/max length validation test feature (values OK)">
+        <setting ref="Max" name="Max" type="string">
+            <xs:maxLength value="3"/>
+        </setting>
+        <setting ref="Min" name="Min" type="string">
+            <xs:minLength value="3"/>
+        </setting>
+        <setting ref="Exact" name="Exact" type="string">
+            <xs:length value="3"/>
+        </setting>
+        <setting ref="NoData" name="No data" type="string">
+            <xs:minLength value="3"/>
+        </setting>
+    </feature>
+    
+    <feature ref="MinMaxLengthNotOk" name="Min/max length validation test feature (values not OK)">
+        <setting ref="Max" name="Max" type="string">
+            <xs:maxLength value="3"/>
+        </setting>
+        <setting ref="Min" name="Min" type="string">
+            <xs:minLength value="3"/>
+        </setting>
+        <setting ref="Exact1" name="Exact 1" type="string">
+            <xs:length value="3"/>
+        </setting>
+        <setting ref="Exact2" name="Exact 2" type="string">
+            <xs:length value="3"/>
+        </setting>
+    </feature>
+    
+    <data>
+        <MinMaxLengthOk>
+            <Max>fo</Max>
+            <Min>foobar</Min>
+            <Exact>baz</Exact>
+        </MinMaxLengthOk>
+        
+        <MinMaxLengthNotOk>
+            <Max>foobar</Max>
+            <Min>ba</Min>
+            <Exact1>baztu</Exact1>
+            <Exact2>b</Exact2>
+        </MinMaxLengthNotOk>
+    </data>
+</configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/testdata/model/confml/single_files_expected/data_without_feature.confml.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,2 @@
+Problem(msg="Feature 'Foo.Bar' not found", type='model.confml.missing_feature_for_data', line=5, file='data_without_feature.confml', severity='error')
+Problem(msg="Feature 'Foo' not found", type='model.confml.missing_feature_for_data', line=4, file='data_without_feature.confml', severity='error')
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/testdata/model/confml/single_files_expected/duplicate_root.confml.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,8 @@
+Problem(msg="Feature Feature has '2' definitions in files ['duplicate_settings1.confml', 'duplicate_settings2.confml']", type='model.confml.duplicate.feature', line=3, file='duplicate_settings2.confml', severity='info')
+Problem(msg="Feature Feature.NoData has '2' definitions in files ['duplicate_settings1.confml', 'duplicate_settings2.confml']", type='model.confml.duplicate.setting', line=15, file='duplicate_settings2.confml', severity='warning')
+Problem(msg="Feature Feature.One has '2' definitions in files ['duplicate_settings1.confml', 'duplicate_settings2.confml']", type='model.confml.duplicate.setting', line=4, file='duplicate_settings2.confml', severity='warning')
+Problem(msg="Feature Feature.TestSequence has '2' definitions in files ['duplicate_settings1.confml', 'duplicate_settings2.confml']", type='model.confml.duplicate.setting', line=17, file='duplicate_settings2.confml', severity='warning')
+Problem(msg="Feature Feature.TestSequence.SeqThree has '2' definitions in files ['duplicate_settings1.confml', 'duplicate_settings2.confml']", type='model.confml.duplicate.setting', line=20, file='duplicate_settings2.confml', severity='warning')
+Problem(msg="Feature Feature.TestSequence.SeqTwo has '2' definitions in files ['duplicate_settings1.confml', 'duplicate_settings2.confml']", type='model.confml.duplicate.setting', line=18, file='duplicate_settings2.confml', severity='warning')
+Problem(msg="Feature Feature.Three has '2' definitions in files ['duplicate_settings1.confml', 'duplicate_settings2.confml']", type='model.confml.duplicate.setting', line=10, file='duplicate_settings2.confml', severity='warning')
+Problem(msg="Feature Feature.Two has '2' definitions in files ['duplicate_settings1.confml', 'duplicate_settings2.confml']", type='model.confml.duplicate.setting', line=7, file='duplicate_settings2.confml', severity='warning')
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/testdata/model/confml/single_files_expected/min_max_length.confml.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+Problem(msg='Setting MinMaxLengthNotOk.Exact1: Exact number of characters must be 3 (value has 5)', type='model.confml.invalid_value.length', line=43, file='min_max_length.confml', severity='error')
+Problem(msg='Setting MinMaxLengthNotOk.Exact2: Exact number of characters must be 3 (value has 1)', type='model.confml.invalid_value.length', line=44, file='min_max_length.confml', severity='error')
+Problem(msg='Setting MinMaxLengthNotOk.Max: Maximum number of characters is 3 (value has 6)', type='model.confml.invalid_value.maxlength', line=41, file='min_max_length.confml', severity='error')
+Problem(msg='Setting MinMaxLengthNotOk.Min: Minimum number of characters is 3 (value has 2)', type='model.confml.invalid_value.minlength', line=42, file='min_max_length.confml', severity='error')
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/testdata/model/implml/expected/duplicate_tempvar_ref.implml.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,2 @@
+Problem(msg="Duplicate temporary variable ref 'Temp.Foo'", type='model.implml.container.duplicate_tempvar', line=4, file='Layer1/implml/duplicate_tempvar_ref.implml', severity='error')
+Problem(msg="Duplicate temporary variable ref 'Temp.Foo'", type='model.implml.container.duplicate_tempvar', line=8, file='Layer1/implml/duplicate_tempvar_ref.implml', severity='error')
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/testdata/model/implml/project/Layer1/implml/duplicate_tempvar_ref.implml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<container xmlns="http://www.symbianfoundation.org/xml/implml/1">
+    <container>
+        <tempVariable ref="Temp.Foo"/>
+    </container>
+    
+    <container>
+        <tempVariable ref="Temp.Foo"/>
+    </container>
+</container>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/testdata/model/implml/project/Layer1/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<confml:configuration xmlns:confml="http://www.s60.com/xml/confml/1" xmlns:xi="http://www.w3.org/2001/XInclude" name="Layer 1">
+  <!--<xi:include href="confml/foo.confml#/"/>-->
+</confml:configuration>
Binary file configurationengine/source/cone/validation/tests/testdata/model/implml/project/root.confml has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/testdata/schema/confml1/invalid/invalid_type.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<confml:configuration xmlns:confml="http://www.s60.com/xml/confml/1" name="Invalid type test">
+  <confml:feature ref="InvalidTypeTest" name="Invalid type test">
+    <confml:setting ref="TestSetting" name="Test setting" type="invalid_type"/>
+  </confml:feature>
+  <confml:data>
+    <confml:InvalidTypeTest>
+      <confml:TestSetting>test</confml:TestSetting>
+    </confml:InvalidTypeTest>
+  </confml:data>
+</confml:configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/testdata/schema/confml1/valid/feature1.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/1" name="Feature 1" version="1">
+  <feature ref="Feature1" name="Feature 1 (ConfML v1.0)">
+    <desc>Feature with all supported setting types for ConfML v1.0</desc>
+    <setting ref="RealSetting" name="Real setting" type="real">
+      <desc>A real setting</desc>
+    </setting>
+    <setting ref="IntSetting" name="Int setting" type="int">
+      <desc>An int setting</desc>
+    </setting>
+    <setting ref="StringSetting" name="String setting" type="string">
+      <desc>A string setting</desc>
+    </setting>
+    <setting ref="BooleanSetting" name="Boolean setting" type="boolean">
+      <desc>A boolean setting</desc>
+    </setting>
+    <setting ref="SelectionSetting" name="Selection setting" type="selection">
+      <desc>A selection setting</desc>
+      <option name="Option0" value="0"/>
+      <option name="Option1" value="1"/>
+      <option name="Option2" value="2"/>
+      <option name="Option3" value="3"/>
+      <option name="Option4" value="4"/>
+    </setting>
+    
+    <setting ref="MultiSelectionSetting" name="Multi-selection setting" type="multiSelection">
+      <desc>A multi-selection setting</desc>
+      <option name="Option 0" value="opt 0"/>
+      <option name="Option 1" value="opt 1"/>
+      <option name="Option 2" value="opt 2"/>
+      <option name="Option 3" value="opt 3"/>
+      <option name="Option 4" value="opt 4"/>
+    </setting>
+    
+    <setting ref="SequenceSetting" name="Sequence setting" type="sequence">
+      <desc>A sequence setting</desc>
+      <setting ref="RealSubSetting" name="Real sub-setting" type="real">
+        <desc>A real sub-setting</desc>
+      </setting>
+      <setting ref="IntSubSetting" name="Int sub-setting" type="int">
+        <desc>An int sub-setting</desc>
+      </setting>
+      <setting ref="StringSubSetting" name="String sub-setting" type="string">
+        <desc>A string sub-setting</desc>
+      </setting>
+      <setting ref="BooleanSubSetting" name="Boolean sub-setting" type="boolean">
+        <desc>A boolean sub-setting</desc>
+      </setting>
+      <setting ref="SelectionSubSetting" name="Selection sub-setting" type="selection">
+        <desc>A selection sub-setting</desc>
+        <option name="Op0" value="0"/>
+        <option name="Op1" value="1"/>
+        <option name="Op2" value="2"/>
+        <option name="Op3" value="3"/>
+        <option name="Op4" value="4"/>
+      </setting>
+      <setting ref="MultiSelectionSubSetting" name="Multi-selection sub-setting" type="multiSelection">
+        <desc>A multi-selection sub-setting</desc>
+        <option name="Option 0" value="opt 0"/>
+        <option name="Option 1" value="opt 1"/>
+        <option name="Option 2" value="opt 2"/>
+        <option name="Option 3" value="opt 3"/>
+        <option name="Option 4" value="opt 4"/>
+      </setting>
+    </setting>
+  </feature>
+  <data>
+    <Feature1>
+      <RealSetting>3.14</RealSetting>
+      <IntSetting>10</IntSetting>
+      <StringSetting>default string</StringSetting>
+      <BooleanSetting>true</BooleanSetting>
+      <SelectionSetting>1</SelectionSetting>
+      <MultiSelectionSetting>"opt 0" "opt 2" "opt 4"</MultiSelectionSetting>
+      <SequenceSetting template="true">
+        <RealSubSetting>1.0</RealSubSetting>
+        <IntSubSetting>1</IntSubSetting>
+        <StringSubSetting>template</StringSubSetting>
+        <BooleanSubSetting>false</BooleanSubSetting>
+        <SelectionSubSetting>0</SelectionSubSetting>
+        <MultiSelectionSubSetting>"opt 0"</MultiSelectionSubSetting>
+      </SequenceSetting>
+      <SequenceSetting>
+        <RealSubSetting>1.25</RealSubSetting>
+        <IntSubSetting>128</IntSubSetting>
+        <StringSubSetting>def1</StringSubSetting>
+        <BooleanSubSetting>false</BooleanSubSetting>
+        <SelectionSubSetting>1</SelectionSubSetting>
+        <MultiSelectionSubSetting>"opt 1"</MultiSelectionSubSetting>
+      </SequenceSetting>
+      <SequenceSetting>
+        <RealSubSetting>1.5</RealSubSetting>
+        <IntSubSetting>256</IntSubSetting>
+        <StringSubSetting>def2</StringSubSetting>
+        <BooleanSubSetting>false</BooleanSubSetting>
+        <SelectionSubSetting>1</SelectionSubSetting>
+        <MultiSelectionSubSetting>"opt 2"</MultiSelectionSubSetting>
+      </SequenceSetting>
+    </Feature1>
+  </data>
+  
+  <rfs>
+    <Feature1>
+      <RealSetting>true</RealSetting>
+      <IntSetting>false</IntSetting>
+      <StringSetting>false</StringSetting>
+      <BooleanSetting>true</BooleanSetting>
+      <SelectionSetting>true</SelectionSetting>
+      <MultiSelectionSetting>false</MultiSelectionSetting>
+    </Feature1>
+  </rfs>
+</configuration>
Binary file configurationengine/source/cone/validation/tests/testdata/schema/confml1/valid/feature2.confml has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/testdata/schema/confml1/valid/name_id_mapping_test.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,151 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/1" name="Test features for testing name-ID mappings" version="1">
+    <feature ref="NameIdMappingTestSourceSequences" name="Source sequences for name-ID mappings">
+        <setting ref="StringSequence" name="String sequence" type="sequence" mapKey="Value" mapValue="Value">
+            <setting ref="Value" name="Value sub-setting" type="string"/>
+        </setting>
+        
+        <setting ref="StringToStringSequence" name="String-to-string sequence" type="sequence" mapKey="Name" mapValue="Value">
+            <setting ref="Name" name="Name sub-setting" type="string"/>
+            <setting ref="Value" name="Value sub-setting" type="string"/>
+        </setting>
+        
+        <setting ref="StringToIntSequence" name="String-to-int sequence" type="sequence" mapKey="Name" mapValue="Value">
+            <setting ref="Name" name="Name sub-setting" type="string"/>
+            <setting ref="Value" name="Value sub-setting" type="int"/>
+        </setting>
+        
+        <setting ref="StringToRealSequence" name="String-to-real sequence" type="sequence" mapKey="Name" mapValue="Value">
+            <setting ref="Name" name="Name sub-setting" type="string"/>
+            <setting ref="Value" name="Value sub-setting" type="real"/>
+        </setting>
+    </feature>
+
+
+    <feature ref="NameIdMappingTestTargetSettings" name="Target settings for name-ID mappings">
+        <setting ref="Selection" name="Selection setting" type="selection">
+            <option map="NameIdMappingTestSourceSequences/StringSequence"/>
+            <option name="None" value="none"/>
+        </setting>
+        
+        <setting ref="Selection2" name="Selection setting 2" type="selection">
+            <option map="NameIdMappingTestSourceSequences/StringToStringSequence"/>
+            <option name="None" value="none"/>
+        </setting>
+        
+        <setting ref="String" name="String setting" type="string">
+            <option map="NameIdMappingTestSourceSequences/StringSequence"/>
+            <option name="None" value=""/>
+        </setting>
+        
+        <setting ref="String2" name="String setting 2" type="string">
+            <option map="NameIdMappingTestSourceSequences/StringToStringSequence"/>
+            <option name="None" value=""/>
+        </setting>
+        
+        <setting ref="Int" name="Int setting" type="int">
+            <option map="NameIdMappingTestSourceSequences/StringToIntSequence"/>
+            <option name="Zero" value="0"/>
+        </setting>
+        
+        <setting ref="Real" name="Real setting" type="real">
+            <option map="NameIdMappingTestSourceSequences/StringToRealSequence"/>
+            <option name="Zero" value="0"/>
+        </setting>
+        
+        <setting ref="Sequence" name="Sequence" type="sequence">
+            <setting ref="Selection" name="Selection sub-setting" type="selection">
+                <option map="NameIdMappingTestSourceSequences/StringSequence"/>
+                <option name="None" value="none"/>
+            </setting>
+            
+            <setting ref="Selection2" name="Selection sub-setting 2" type="selection">
+                <option map="NameIdMappingTestSourceSequences/StringToStringSequence"/>
+                <option name="None" value="none"/>
+            </setting>
+            
+            <setting ref="String" name="String sub-setting" type="string">
+                <option map="NameIdMappingTestSourceSequences/StringSequence"/>
+                <option name="None" value=""/>
+            </setting>
+            
+            <setting ref="String2" name="String sub-setting 2" type="string">
+                <option map="NameIdMappingTestSourceSequences/StringToStringSequence"/>
+                <option name="None" value=""/>
+            </setting>
+            
+            <setting ref="Int" name="Int sub-setting" type="int">
+                <option map="NameIdMappingTestSourceSequences/StringToIntSequence"/>
+                <option name="Zero" value="0"/>
+            </setting>
+            
+            <setting ref="Real" name="Real sub-setting" type="real">
+                <option map="NameIdMappingTestSourceSequences/StringToRealSequence"/>
+                <option name="Zero" value="0"/>
+            </setting>
+        </setting>
+    </feature>
+
+    <data>
+        <NameIdMappingTestSourceSequences>
+            <StringSequence template="true">
+                <Value></Value>
+            </StringSequence>
+            <StringSequence><Value>Entry 1</Value></StringSequence>
+            <StringSequence><Value>Entry 2</Value></StringSequence>
+            <StringSequence><Value>Entry 3</Value></StringSequence>
+            
+            <StringToStringSequence template="true">
+                <Name></Name>
+                <Value></Value>
+            </StringToStringSequence>
+            <StringToStringSequence><Name>Entry 1</Name><Value>e 1</Value></StringToStringSequence>
+            <StringToStringSequence><Name>Entry 2</Name><Value>e 2</Value></StringToStringSequence>
+            <StringToStringSequence><Name>Entry 3</Name><Value>e 3</Value></StringToStringSequence>
+            
+            <StringToIntSequence template="true">
+                <Name></Name>
+                <Value></Value>
+            </StringToIntSequence>
+            <StringToIntSequence><Name>Entry 1</Name><Value>100</Value></StringToIntSequence>
+            <StringToIntSequence><Name>Entry 2</Name><Value>120</Value></StringToIntSequence>
+            <StringToIntSequence><Name>Entry 3</Name><Value>130</Value></StringToIntSequence>
+            
+            
+            <StringToRealSequence template="true">
+                <Name></Name>
+                <Value></Value>
+            </StringToRealSequence>
+            <StringToRealSequence><Name>Entry 1</Name><Value>1.1</Value></StringToRealSequence>
+            <StringToRealSequence><Name>Entry 2</Name><Value>1.2</Value></StringToRealSequence>
+            <StringToRealSequence><Name>Entry 3</Name><Value>1.3</Value></StringToRealSequence>
+        </NameIdMappingTestSourceSequences>
+        
+        
+        <NameIdMappingTestTargetSettings>
+            <Selection>none</Selection>
+            <Selection2>none</Selection2>
+            <String></String>
+            <String2></String2>
+            <Int>0</Int>
+            <Real>0</Real>
+            
+            <Sequence template="true">
+                <Selection>none</Selection>
+                <Selection2>none</Selection2>
+                <String></String>
+                <String2></String2>
+                <Int>0</Int>
+                <Real>0</Real>
+            </Sequence>
+            <Sequence>
+                <Selection>none</Selection>
+                <Selection2>none</Selection2>
+                <String></String>
+                <String2></String2>
+                <Int>0</Int>
+                <Real>0</Real>
+            </Sequence>
+        </NameIdMappingTestTargetSettings>
+    </data>
+</configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/testdata/schema/confml2/invalid/invalid_type.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/2" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2" name="Invalid type test">
+  <confml:feature ref="InvalidTypeTest" name="Invalid type test">
+    <confml:setting ref="TestSetting" name="Test setting" type="invalid_type"/>
+  </confml:feature>
+  <confml:data>
+    <confml:InvalidTypeTest>
+      <confml:TestSetting>test</confml:TestSetting>
+    </confml:InvalidTypeTest>
+  </confml:data>
+</confml:configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/testdata/schema/confml2/valid/basic_setting_types_test.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/2" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2" name="Basic setting types test">
+  <confml:feature ref="BasicSettingTypesTest" name="Basic setting types test">
+    <confml:desc>Feature with basic setting types (ConfML v2.0)</confml:desc>
+    
+    <confml:setting ref="RealSetting" name="Real setting" type="real">
+      <confml:desc>A real setting</confml:desc>
+    </confml:setting>
+    
+    <confml:setting ref="IntSetting" name="Int setting" type="int">
+      <confml:desc>An int setting</confml:desc>
+    </confml:setting>
+    
+    <confml:setting ref="StringSetting" name="String setting" type="string">
+      <confml:desc>A string setting</confml:desc>
+    </confml:setting>
+    
+    <confml:setting ref="BooleanSetting" name="Boolean setting" type="boolean">
+      <confml:desc>A boolean setting</confml:desc>
+    </confml:setting>
+    
+    <confml:setting ref="SelectionSetting" name="Selection setting" type="selection">
+      <confml:desc>A selection setting</confml:desc>
+      <confml:option name="Option0" value="0"/>
+      <confml:option name="Option1" value="1"/>
+      <confml:option name="Option2" value="2"/>
+      <confml:option name="Option3" value="3"/>
+      <confml:option name="Option4" value="4"/>
+    </confml:setting>
+    
+    <confml:setting ref="MultiSelectionSetting" name="Multi-selection setting" type="multiSelection">
+      <confml:desc>A multi-selection setting</confml:desc>
+      <confml:option name="Option 0" value="opt 0"/>
+      <confml:option name="Option 1" value="opt 1"/>
+      <confml:option name="Option 2" value="opt 2"/>
+      <confml:option name="Option 3" value="opt 3"/>
+      <confml:option name="Option 4" value="opt 4"/>
+    </confml:setting>
+  </confml:feature>
+  
+  <confml:data>
+    <confml:BasicSettingTypesTest>
+      <confml:RealSetting>3.14</confml:RealSetting>
+      <confml:IntSetting>10</confml:IntSetting>
+      <confml:StringSetting>default string</confml:StringSetting>
+      <confml:BooleanSetting>true</confml:BooleanSetting>
+      <confml:SelectionSetting>1</confml:SelectionSetting>
+      <confml:MultiSelectionSetting>"opt 0" "opt 2" "opt 4"</confml:MultiSelectionSetting>
+    </confml:BasicSettingTypesTest>
+  </confml:data>
+  
+  <confml:rfs>
+    <confml:BasicSettingTypesTest>
+      <confml:RealSetting>true</confml:RealSetting>
+      <confml:IntSetting>false</confml:IntSetting>
+      <confml:StringSetting>false</confml:StringSetting>
+      <confml:BooleanSetting>true</confml:BooleanSetting>
+      <confml:SelectionSetting>true</confml:SelectionSetting>
+      <confml:MultiSelectionSetting>true</confml:MultiSelectionSetting>
+    </confml:BasicSettingTypesTest>
+  </confml:rfs>
+</confml:configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/testdata/schema/confml2/valid/file_folder_test.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/2" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2" name="Time types test">
+  <confml:feature ref="FileFolderTest" name="File &amp; folder types test">
+    <confml:desc>Feature with file and folder setting types</confml:desc>
+    <confml:setting ref="FolderSetting" name="Folder setting" type="folder">
+      <confml:desc>A folder setting</confml:desc>
+      <confml:localPath/>
+      <confml:targetPath/>
+    </confml:setting>
+    <confml:setting ref="FileSetting" name="File setting" type="file">
+      <confml:desc>A file setting</confml:desc>
+      <confml:localPath/>
+      <confml:targetPath/>
+    </confml:setting>
+  </confml:feature>
+  <confml:data>
+    <confml:FileFolderTest>
+      <confml:FolderSetting>
+        <confml:localPath>default_folder</confml:localPath>
+        <confml:targetPath>default_target_folder/</confml:targetPath>
+      </confml:FolderSetting>
+      <confml:FileSetting>
+        <confml:localPath>default_file.txt</confml:localPath>
+        <confml:targetPath>default_target_folder/default_file_renamed.txt</confml:targetPath>
+      </confml:FileSetting>
+    </confml:FileFolderTest>
+  </confml:data>
+</confml:configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/testdata/schema/confml2/valid/name_id_mapping_test.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,151 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/2" name="Test features for testing name-ID mappings" version="1">
+    <feature ref="NameIdMappingTestSourceSequences" name="Source sequences for name-ID mappings">
+        <setting ref="StringSequence" name="String sequence" type="sequence" mapKey="Value" mapValue="Value">
+            <setting ref="Value" name="Value sub-setting" type="string"/>
+        </setting>
+        
+        <setting ref="StringToStringSequence" name="String-to-string sequence" type="sequence" mapKey="Name" mapValue="Value">
+            <setting ref="Name" name="Name sub-setting" type="string"/>
+            <setting ref="Value" name="Value sub-setting" type="string"/>
+        </setting>
+        
+        <setting ref="StringToIntSequence" name="String-to-int sequence" type="sequence" mapKey="Name" mapValue="Value">
+            <setting ref="Name" name="Name sub-setting" type="string"/>
+            <setting ref="Value" name="Value sub-setting" type="int"/>
+        </setting>
+        
+        <setting ref="StringToRealSequence" name="String-to-real sequence" type="sequence" mapKey="Name" mapValue="Value">
+            <setting ref="Name" name="Name sub-setting" type="string"/>
+            <setting ref="Value" name="Value sub-setting" type="real"/>
+        </setting>
+    </feature>
+
+
+    <feature ref="NameIdMappingTestTargetSettings" name="Target settings for name-ID mappings">
+        <setting ref="Selection" name="Selection setting" type="selection">
+            <option map="NameIdMappingTestSourceSequences/StringSequence"/>
+            <option name="None" value="none"/>
+        </setting>
+        
+        <setting ref="Selection2" name="Selection setting 2" type="selection">
+            <option map="NameIdMappingTestSourceSequences/StringToStringSequence"/>
+            <option name="None" value="none"/>
+        </setting>
+        
+        <setting ref="String" name="String setting" type="string">
+            <option map="NameIdMappingTestSourceSequences/StringSequence"/>
+            <option name="None" value=""/>
+        </setting>
+        
+        <setting ref="String2" name="String setting 2" type="string">
+            <option map="NameIdMappingTestSourceSequences/StringToStringSequence"/>
+            <option name="None" value=""/>
+        </setting>
+        
+        <setting ref="Int" name="Int setting" type="int">
+            <option map="NameIdMappingTestSourceSequences/StringToIntSequence"/>
+            <option name="Zero" value="0"/>
+        </setting>
+        
+        <setting ref="Real" name="Real setting" type="real">
+            <option map="NameIdMappingTestSourceSequences/StringToRealSequence"/>
+            <option name="Zero" value="0"/>
+        </setting>
+        
+        <setting ref="Sequence" name="Sequence" type="sequence">
+            <setting ref="Selection" name="Selection sub-setting" type="selection">
+                <option map="NameIdMappingTestSourceSequences/StringSequence"/>
+                <option name="None" value="none"/>
+            </setting>
+            
+            <setting ref="Selection2" name="Selection sub-setting 2" type="selection">
+                <option map="NameIdMappingTestSourceSequences/StringToStringSequence"/>
+                <option name="None" value="none"/>
+            </setting>
+            
+            <setting ref="String" name="String sub-setting" type="string">
+                <option map="NameIdMappingTestSourceSequences/StringSequence"/>
+                <option name="None" value=""/>
+            </setting>
+            
+            <setting ref="String2" name="String sub-setting 2" type="string">
+                <option map="NameIdMappingTestSourceSequences/StringToStringSequence"/>
+                <option name="None" value=""/>
+            </setting>
+            
+            <setting ref="Int" name="Int sub-setting" type="int">
+                <option map="NameIdMappingTestSourceSequences/StringToIntSequence"/>
+                <option name="Zero" value="0"/>
+            </setting>
+            
+            <setting ref="Real" name="Real sub-setting" type="real">
+                <option map="NameIdMappingTestSourceSequences/StringToRealSequence"/>
+                <option name="Zero" value="0"/>
+            </setting>
+        </setting>
+    </feature>
+
+    <data>
+        <NameIdMappingTestSourceSequences>
+            <StringSequence template="true">
+                <Value></Value>
+            </StringSequence>
+            <StringSequence><Value>Entry 1</Value></StringSequence>
+            <StringSequence><Value>Entry 2</Value></StringSequence>
+            <StringSequence><Value>Entry 3</Value></StringSequence>
+            
+            <StringToStringSequence template="true">
+                <Name></Name>
+                <Value></Value>
+            </StringToStringSequence>
+            <StringToStringSequence><Name>Entry 1</Name><Value>e 1</Value></StringToStringSequence>
+            <StringToStringSequence><Name>Entry 2</Name><Value>e 2</Value></StringToStringSequence>
+            <StringToStringSequence><Name>Entry 3</Name><Value>e 3</Value></StringToStringSequence>
+            
+            <StringToIntSequence template="true">
+                <Name></Name>
+                <Value></Value>
+            </StringToIntSequence>
+            <StringToIntSequence><Name>Entry 1</Name><Value>100</Value></StringToIntSequence>
+            <StringToIntSequence><Name>Entry 2</Name><Value>120</Value></StringToIntSequence>
+            <StringToIntSequence><Name>Entry 3</Name><Value>130</Value></StringToIntSequence>
+            
+            
+            <StringToRealSequence template="true">
+                <Name></Name>
+                <Value></Value>
+            </StringToRealSequence>
+            <StringToRealSequence><Name>Entry 1</Name><Value>1.1</Value></StringToRealSequence>
+            <StringToRealSequence><Name>Entry 2</Name><Value>1.2</Value></StringToRealSequence>
+            <StringToRealSequence><Name>Entry 3</Name><Value>1.3</Value></StringToRealSequence>
+        </NameIdMappingTestSourceSequences>
+        
+        
+        <NameIdMappingTestTargetSettings>
+            <Selection>none</Selection>
+            <Selection2>none</Selection2>
+            <String></String>
+            <String2></String2>
+            <Int>0</Int>
+            <Real>0</Real>
+            
+            <Sequence template="true">
+                <Selection>none</Selection>
+                <Selection2>none</Selection2>
+                <String></String>
+                <String2></String2>
+                <Int>0</Int>
+                <Real>0</Real>
+            </Sequence>
+            <Sequence>
+                <Selection>none</Selection>
+                <Selection2>none</Selection2>
+                <String></String>
+                <String2></String2>
+                <Int>0</Int>
+                <Real>0</Real>
+            </Sequence>
+        </NameIdMappingTestTargetSettings>
+    </data>
+</configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/testdata/schema/confml2/valid/product_root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="ASCII"?>
+<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2 http://www.w3.org/2001/XInclude http://www.s60.com/xml/confml/1#//include">
+  <xi:include href="assets/asset1/root.confml"/>
+  <xi:include href="assets/asset2/root.confml"/>
+  <xi:include href="family/root.confml"/>
+  <xi:include href="product/root.confml"/>
+</confml:configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/testdata/schema/confml2/valid/relevant_feature_test.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/2"
+               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+               xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2"
+               name="Relevant feature test">
+    <feature ref="RelevantFeatureTest" name="Relevant feature test" relevant="Feature1/StringSetting = 'test'">
+        <desc>Feature for testing attribute 'relevant' in a feature.</desc>
+        
+        <setting ref="RealSetting" name="Real setting" type="real">
+            <desc>A real setting</desc>
+        </setting>
+    
+        <setting ref="IntSetting" name="Int setting" type="int">
+            <desc>An int setting</desc>
+        </setting>
+    
+        <setting ref="StringSetting" name="String setting" type="string">
+            <desc>A string setting</desc>
+        </setting>
+    
+        <setting ref="BooleanSetting" name="Boolean setting" type="boolean">
+            <desc>A boolean setting</desc>
+        </setting>
+    
+        <setting ref="SelectionSetting" name="Selection setting" type="selection">
+            <desc>A selection setting</desc>
+            <option name="Option0" value="0"/>
+            <option name="Option1" value="1"/>
+            <option name="Option2" value="2"/>
+            <option name="Option3" value="3"/>
+            <option name="Option4" value="4"/>
+        </setting>
+    
+        <setting ref="MultiSelectionSetting" name="Multi-selection setting" type="multiSelection">
+            <desc>A multi-selection setting</desc>
+            <option name="Option 0" value="opt 0"/>
+            <option name="Option 1" value="opt 1"/>
+            <option name="Option 2" value="opt 2"/>
+            <option name="Option 3" value="opt 3"/>
+            <option name="Option 4" value="opt 4"/>
+        </setting>
+    
+        <setting ref="FolderSetting" name="Folder setting" type="folder">
+            <desc>A folder setting</desc>
+            <localPath/>
+            <targetPath/>
+        </setting>
+    
+        <setting ref="FileSetting" name="File setting" type="file">
+            <desc>A file setting</desc>
+            <localPath/>
+            <targetPath/>
+        </setting>
+    
+        <setting ref="SequenceSetting" name="Sequence setting" type="sequence">
+            <desc>A sequence setting</desc>
+
+            <setting ref="RealSubSetting" name="Real sub-setting" type="real">
+                <desc>A real sub-setting</desc>
+            </setting>
+
+            <setting ref="IntSubSetting" name="Int sub-setting" type="int">
+                <desc>An int sub-setting</desc>
+            </setting>
+
+            <setting ref="StringSubSetting" name="String sub-setting" type="string">
+                <desc>A string sub-setting</desc>
+            </setting>
+
+            <setting ref="BooleanSubSetting" name="Boolean sub-setting" type="boolean">
+                <desc>A boolean sub-setting</desc>
+            </setting>
+
+            <setting ref="SelectionSubSetting" name="Selection sub-setting" type="selection">
+                <desc>A selection sub-setting</desc>
+                <option name="Op0" value="0"/>
+                <option name="Op1" value="1"/>
+                <option name="Op2" value="2"/>
+                <option name="Op3" value="3"/>
+                <option name="Op4" value="4"/>
+            </setting>
+
+            <setting ref="MultiSelectionSubSetting" name="Multi-selection sub-setting" type="multiSelection">
+                <desc>A multi-selection sub-setting</desc>
+                <option name="Option 0" value="opt 0"/>
+                <option name="Option 1" value="opt 1"/>
+                <option name="Option 2" value="opt 2"/>
+                <option name="Option 3" value="opt 3"/>
+                <option name="Option 4" value="opt 4"/>
+            </setting>
+            
+            <setting ref="FolderSubSetting" name="Folder sub-setting" type="folder">
+                <desc>A folder sub-setting</desc>
+                <localPath/>
+                <targetPath/>
+            </setting>
+            
+            <setting ref="FileSubSetting" name="File sub-setting" type="file">
+                <desc>A file sub-setting</desc>
+                <localPath/>
+                <targetPath/>
+            </setting>
+        </setting>
+    </feature>
+  
+  <data>
+    <RelevantFeatureTest>
+        <RealSetting>3.14</RealSetting>
+        <IntSetting>10</IntSetting>
+        <StringSetting>default string</StringSetting>
+        <BooleanSetting>true</BooleanSetting>
+        <SelectionSetting>1</SelectionSetting>
+        <MultiSelectionSetting>"opt 0" "opt 2" "opt 4"</MultiSelectionSetting>
+        
+        <FolderSetting>
+            <localPath>default_folder</localPath>
+            <targetPath>default_target_folder/</targetPath>
+        </FolderSetting>
+        <FileSetting>
+            <localPath>default_file.txt</localPath>
+            <targetPath>default_target_folder/default_file_renamed.txt</targetPath>
+        </FileSetting>
+        
+        <SequenceSetting>
+            <RealSubSetting>1.25</RealSubSetting>
+            <IntSubSetting>128</IntSubSetting>
+            <StringSubSetting>def1</StringSubSetting>
+            <BooleanSubSetting>false</BooleanSubSetting>
+            <SelectionSubSetting>1</SelectionSubSetting>
+            <MultiSelectionSubSetting>"opt 1"</MultiSelectionSubSetting>
+            <FolderSubSetting><localPath>seq/def1_folder</localPath></FolderSubSetting>
+            <FileSubSetting><localPath>seq/def1_file.txt</localPath></FileSubSetting>
+        </SequenceSetting>
+    </RelevantFeatureTest>
+  </data>
+</configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/testdata/schema/confml2/valid/sequence_setting_test.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/2" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2" name="Basic setting types test">
+  <confml:feature ref="SequenceSettingTest" name="Sequence setting test">
+    <confml:desc>Feature with a sequence setting (ConfML v2.0)</confml:desc>
+    
+    <confml:setting ref="SequenceSetting" name="Sequence setting" type="sequence">
+      <confml:desc>A sequence setting</confml:desc>
+      
+      <confml:setting ref="FolderSubSetting" name="Folder sub-setting" type="folder">
+        <confml:desc>A folder sub-setting</confml:desc>
+        <confml:localPath/>
+        <confml:targetPath/>
+      </confml:setting>
+      
+      <confml:setting ref="RealSubSetting" name="Real sub-setting" type="real">
+        <confml:desc>A real sub-setting</confml:desc>
+      </confml:setting>
+      
+      <confml:setting ref="FileSubSetting" name="File sub-setting" type="file">
+        <confml:desc>A file sub-setting</confml:desc>
+        <confml:localPath/>
+        <confml:targetPath/>
+      </confml:setting>
+      
+      <confml:setting ref="IntSubSetting" name="Int sub-setting" type="int">
+        <confml:desc>An int sub-setting</confml:desc>
+      </confml:setting>
+      
+      <confml:setting ref="StringSubSetting" name="String sub-setting" type="string">
+        <confml:desc>A string sub-setting</confml:desc>
+      </confml:setting>
+      
+      <confml:setting ref="BooleanSubSetting" name="Boolean sub-setting" type="boolean">
+        <confml:desc>A boolean sub-setting</confml:desc>
+      </confml:setting>
+      
+      <confml:setting ref="SelectionSubSetting" name="Selection sub-setting" type="selection">
+        <confml:desc>A selection sub-setting</confml:desc>
+        <confml:option name="Op0" value="0"/>
+        <confml:option name="Op1" value="1"/>
+        <confml:option name="Op2" value="2"/>
+        <confml:option name="Op3" value="3"/>
+        <confml:option name="Op4" value="4"/>
+      </confml:setting>
+      
+      <confml:setting ref="MultiSelectionSubSetting" name="Multi-selection sub-setting" type="multiSelection">
+        <confml:desc>A multi-selection sub-setting</confml:desc>
+        <confml:option name="Option 0" value="opt 0"/>
+        <confml:option name="Option 1" value="opt 1"/>
+        <confml:option name="Option 2" value="opt 2"/>
+        <confml:option name="Option 3" value="opt 3"/>
+        <confml:option name="Option 4" value="opt 4"/>
+      </confml:setting>
+      
+      <confml:setting ref="DateSubSetting" name="Date sub-setting" type="date">
+        <confml:desc>A date sub-setting</confml:desc>
+      </confml:setting>
+      <confml:setting ref="TimeSubSetting" name="Time sub-setting" type="time">
+        <confml:desc>A time sub-setting</confml:desc>
+      </confml:setting>
+      <confml:setting ref="DateTimeSubSetting" name="Date-time sub-setting" type="dateTime">
+        <confml:desc>A date-time sub-setting</confml:desc>
+      </confml:setting>
+      <confml:setting ref="DurationSubSetting" name="Duration sub-setting" type="duration">
+        <confml:desc>A duration sub-setting</confml:desc>
+      </confml:setting>
+      
+    </confml:setting>
+  </confml:feature>
+  
+  <confml:data>
+    <confml:SequenceSettingTest>
+      <confml:SequenceSetting template="true">
+        <confml:FolderSubSetting><confml:localPath>seq/default_folder</confml:localPath></confml:FolderSubSetting>
+        <confml:RealSubSetting>1.0</confml:RealSubSetting>
+        <confml:FileSubSetting><confml:localPath>seq/default_file.txt</confml:localPath></confml:FileSubSetting>
+        <confml:IntSubSetting>1</confml:IntSubSetting>
+        <confml:StringSubSetting>template</confml:StringSubSetting>
+        <confml:BooleanSubSetting>false</confml:BooleanSubSetting>
+        <confml:SelectionSubSetting>0</confml:SelectionSubSetting>
+        <confml:MultiSelectionSubSetting>"opt 0"</confml:MultiSelectionSubSetting>
+        <confml:DateSubSetting>2009-02-02</confml:DateSubSetting>
+        <confml:TimeSubSetting>07:30:15</confml:TimeSubSetting>
+        <confml:DateTimeSubSetting>2009-02-02-07:00:00</confml:DateTimeSubSetting>
+        <confml:DurationSubSetting>P5Y4M3DT12H25M15S</confml:DurationSubSetting>
+      </confml:SequenceSetting>
+      <confml:SequenceSetting>
+        <confml:FolderSubSetting><confml:localPath>seq/def1_folder</confml:localPath></confml:FolderSubSetting>
+        <confml:RealSubSetting>1.25</confml:RealSubSetting>
+        <confml:FileSubSetting><confml:localPath>seq/def1_file.txt</confml:localPath></confml:FileSubSetting>
+        <confml:IntSubSetting>128</confml:IntSubSetting>
+        <confml:StringSubSetting>def1</confml:StringSubSetting>
+        <confml:BooleanSubSetting>false</confml:BooleanSubSetting>
+        <confml:SelectionSubSetting>1</confml:SelectionSubSetting>
+        <confml:MultiSelectionSubSetting>"opt 1"</confml:MultiSelectionSubSetting>
+        <confml:DateSubSetting>2009-02-02</confml:DateSubSetting>
+        <confml:TimeSubSetting>07:30:15</confml:TimeSubSetting>
+        <confml:DateTimeSubSetting>2009-02-02-07:00:00</confml:DateTimeSubSetting>
+        <confml:DurationSubSetting>P5Y4M3DT12H25M15S</confml:DurationSubSetting>
+      </confml:SequenceSetting>
+      <confml:SequenceSetting>
+        <confml:FolderSubSetting><confml:localPath>seq/def2_folder</confml:localPath></confml:FolderSubSetting>
+        <confml:RealSubSetting>1.5</confml:RealSubSetting>
+        <confml:FileSubSetting><confml:localPath>seq/def2_file.txt</confml:localPath></confml:FileSubSetting>
+        <confml:IntSubSetting>256</confml:IntSubSetting>
+        <confml:StringSubSetting>def2</confml:StringSubSetting>
+        <confml:BooleanSubSetting>false</confml:BooleanSubSetting>
+        <confml:SelectionSubSetting>1</confml:SelectionSubSetting>
+        <confml:MultiSelectionSubSetting>"opt 2"</confml:MultiSelectionSubSetting>
+        <confml:DateSubSetting>2009-02-02</confml:DateSubSetting>
+        <confml:TimeSubSetting>07:30:15</confml:TimeSubSetting>
+        <confml:DateTimeSubSetting>2009-02-02-07:00:00</confml:DateTimeSubSetting>
+        <confml:DurationSubSetting>P5Y4M3DT12H25M15S</confml:DurationSubSetting>
+      </confml:SequenceSetting>
+    </confml:SequenceSettingTest>
+  </confml:data>
+</confml:configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/testdata/schema/confml2/valid/time_types_test.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/2" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2" name="Time types test">
+  <confml:feature ref="TimeTypesTest" name="Time types test">
+    <confml:desc>Feature with date-time etc. setting types</confml:desc>
+    <confml:setting ref="DateSetting" name="Date setting" type="date">
+      <confml:desc>A date setting</confml:desc>
+    </confml:setting>
+    <confml:setting ref="TimeSetting" name="Time setting" type="time">
+      <confml:desc>A time setting</confml:desc>
+    </confml:setting>
+    <confml:setting ref="DateTimeSetting" name="Date-time setting" type="dateTime">
+      <confml:desc>A date-time setting</confml:desc>
+    </confml:setting>
+    <confml:setting ref="DurationSetting" name="Duration setting" type="duration">
+      <confml:desc>A duration setting</confml:desc>
+    </confml:setting>
+  </confml:feature>
+  <confml:data>
+    <confml:TimeTypesTest>
+      <confml:DateSetting>2009-02-02</confml:DateSetting>
+      <confml:TimeSetting>07:30:15</confml:TimeSetting>
+      <confml:DateTimeSetting>2009-02-02-07:00:00</confml:DateTimeSetting>
+      <confml:DurationSetting>P5Y4M3DT12H25M15S</confml:DurationSetting>
+    </confml:TimeTypesTest>
+  </confml:data>
+</confml:configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/testdata/schema/confml2/valid/view.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/2" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2">
+  <confml:view name="Layer 1 view">
+    <confml:desc>Testing view located on layer 1.</confml:desc>
+    <confml:group name="ConfML v1.0 settings">
+      <confml:setting ref="Feature1/RealSetting"/>
+      <confml:setting ref="Feature1/IntSetting"/>
+      <confml:setting ref="Feature1/StringSetting"/>
+      <confml:setting ref="Feature1/BooleanSetting"/>
+      <confml:setting ref="Feature1/SelectionSetting"/>
+      <confml:setting ref="Feature1/SequenceSetting"/>
+      <confml:setting ref="Feature2/SequenceSetting"/>
+    </confml:group>
+    <confml:group name="ConfML v2.0 settings">
+      <confml:setting ref="BasicSettingTypesTest/RealSetting"/>
+      <confml:setting ref="BasicSettingTypesTest/IntSetting"/>
+      <confml:setting ref="BasicSettingTypesTest/StringSetting"/>
+      <confml:setting ref="BasicSettingTypesTest/BooleanSetting"/>
+      <confml:setting ref="BasicSettingTypesTest/SelectionSetting"/>
+      <confml:setting ref="FileFolderTest/FolderSetting"/>
+      <confml:setting ref="FileFolderTest/FileSetting"/>
+      <confml:setting ref="SequenceSettingTest/SequenceSetting"/>
+    </confml:group>
+    
+    
+    <confml:group name="Settings for testing attribute 'relevant'">
+        <confml:group name="In options">
+            <confml:setting ref="RelevantOptionTest/*"/>
+        </confml:group>
+        <confml:group name="In settings">
+            <confml:setting ref="RelevantSettingTest/*"/>
+        </confml:group>
+        <confml:group name="In a feature">
+            <confml:setting ref="RelevantFeatureTest/*"/>
+        </confml:group>
+    </confml:group>
+    
+    <confml:group name="Settings for testing Name-ID mapping">
+        <confml:group name="Source sequences">
+            <confml:setting ref="NameIdMappingTestSourceSequences/*"/>
+        </confml:group>
+        <confml:group name="Target settings">
+            <confml:setting ref="NameIdMappingTestTargetSettings/*"/>
+        </confml:group>
+    </confml:group>
+    
+    <confml:group name="Settings for testing options">
+        <confml:setting ref="OptionTest/*"/>
+    </confml:group>
+    
+    <confml:group name="Settings for testing redefining things in views">
+        <confml:group name="Redefining name and description">
+            <confml:setting ref="RedefineInViewTest/NameAndDescRedefinition" name="Name from view">
+                <confml:desc>Description from view</confml:desc>
+            </confml:setting>
+        </confml:group>
+        
+        <confml:group name="Redefining options">
+            <confml:setting ref="RedefineInViewTest/IntWithOptions">
+                <confml:option name="Small value" value="2"/>
+                <confml:option name="Large value" value="200"/>
+                <confml:option name="Huge value" value="1000000"/>
+            </confml:setting>
+            
+            <confml:setting ref="RedefineInViewTest/RealWithOptions">
+                <confml:option name="Small value" value="0.002"/>
+                <confml:option name="Large value" value="20"/>
+                <confml:option name="Microscopic value" value="1e-9"/>
+            </confml:setting>
+            
+            <confml:setting ref="RedefineInViewTest/StringWithOptions">
+                <confml:option name="UTF-8" value="utf8"/>
+                <confml:option name="UTF-16" value="utf16"/>
+                <confml:option name="Latin-1" value="iso-8859-1"/>
+            </confml:setting>
+        </confml:group>
+    </confml:group>
+
+    
+  </confml:view>
+</confml:configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/testdata/schema/implml/invalid/empty_temp_variable_sequence.implml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<container xmlns="http://www.symbianfoundation.org/xml/implml/1">
+    <tempVariableSequence ref="Foo.Bar.Seq">
+    </tempVariableSequence>
+</container>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/testdata/schema/implml/invalid/output_root_dir_without_value.implml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<container xmlns="http://www.symbianfoundation.org/xml/implml/1">
+    <outputRootDir/>
+</container>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/testdata/schema/implml/invalid/output_sub_dir_without_value.implml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<container xmlns="http://www.symbianfoundation.org/xml/implml/1">
+    <outputSubDir/>
+</container>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/testdata/schema/implml/invalid/phase_without_value.implml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<container xmlns="http://www.symbianfoundation.org/xml/implml/1">
+    <phase/>
+</container>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/testdata/schema/implml/invalid/setting_refs_override_without_value.implml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<container xmlns="http://www.symbianfoundation.org/xml/implml/1">
+    <settingRefsOverride>
+        <settingRef/>
+    </settingRefsOverride>
+</container>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/testdata/schema/implml/invalid/tag_without_value.implml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<container xmlns="http://www.symbianfoundation.org/xml/implml/1">
+    <tag/>
+</container>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/testdata/schema/implml/invalid/temp_variable_sequence_without_ref.implml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<container xmlns="http://www.symbianfoundation.org/xml/implml/1">
+    <tempVariableSequence>
+        <tempVariable ref="Sub1" type="int"/>
+        <tempVariable ref="Sub2"/>
+    </tempVariableSequence>
+</container>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/testdata/schema/implml/invalid/temp_variable_without_ref.implml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<container xmlns="http://www.symbianfoundation.org/xml/implml/1">
+    <tempVariable type="string" value="test"/>
+</container>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/testdata/schema/implml/valid/dummy.dummy1ml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<dummy1 xmlns="http://www.dummy.com/dummy1">
+    <myElem>jee</myElem>
+</dummy1>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/testdata/schema/implml/valid/dummy.dummy2ml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<dummy2 xmlns="http://www.dummy.com/dummy2">
+    <someElem>jee</someElem>
+</dummy2>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/testdata/schema/implml/valid/empty.implml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<container xmlns="http://www.symbianfoundation.org/xml/implml/1"/>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/testdata/schema/implml/valid/empty_with_all_common_elements.implml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<container xmlns="http://www.symbianfoundation.org/xml/implml/1">
+    <phase name="pre"/>
+    
+    <tag name="target" value="uda"/>
+    <tag name="target" value="uda"/>
+    
+    <settingRefsOverride>
+        <settingRef value="Foo.Bar"/>
+    </settingRefsOverride>
+    
+    <tempVariable ref="Foo.Bar1" type="int" value="5"/>
+    <tempVariable ref="Foo.Bar2" type="real"/>
+    <tempVariable ref="Foo.Bar3"/>
+    
+    <tempVariableSequence ref="Foo.Bar.Seq1">
+        <tempVariable ref="Sub1" type="int"/>
+        <tempVariable ref="Sub2"/>
+    </tempVariableSequence>
+    <tempVariableSequence ref="Foo.Bar.Seq2">
+        <tempVariable ref="Sub1" type="int"/>
+        <tempVariable ref="Sub2"/>
+    </tempVariableSequence>
+    
+    <outputRootDir value="foo/bar"/>
+    <outputSubDir value="sub_foo"/>
+</container>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/testdata/schema/implml/valid/empty_with_condition.implml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<container xmlns="http://www.symbianfoundation.org/xml/implml/1" condition="${Foo.Bar}"/>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/testdata/schema/implml/valid/empty_with_condition_and_value.implml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<container xmlns="http://www.symbianfoundation.org/xml/implml/1" condition="${Foo.Bar}" value="false"/>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/testdata/schema/implml/valid/multi_impl_1.implml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<container xmlns="http://www.symbianfoundation.org/xml/implml/1">
+    <dummy1 xmlns="http://www.dummy.com/dummy1">
+        <myElem>jee</myElem>
+    </dummy1>
+    
+    <dummy2 xmlns="http://www.dummy.com/dummy2">
+        <someElem>jee</someElem>
+    </dummy2>
+</container>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/testdata/schema/implml/valid/multi_impl_2.implml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<container xmlns="http://www.symbianfoundation.org/xml/implml/1">
+    <dummy2 xmlns="http://www.dummy.com/dummy2">
+        <someElem>jee</someElem>
+    </dummy2>
+    
+    <dummy1 xmlns="http://www.dummy.com/dummy1">
+        <myElem>jee</myElem>
+    </dummy1>
+</container>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/testdata/schema/implml/valid/multi_impl_3.implml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<container xmlns="http://www.symbianfoundation.org/xml/implml/1">
+    <dummy1 xmlns="http://www.dummy.com/dummy1">
+        <myElem>jee</myElem>
+    </dummy1>
+	
+	<dummy1 xmlns="http://www.dummy.com/dummy1">
+        <myElem>jee2</myElem>
+    </dummy1>
+</container>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/testdata/schema/implml/valid/multi_impl_4.implml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<container xmlns="http://www.symbianfoundation.org/xml/implml/1">
+    <dummy2 xmlns="http://www.dummy.com/dummy2">
+        <someElem>jee</someElem>
+    </dummy2>
+</container>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/testdata/schema/implml/valid/multi_impl_5.implml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<container xmlns="http://www.symbianfoundation.org/xml/implml/1">
+    <dummy2 xmlns="http://www.dummy.com/dummy2">
+        <someElem>jee</someElem>
+    </dummy2>
+    
+    <dummy1 xmlns="http://www.dummy.com/dummy1">
+        <myElem>jee</myElem>
+    </dummy1>
+    
+    <dummy2 xmlns="http://www.dummy.com/dummy2">
+        <someElem>joojaa</someElem>
+    </dummy2>
+</container>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/testdata/schema/implml/valid/nested_containers.implml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<container xmlns="http://www.symbianfoundation.org/xml/implml/1">
+    <tag name="target" value="foo"/>
+    
+    <container condition="${Foo.Bar}">
+        <phase name="pre"/>
+        
+        <dummy1 xmlns="http://www.dummy.com/dummy1">
+            <myElem>jee</myElem>
+        </dummy1>
+        
+        <dummy2 xmlns="http://www.dummy.com/dummy2">
+            <someElem>nested dummy 2</someElem>
+        </dummy2>
+    </container>
+    
+    <container condition="${Foo.Bar2}" value="test">
+        <phase name="normal"/>
+        
+        <dummy1 xmlns="http://www.dummy.com/dummy1">
+            <myElem>jee</myElem>
+        </dummy1>
+        
+        <container>
+            <outputSubDir value="foosub"/>
+            
+            <dummy1 xmlns="http://www.dummy.com/dummy1">
+                <myElem>still more nesting</myElem>
+            </dummy1>
+        </container>
+    </container>
+    
+    <dummy2 xmlns="http://www.dummy.com/dummy2">
+        <someElem>jee</someElem>
+    </dummy2>
+</container>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/unittest_confmlfixing.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,79 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+import os
+import unittest
+import logging
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+TESTDATA_DIR = os.path.join(ROOT_PATH, 'testdata')
+TEMP_DIR = os.path.join(ROOT_PATH, 'temp')
+
+from testautomation.base_testcase import BaseTestCase
+from cone.public import api
+import cone.validation.confmlvalidation
+
+class TestConfmlFixing(unittest.TestCase):
+    def test_confml_fixer_filter_problems(self):
+        fixer = cone.validation.confmlvalidation.FixerBase()
+        prbs = [api.Problem("msg1", type="test.foo.bar"),
+                api.Problem("msg2", type="test.foo.bar"),
+                api.Problem("msg3", type="test.foo.faa"),
+                api.Problem("msg4", type="test.foo.bar")]
+        self.assertEquals(len(fixer.filter_problems(prbs,'test.foo.bar')),3)
+
+    def test_get_fixer_classes(self):
+        fixers = cone.validation.confmlvalidation.get_fixer_classes()
+        self.assertEquals(len(fixers),1)
+
+class TestConfmlFixModel(BaseTestCase):
+    def test_fix_duplicates(self):
+        prj_dir = os.path.join(TESTDATA_DIR, 'model/confml/single_files')
+        prj = api.Project(api.Storage.open(prj_dir))
+        conf = prj.get_configuration("duplicate_root.confml")
+        vc = cone.validation.confmlvalidation.fix_configuration(conf)
+        self.assertEqual(len(vc.fixes), 1)
+        self.assertEquals(conf.list_configurations(),['duplicate_settings1.confml', 
+                                                      'duplicate_settings2.confml'])
+        subconf1 = conf.get_configuration('duplicate_settings1.confml')
+        subconf2 = conf.get_configuration('duplicate_settings2.confml')
+        self.assertEquals(subconf2.list_all_features(),[])
+        self.assertEquals(subconf1.list_all_features(),['Feature', 
+                                                        'Feature.One', 
+                                                        'Feature.Two', 
+                                                        'Feature.Three', 
+                                                        'Feature.NoData',
+                                                        'Feature.TestSequence', 
+                                                        'Feature.TestSequence.SeqTwo', 
+                                                        'Feature.TestSequence.SeqThree'])
+
+class TestConfmlFixingFiles(BaseTestCase):
+        
+    def test_export_fixed_configuration_test(self):
+        # Open the file as a configuration
+        prj_dir = os.path.join(TESTDATA_DIR, 'model/confml/single_files')
+        prj = api.Project(api.Storage.open(prj_dir))
+        conf = prj.get_configuration('duplicate_root.confml')
+        vc = cone.validation.confmlvalidation.fix_configuration(conf)
+        self.recreate_dir(os.path.join(TEMP_DIR,'fixed'))
+        rstorage = api.Storage.open(os.path.join(TEMP_DIR,'fixed'), "w")
+        prj.export_configuration(conf, rstorage)
+        rstorage.save()
+        rstorage.close()
+        self.assert_dir_contents_equal(os.path.join(TEMP_DIR,'fixed'),
+                                       os.path.join(TESTDATA_DIR, 'model/confml/fixed_expected'),
+                                       ignore=[".metadata", '.svn'])
+        
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/unittest_confmlvalidation.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,51 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+import os
+import unittest
+import logging
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+TESTDATA_DIR = os.path.join(ROOT_PATH, 'testdata')
+TEMP_DIR = os.path.join(ROOT_PATH, 'temp')
+
+from testautomation.base_testcase import BaseTestCase
+from cone.public import api
+import cone.validation.confmlvalidation
+
+
+class TestConfmlValidation(BaseTestCase):
+        
+    def _run_single_file_test(self, filename):
+        # Open the file as a configuration
+        prj_dir = os.path.join(TESTDATA_DIR, 'model/confml/single_files')
+        prj = api.Project(api.Storage.open(prj_dir))
+        conf = prj.get_configuration(filename)
+        
+        self.assert_problem_list_equals_expected(
+            actual = cone.validation.confmlvalidation.validate_configuration(conf).problems,
+            expected_file = os.path.join(TESTDATA_DIR, 'model/confml/single_files_expected', filename + '.txt'),
+            outdir = os.path.join(TEMP_DIR, 'confml_model_single_files', filename))
+    
+    def test_validate_min_max_length(self):
+        self._run_single_file_test('min_max_length.confml')
+    
+    def test_validate_data_without_feature(self):
+        self._run_single_file_test('data_without_feature.confml')
+
+    def test_validate_duplicates(self):
+        self._run_single_file_test('duplicate_root.confml')
+    
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/unittest_implmlvalidation.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,46 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+import os
+import __init__
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+TESTDATA_DIR = os.path.join(ROOT_PATH, 'testdata')
+TEMP_DIR = os.path.join(ROOT_PATH, 'temp')
+
+from testautomation.base_testcase import BaseTestCase
+from cone.public import api
+import cone.validation.implmlvalidation
+
+class TestImplmlValidation(BaseTestCase):
+    
+    def _run_test(self, filename):
+        filepath = 'Layer1/implml/' + filename
+        project_dir = os.path.join(ROOT_PATH, 'testdata/model/implml/project')
+        config      = 'root.confml'
+        
+        prj = api.Project(api.Storage.open(project_dir))
+        config = prj.get_configuration(config)
+        problems = cone.validation.implmlvalidation.validate_impls(config, filter=filepath + '$')
+        
+        self.assert_problem_list_equals_expected(
+            actual = problems,
+            expected_file = os.path.join(ROOT_PATH, 'testdata/model/implml/expected', filename + '.txt'),
+            outdir = os.path.join(ROOT_PATH, 'temp/implml_model', filename))
+    
+    def test_validate_duplicate_tempvar_refs(self):
+        self._run_test('duplicate_tempvar_ref.implml')
+    
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/unittest_problem_type_filter.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,135 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+import unittest
+
+from cone.public import api
+from cone.validation.problem_type_filter import ProblemTypeFilter
+
+class TestProblemTypeFilter(unittest.TestCase):
+    def test_empty_matches_everything(self):
+        filter = ProblemTypeFilter([], [])
+        self.assertTrue(filter.match(''))
+        self.assertTrue(filter.match('foo'))
+        self.assertTrue(filter.match('foo.bar'))
+        self.assertTrue(filter.match('foo.bar.baz'))
+    
+    def test_single_include(self):
+        filter = ProblemTypeFilter(['foo.bar'], [])
+        self.assertFalse(filter.match(''))
+        self.assertFalse(filter.match('foo'))
+        self.assertTrue(filter.match('foo.bar'))
+        self.assertTrue(filter.match('foo.bar.baz'))
+        self.assertFalse(filter.match('bar'))
+    
+    def test_single_exclude(self):
+        filter = ProblemTypeFilter([], ['foo.bar'])
+        self.assertTrue(filter.match(''))
+        self.assertTrue(filter.match('foo'))
+        self.assertTrue(filter.match('bar'))
+        self.assertFalse(filter.match('foo.bar'))
+        self.assertFalse(filter.match('foo.bar.baz'))
+    
+    def test_include_and_exclude(self):
+        filter = ProblemTypeFilter(['foo'], ['foo.bar.baz'])
+        self.assertFalse(filter.match(''))
+        self.assertTrue(filter.match('foo'))
+        self.assertFalse(filter.match('bar'))
+        self.assertTrue(filter.match('foo.bar'))
+        self.assertFalse(filter.match('foo.bar.baz'))
+        self.assertFalse(filter.match('foo.bar.baz.x'))
+    
+    def test_multiple_includes_and_excludes(self):
+        filter = ProblemTypeFilter(['foo', 'boo'], ['foo.bar.baz', 'boo.bar.baz'])
+        
+        self.assertFalse(filter.match(''))
+        self.assertFalse(filter.match('bar'))
+        
+        self.assertTrue(filter.match('foo'))
+        self.assertTrue(filter.match('foo.bar'))
+        self.assertFalse(filter.match('foo.bar.baz'))
+        self.assertFalse(filter.match('foo.bar.baz.x'))
+        
+        self.assertTrue(filter.match('boo'))
+        self.assertTrue(filter.match('boo.bar'))
+        self.assertFalse(filter.match('boo.bar.baz'))
+        self.assertFalse(filter.match('boo.bar.baz.x'))
+    
+    def test_wildcard_in_include(self):
+        filter = ProblemTypeFilter(['*.bar'], [])
+        
+        self.assertFalse(filter.match('foo'))
+        self.assertFalse(filter.match('boo'))
+        self.assertFalse(filter.match('foo.baz.bar'))
+        
+        self.assertTrue(filter.match('foo.bar'))
+        self.assertTrue(filter.match('foo.bar.baz'))
+        self.assertTrue(filter.match('boo.bar'))
+        self.assertTrue(filter.match('boo.bar.baz'))
+        
+        
+        filter = ProblemTypeFilter(['*.*.baz'], [])
+        self.assertTrue(filter.match('foo.bar.baz'))
+        self.assertTrue(filter.match('boo.bar.baz'))
+        
+        self.assertFalse(filter.match('baz'))
+        self.assertFalse(filter.match('foo.baz'))
+    
+    def test_wildcard_in_exclude(self):
+        filter = ProblemTypeFilter([], ['*.bar'])
+        
+        self.assertTrue(filter.match('foo'))
+        self.assertTrue(filter.match('boo'))
+        self.assertTrue(filter.match('foo.baz.bar'))
+        
+        self.assertFalse(filter.match('foo.bar'))
+        self.assertFalse(filter.match('foo.bar.baz'))
+        self.assertFalse(filter.match('boo.bar'))
+        self.assertFalse(filter.match('boo.bar.baz'))
+        
+        
+        filter = ProblemTypeFilter([], ['*.*.baz'])
+        self.assertFalse(filter.match('foo.bar.baz'))
+        self.assertFalse(filter.match('boo.bar.baz'))
+        
+        self.assertTrue(filter.match('baz'))
+        self.assertTrue(filter.match('foo.baz'))
+    
+    def test_filter_problems(self):
+        filter = ProblemTypeFilter(['foo'], ['foo.bar.baz'])
+        problems = [api.Problem('', type=''),
+                    api.Problem('', type='foo'),
+                    api.Problem('', type='bar'),
+                    api.Problem('', type='foo.bar'),
+                    api.Problem('', type='foo.bar.baz'),
+                    api.Problem('', type='foo.bar.baz.x')]
+        
+        filtered_problems = filter.filter(problems)
+        self.assertEquals(filtered_problems,
+                          [api.Problem('', type='foo'),
+                           api.Problem('', type='foo.bar')])
+
+    def test_filter_strings(self):
+        filter = ProblemTypeFilter(['foo'], ['foo.bar.baz'])
+        problems = ['',
+                   'foo',
+                   'bar',
+                   'foo.bar',
+                   'foo.bar.baz',
+                   'foo.bar.baz.x']
+        
+        filtered_problems = filter.filter(problems, key=lambda item: item)
+        self.assertEquals(filtered_problems, ['foo', 'foo.bar'])
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/validation/tests/unittest_schemavalidation.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,192 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+import unittest
+import os
+import StringIO
+
+from testautomation.base_testcase import BaseTestCase
+from cone.public import api, plugin, utils, exceptions
+from cone.validation import schemavalidation 
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+CONFML1_NAMESPACE = 'http://www.s60.com/xml/confml/1'
+CONFML2_NAMESPACE = 'http://www.s60.com/xml/confml/2'
+
+class DummyResource(object):
+    def __init__(self, data):
+        self.data = data
+    def read(self):
+        return self.data
+    def close(self):
+        pass
+
+class DummyConfiguration(object):
+    def __init__(self, resources):
+        self.resources = resources
+    
+    def get_resource(self, ref):
+        if ref in self.resources:
+            return DummyResource(self.resources[ref])
+        else:
+            raise exceptions.NotFound("No such resource '%s'!" % ref)
+
+class TestConfmlSchemaValidation(BaseTestCase, schemavalidation.SchemaValidationTestMixin):
+    
+    def test_valid_confml2_files(self):
+        self.assert_schemavalidation_succeeds(
+            type = 'confml',
+            dir = os.path.join(ROOT_PATH, 'testdata/schema/confml2/valid'),
+            namespace = CONFML2_NAMESPACE)
+    
+    def test_invalid_confml2_files(self):
+        self.assert_schemavalidation_fails(
+            type = 'confml',
+            dir = os.path.join(ROOT_PATH, 'testdata/schema/confml2/invalid'),
+            namespace = CONFML2_NAMESPACE)
+    
+    def test_valid_confml1_files(self):
+        self.assert_schemavalidation_succeeds(
+            type = 'confml',
+            dir = os.path.join(ROOT_PATH, 'testdata/schema/confml1/valid'),
+            namespace = CONFML1_NAMESPACE)
+    
+    def test_invalid_confml1_files(self):
+        self.assert_schemavalidation_fails(
+            type = 'confml',
+            dir = os.path.join(ROOT_PATH, 'testdata/schema/confml1/invalid'),
+            namespace = CONFML1_NAMESPACE)
+    
+    def test_validate_confml_invalid_xml_data(self):
+        config = DummyConfiguration({'foo.confml': 'foo'})
+        problems = schemavalidation.validate_confml_file(config, 'foo.confml')
+        self.assertEquals(len(problems), 1)
+        prob = problems[0]
+        #self.assertEquals(prob.type, api.Problem.TYPE_XML_PROBLEM)
+        self.assertEquals(prob.severity, api.Problem.SEVERITY_ERROR)
+        self.assertEquals(prob.line, 1)
+    
+    def test_validate_confml_invalid_xml_data_but_valid_root(self):
+        REF = 'test.confml'
+        DATA = """<?xml version="1.0" encoding="UTF-8"?>
+            <configuration xmlns="http://www.s60.com/xml/confml/2">
+            <test someattr/>
+            </configuration>""".encode('utf-8')
+        config = DummyConfiguration({REF: DATA})
+        problems = schemavalidation.validate_confml_file(config, REF)
+        self.assertEquals(len(problems), 1)
+        prob = problems[0]
+        #self.assertEquals(prob.type, api.Problem.TYPE_XML_PROBLEM)
+        self.assertEquals(prob.severity, api.Problem.SEVERITY_ERROR)
+        self.assertEquals(prob.line, 3)
+    
+    def test_validate_confml_unsupported_namespace(self):
+        DATA = """<?xml version="1.0" encoding="UTF-8"?>
+            <unsupported xmlns="http://www.test.com/xml/unsupported">
+                <test someattr="yay"/>
+            </unsupported>""".encode('utf-8')
+        self.assertRaises(exceptions.ConfmlParseError, schemavalidation.validate_confml_data, DATA)
+
+
+
+
+class TestImplmlSchemaValidation(BaseTestCase, schemavalidation.SchemaValidationTestMixin):
+    
+    DUMMY1_XSD_DATA = """<?xml version="1.0" encoding="UTF-8"?>
+    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+               targetNamespace="http://www.dummy.com/dummy1"
+               elementFormDefault="qualified">
+        
+        <xs:element name="dummy1">
+            <xs:complexType>
+                <xs:choice minOccurs="0" maxOccurs="unbounded">
+                    <xs:element name="myElem" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+                </xs:choice>
+            </xs:complexType>
+        </xs:element>
+    </xs:schema>"""
+    
+    DUMMY2_XSD_DATA = """<?xml version="1.0" encoding="UTF-8"?>
+    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+               targetNamespace="http://www.dummy.com/dummy2"
+               elementFormDefault="qualified">
+        
+        <xs:element name="dummy2">
+            <xs:complexType>
+                <xs:choice minOccurs="0" maxOccurs="unbounded">
+                    <xs:element name="someElem" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+                </xs:choice>
+            </xs:complexType>
+        </xs:element>
+    </xs:schema>"""
+    
+    def setUp(self):
+        class MockReader1(plugin.ReaderBase):
+            NAMESPACE = "http://www.dummy.com/dummy1"
+            NAMESPACE_ID = "dummy1ml"
+            FILE_EXTENSIONS = ['dummy1ml']
+            ROOT_ELEMENT_NAME = 'dummy1'
+            @classmethod
+            def get_schema_data(cls):
+                return self.DUMMY1_XSD_DATA
+        class MockReader2(plugin.ReaderBase):
+            NAMESPACE = "http://www.dummy.com/dummy2"
+            NAMESPACE_ID = "dummy2ml"
+            FILE_EXTENSIONS = ['dummy2ml']
+            ROOT_ELEMENT_NAME = 'dummy2'
+            @classmethod
+            def get_schema_data(cls):
+                return self.DUMMY2_XSD_DATA
+        class MockReader3(plugin.ReaderBase):
+            NAMESPACE = "http://www.dummy.com/dummy3"
+            NAMESPACE_ID = "dummy3ml"
+            FILE_EXTENSIONS = ['dummy3ml']
+            ROOT_ELEMENT_NAME = 'dummy3'
+        plugin.ImplFactory.set_reader_classes_override([MockReader1, MockReader2, MockReader3])
+    
+    def tearDown(self):
+        plugin.ImplFactory.set_reader_classes_override(None)
+    
+    def test_valid_implml_files(self):
+        self.assert_schemavalidation_succeeds(
+            type = 'implml',
+            dir = os.path.join(ROOT_PATH, 'testdata/schema/implml/valid'))
+    
+    def test_invalid_implml_files(self):
+        self.assert_schemavalidation_fails(
+            type = 'implml',
+            dir = os.path.join(ROOT_PATH, 'testdata/schema/implml/invalid'))
+    
+    def test_validate_implml_invalid_xml_data(self):
+        self.assertRaises(exceptions.XmlParseError, schemavalidation.validate_implml_data, "foo")
+    
+    def test_validate_implml_invalid_xml_data_but_valid_root(self):
+        DATA = """<?xml version="1.0" encoding="UTF-8"?>
+            <implml>
+            <test someattr/>
+            </implml>""".encode('utf-8')
+        self.assertRaises(exceptions.ImplmlParseError, schemavalidation.validate_implml_data, DATA)
+    
+    def test_validate_implml_unsupported_namespace(self):
+        DATA = """<?xml version="1.0" encoding="UTF-8"?>
+            <unsupported xmlns="http://www.test.com/xml/unsupported">
+                <test someattr="yay"/>
+            </unsupported>""".encode('utf-8')
+        self.assertRaises(exceptions.ImplmlParseError, schemavalidation.validate_implml_data, DATA)
+
+if __name__ == '__main__':
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/dev-tools/depfea.cmd	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,94 @@
+@rem
+@rem Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+@rem All rights reserved.
+@rem This component and the accompanying materials are made available
+@rem under the terms of "Eclipse Public License v1.0"
+@rem which accompanies this distribution, and is available
+@rem at the URL "http://www.eclipse.org/legal/epl-v10.html".
+@rem
+@rem Initial Contributors:
+@rem Nokia Corporation - initial contribution.
+@rem
+@rem Contributors:
+@rem
+@rem Description:
+@rem
+
+:: ============================================================================
+::  Name        : depfea.cmd
+::  Part of     : depfea
+::  Description : depfea tool wrapper for Windows
+::  Version     : %version: 1 %
+::
+:: ============================================================================
+
+
+
+@echo off
+setlocal
+
+set CONE_CMDARG=%*
+set BASEDIR=%~dp0
+set CONE_BASEDIR=%BASEDIR%configurationengine\win\
+set PYTHONCASEOK=1
+
+if not exist "%CONE_BASEDIR%" (
+echo Cannot run ConE, the ConE base directory does not exist:
+echo %CONE_BASEDIR%
+exit /b 1
+)
+
+@rem Check that Python is available
+call python -c None >nul 2>&1
+if %errorlevel% neq 0 (
+echo Python is required to run ConE!
+exit /b 1
+)
+
+@REM Find out Python version
+FOR /F "tokens=*" %%i in ('PYTHON -c "import sys; sys.stdout.write(sys.version[:3])"') do SET VER1=%%i
+
+@REM Set the used base directory based on the version
+if %VER1%==2.5 (
+set CONE_BASEDIR=%CONE_BASEDIR%2.5\
+goto EndVersionCheck
+)
+if %VER1%==2.6 (
+set CONE_BASEDIR=%CONE_BASEDIR%2.6\
+goto EndVersionCheck
+)
+echo You are using an unsupported Python version (%VER1%)
+echo ConE requires Python 2.5 or 2.6
+exit /b 1
+)
+:EndVersionCheck
+
+@rem Check that this ConE installation supports the Python version
+if not exist "%CONE_BASEDIR%" (
+echo Python version %VER1% is not supported by this ConE installation
+exit /b 1
+)
+
+@rem Set the egg cache dir to be unique to avoid egg extraction clashes
+@rem when running multiple parallel ConE instances
+FOR /F "tokens=*" %%i in ('PYTHON -c "import tempfile; d = tempfile.mkdtemp(); print d"') do SET EGG_CACHE_DIR=%%i
+@rem echo Egg cache dir: %EGG_CACHE_DIR%
+set PYTHON_EGG_CACHE=%EGG_CACHE_DIR%
+
+@rem Set environment variables and run deprfea.py
+set CONE_LIBDIR=%CONE_BASEDIR%\lib
+set CONE_SCRIPTDIR=%CONE_BASEDIR%\scripts
+set PATH=%CONE_SCRIPTDIR%;%PATH%
+set PYTHONPATH=%CONE_LIBDIR%;%PYTHONPATH%
+REM The cone_tool will parse the arguments from the environment variable
+call python "%BASEDIR%deprfea.py" %*
+set CONE_ERROR_CODE=%ERRORLEVEL%
+
+@rem Delete the egg cache dir
+call rd /S /Q "%EGG_CACHE_DIR%"
+
+if 0%CONE_EXITSHELL% equ 0 exit /b %CONE_ERROR_CODE%
+exit %CONE_ERROR_CODE%
+endlocal
+
+:: END OF depfea.cmd
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/dev-tools/deprfea.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,230 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import os
+import sys
+import re
+import shutil
+from optparse import OptionParser
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+sys.path.append(os.path.join(ROOT_PATH, '..'))
+if sys.version_info[0] == 2 and (sys.version_info[1] == 5 or sys.version_info[1] == 6):
+    cone_basedir = os.path.join(ROOT_PATH, 'configurationengine', 
+                                 'win', '%s.%s' % (sys.version_info[0], sys.version_info[1]))
+    cone_scriptdir = os.path.join(cone_basedir, 'scripts')
+    cone_libdir = os.path.join(cone_basedir, 'lib')
+    sys.path.append(cone_basedir)
+    sys.path.append(cone_scriptdir)
+    sys.path.append(cone_libdir)
+else:
+    print 'You are using an unsupported Python version: %s.%s' % (sys.version_info[0], sys.version_info[1])
+    sys.exit(1)
+
+print sys.path
+print os.getenv('PATH')
+    
+try:
+    import scripts.cone_common
+except:
+    import cone_common
+from cone.public import api, plugin, utils, exceptions
+from cone.storage.filestorage import FileStorage
+
+CARBON_PROJECT_URL = 'http://carbon.nokia.com/extapi'
+
+CONFIGS_FILE = os.path.join(ROOT_PATH, 'configs.txt')
+ALL_FEATURES_FILE = os.path.join(ROOT_PATH, 'all_features_and_values.txt')
+REPORT_FILE = os.path.join(ROOT_PATH, 'deprecated_features.txt')
+EXPORT_STORAGE = os.path.join(ROOT_PATH, 'exported')
+
+
+def get_list_of_configurations_from_carbon(carbon_prj):
+    config_list = carbon_prj.list_configurations()
+    config_list.sort()
+    return config_list
+
+def filter_configurations_from_file(cfilter=""):
+    config_list = []
+    fh = open(CONFIGS_FILE, 'r')
+    config_list = fh.readlines()
+    fh.close()
+    if cfilter:
+        return [elem.strip() for elem in config_list if match_filter(cfilter, elem)]
+    else: 
+        return config_list
+
+def check_deprecated_features(config, depr_features):
+    default_view = config.get_default_view()
+    f = open(ALL_FEATURES_FILE, 'a')
+    f.write('\n\n### %s ###\n\n' % config.get_name())
+    for fea_ref in default_view.list_all_features():
+        feature = default_view.get_feature(fea_ref)
+        # If feature has subfeatures, skip it
+        if len(feature.list_features()) > 0:
+            f.write('%-15s # %s\n' % ('Has subs', fea_ref))
+            continue
+        fea_value = default_view.get_feature(fea_ref).get_value()
+        f.write('%-15s # %s\n' % (fea_value, fea_ref))  
+        # If the value is None and it is not on the list yet, append it to deprecated features
+        if fea_value == None and depr_features.count(fea_ref) == 0:
+            depr_features.append(fea_ref)
+        # If the value is something else and the feature is on the list, remove it
+        elif fea_value != None and depr_features.count(fea_ref) != 0:
+            depr_features.remove(fea_ref)
+    f.close()
+    return depr_features
+
+def save_report(depr_features):
+    fh = open(REPORT_FILE, 'w')
+    try: [fh.write(df + '\n') for df in depr_features]
+    finally: fh.close()
+    
+
+def match_filter(cfilter, element):
+    filters = cfilter.split(';')
+    for f in filters:
+        if f.strip().lower() == element.strip().lower():
+            return True
+        if re.match('.*' + f.strip().lower() + '.*', element.strip().lower()):
+            return True
+    return False
+
+def create_options():
+    #parser = OptionParser(usage="Sumthin")
+    parser = OptionParser()
+    parser.add_option("-f", "--filter",
+                      action="store",
+                      dest="filter",
+                      help="Filter configurations. Multiple filters can be given, separated by \';\'. E.g. -f \"\(Vasco 01\);\(Vasco 06\)\"",
+                      metavar="REGEX",
+                      default="")
+    parser.add_option("-l", "--list-configurations",
+                      action="store_true",
+                      dest="list_configs",
+                      help="Only list available configurations in Carbon. When used with the -f option, preview the configurations which would be fetched from Carbon.",
+                      default=False)
+    parser.add_option("--force-carbon",
+                      action="store_true",
+                      dest="force_carbon",
+                      help="Get configurations from Carbon even if they have already been fetched.",
+                      default=False)
+    return parser
+
+def main():
+    parser = create_options()
+    (options, args) = parser.parse_args()
+    configs = []
+    carbon_prj = None
+    local_prj = None
+    
+    if options.filter == "":
+        selection = raw_input('No filter given! ALL the configs in Carbon will be fetched and it will take a loooong time. Are you ABSOLUTELY sure you want to continue (y/n)? ')
+        if selection.lower() != 'y':
+            print '\nGood choice :)'
+            return 0
+        else:
+            print '\nOk...\n'
+    
+    try:
+        os.remove(ALL_FEATURES_FILE)
+    except Exception, e:
+        pass
+    
+    print '\nOpening project in Carbon (%s)...' % CARBON_PROJECT_URL
+    try:
+        carbon_prj = api.Project(api.Storage.open(CARBON_PROJECT_URL,"r"))
+    except Exception, e:
+        print 'Unable to open Carbon project. %s' % e
+        return 1
+    
+    if os.path.exists(EXPORT_STORAGE):
+        print '\nOpening project on local disk (%s)...' % EXPORT_STORAGE
+        try:
+            local_prj = api.Project(api.Storage.open(EXPORT_STORAGE, 'r'))
+        except Exception, e:
+            print 'Unable to open local project. %s' % e
+            return 1
+    
+    # Force script to get everything from Carbon again
+    if options.force_carbon:
+        try:
+            os.remove(CONFIGS_FILE)
+            shutil.rmtree(EXPORT_STORAGE, ignore_errors=True)
+        except:
+            pass
+    
+    # Only get available configs and exit
+    if options.list_configs:
+        print 'Getting available configurations from Carbon (%s)' % CARBON_PROJECT_URL
+        configs = get_list_of_configurations_from_carbon(carbon_prj)
+        print 'Saving configs to %s...' % CONFIGS_FILE
+        fh = open(CONFIGS_FILE, 'w')
+        try: [fh.write('%s\n' % c) for c in configs]
+        finally: fh.close()
+        print 'Filtered configs: '
+        configs = filter_configurations_from_file(options.filter)
+        for elem in configs: print elem.strip()
+        return 0
+        
+        
+    if not os.path.exists(CONFIGS_FILE):
+        print 'Configurations file not found. Getting list of configurations in project...'
+        configs = get_list_of_configurations_from_carbon(carbon_prj)
+        print 'Saving configs to %s...' % CONFIGS_FILE
+        fh = open(CONFIGS_FILE, 'w')
+        try: [fh.write('%s\n' % c) for c in configs]
+        finally: fh.close()
+    
+    print '\nFilter wanted configurations from file: '   
+    configs = filter_configurations_from_file(options.filter)
+    for elem in configs: print elem.strip()
+    
+    depr_features = []
+    
+    for c in configs:
+        config_name = c.strip()
+        # Configuration has not been exported yet
+        if not os.path.exists(os.path.join(EXPORT_STORAGE, config_name)):
+            print '\nExport configuration %s from Carbon' % config_name
+            if not carbon_prj: 
+                carbon_prj = api.Project(api.Storage.open(CARBON_PROJECT_URL,"r"))
+            try:
+                config = carbon_prj.get_configuration(config_name)
+                carbon_prj.export_configuration(config, FileStorage(EXPORT_STORAGE, 'w'))
+            except:
+                print 'Unable to export %s' % config_name
+                continue
+        print '\nOpen configuration %s in project %s' % (config_name, EXPORT_STORAGE)
+        if not local_prj:
+            try:
+                local_prj = api.Project(api.Storage.open(EXPORT_STORAGE, 'r'))
+            except Exception, e:
+                print 'Unable to open local project. %s' % e
+                if carbon_prj: carbon_prj.close()
+                return 1
+        config = local_prj.get_configuration(c.strip())
+        depr_features = check_deprecated_features(config, depr_features)
+        
+    if local_prj: local_prj.close()
+    if carbon_prj: carbon_prj.close()
+    
+    save_report(depr_features)
+    
+    return 0
+
+if __name__ == '__main__':
+    sys.exit(main())
\ No newline at end of file
--- a/configurationengine/source/plugins/build_egg_info.py	Fri Mar 12 08:30:17 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-#
-# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
-# All rights reserved.
-# This component and the accompanying materials are made available
-# under the terms of "Eclipse Public License v1.0"
-# which accompanies this distribution, and is available
-# at the URL "http://www.eclipse.org/legal/epl-v10.html".
-#
-# Initial Contributors:
-# Nokia Corporation - initial contribution.
-#
-# Contributors:
-#
-# Description: 
-#
-
-# Script for generating the egg-info directories for all needed plug-ins.
-#
-# This is needed, because running some of the tests from Eclipse or
-# command line requires the egg-info dirs to be present for the plug-ins
-# to be found.
-
-import sys, os, subprocess, shutil
-
-ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
-DEBUG = False
-
-def generate_egg_info(path):
-    """Generate egg-info for the given plug-in path if possible and necessary."""
-    if not os.path.isdir(path) or "setup.py" not in os.listdir(path):
-        return
-    
-    # Check if egg-info has already been generated
-    for name in os.listdir(path):
-        egg_info_path = os.path.join(path, name)
-        if os.path.isdir(egg_info_path) and name.endswith('.egg-info'):
-            # xxx.egg-info is present in the directory, check if it is old
-            setup_py_path = os.path.join(path, 'setup.py')
-            if os.stat(setup_py_path).st_mtime < os.stat(egg_info_path).st_mtime:
-                if DEBUG: print "No need to generate egg-info for '%s'" % path
-                return
-            else:
-                if DEBUG: print "egg-info for '%s' is out of date, removing old and generating new" % path
-                shutil.rmtree(egg_info_path)
-    
-    # Run the egg-info generation command
-    orig_workdir = os.getcwd()
-    try:
-        if DEBUG: print "Generating egg-info for '%s'..." % path
-        os.chdir(path)
-        p = subprocess.Popen("python setup.py egg_info", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-        out, err = p.communicate()
-        if p.returncode != 0:
-            print >>sys.stderr, "Could not generate egg-info for '%s'!" % path
-            print >>sys.stderr, "Command stdout output:"
-            print >>sys.stderr, out
-            print >>sys.stderr, "Command stderr output:"
-            print >>sys.stderr, err
-        else:
-            if DEBUG:
-                print "Done"
-                print "Command output:"
-                print out
-    finally:
-        os.chdir(orig_workdir)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeCommandPlugin/__init__.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,16 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
--- a/configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/commandml.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/commandml.py	Tue Aug 10 14:29:28 2010 +0300
@@ -22,14 +22,27 @@
 
 import re
 import os
-import sys
 import logging
 import types
+import pkg_resources
 
 import subprocess
-import __init__
+
+from cone.public import plugin,utils
 
-from cone.public import exceptions,plugin,utils,api, settings
+def get_folder_set(folder):
+    """
+    Get a set object containing all files of given folder
+    @param folder: the folder to create set for
+    @return: a python set 
+    """
+    fileset = set()
+    for (root, _, filenames) in os.walk(folder):
+        for filename in filenames:
+            fname = utils.relpath(os.path.join(root,filename), folder)
+            fileset.add(fname)
+    
+    return fileset
 
 class CommandImpl(plugin.ImplBase):
     """
@@ -47,13 +60,16 @@
         self.desc = ""
         self.logger = logging.getLogger('cone.commandml(%s)' % self.ref)
         self.reader = reader
+        for element in self.reader.elements:
+            element.set_logger(self.logger)
         
 
     def generate(self, context=None):
         """
         Generate the given implementation.
         """
-        self.create_output()        
+        
+        self.create_output(context)
         return 
     
     def generate_layers(self,layers):
@@ -64,17 +80,26 @@
         self.create_output(layers)
         return 
     
-    def create_output(self, layers=None):
+    def create_output(self, context, layers=None):
         """
         Function to generate output files.
         """
-        
+        self.context = context
         tmpDict = self.__create_helper_variables()
-        
+        # Get the contents of output folder before the generation
+        outset_before = get_folder_set(context.output)
         for element in self.reader.elements:
             #Element can be either command or condition.
             element.set_logger(self.logger)
-            element.execute(tmpDict)        
+            element.execute(context, tmpDict)        
+        
+        # Get the contents of output folder after the generation 
+        # and get the new files created by the set difference.
+        # NOTE! this does not recognize files outside output folder!
+        outset_after = get_folder_set(context.output)
+        outset = outset_after - outset_before
+        for outfile in outset:
+            context.add_file(outfile, implementation=self)
         return
 
     def __create_helper_variables(self):
@@ -82,8 +107,8 @@
         Internal function to create dictionary containing most often used ConE "environment" variables.
         """        
         tmp = {}
-        tmp["%CONE_OUT%"] = self.output
-        tmp["%CONE_OUT_ABSOLUTE%"] = os.path.abspath(self.output)
+        tmp["%CONE_OUT%"] = os.path.join(self.context.output, self.output).rstrip('\\')
+        tmp["%CONE_OUT_ABSOLUTE%"] = os.path.abspath(os.path.join(self.context.output, self.output)).rstrip('\\')
         return tmp    
     
     def has_ref(self, refs):
@@ -100,6 +125,8 @@
     Parses a single commandml file
     """ 
     NAMESPACE = 'http://www.s60.com/xml/commandml/1'
+    NAMESPACE_ID = 'commandml'
+    ROOT_ELEMENT_NAME = 'commandml'
     FILE_EXTENSIONS = ['commandml']
     
     def __init__(self):
@@ -122,7 +149,11 @@
         if reader.tags:
             impl.set_tags(reader.tags)
         return impl
-            
+    
+    @classmethod
+    def get_schema_data(cls):
+        return pkg_resources.resource_string('commandplugin', 'xsd/commandml.xsd')
+    
     def set_default_view(self, dview):
         """
         Function to set default view that is needed when solving out ConfML reference information
@@ -260,17 +291,17 @@
             cmd.set_logger(logger)        
 
     def add_command(self, command):
-        self.command.append(command)
+        self.commands.append(command)
 
-    def execute(self, replaceDict=None):
-        if self.__solve_condition(self.condition):
+    def execute(self, context, replaceDict=None):
+        if self._solve_condition(self.condition, context):
             #Condition is true -> running command
             for command in self.commands:                
-                command.execute(replaceDict)
+                command.execute(context, replaceDict)
         else:
             self.logger.info("Ignoring %s because it is evaluated as False." % self.condition)
 
-    def __solve_condition(self, condition_str):
+    def _solve_condition(self, condition_str, context):
         """
         Internal function to handle condition
         """
@@ -278,7 +309,7 @@
             #Expanding ConfML information
             modstr = utils.expand_delimited_tokens(
                 condition_str,
-                lambda ref, index: repr(self.dview.get_feature(ref).get_value()))
+                lambda ref, index: repr(context.configuration.get_default_view().get_feature(ref).get_value()))
             return eval(modstr)
         else:
             #Empty condition is true always.
@@ -323,8 +354,7 @@
         self.cwd = cwd
     
     def set_all_envs(self, envs):
-        if envs:
-            self.envs = eval(envs)
+        self.envs = envs
     def set_default_view(self, dview):
         self.dview = dview
         
@@ -401,9 +431,17 @@
         for filter in self.filters:
             filter.report(self.logger)
 
-    def execute(self, replaceDict=None):
+    def execute(self, context, replaceDict=None):
+        self.dview = context.configuration.get_default_view()
+        
         self.solve_refs()
         
+        try:
+            if self.envs:   env_dict = eval(self.envs)
+            else:           env_dict = None
+        except Exception, e:
+            raise RuntimeError("Failed to evaluate env dictionary: %s: %s" % (e.__class__.__name__, e))
+        
         exit_code = 0
         try:
             try:
@@ -415,8 +453,8 @@
                 self.logger.info("Running command: \"%s\"" % command_str)
                 self.logger.info("with args: shell=%s envs=%s cwd=%s bufsize=%s stdin=%s stdout=%s stderr=%s" \
                                  % (self.shell, self.envs, cwd, self.bufsize, \
-                                    self.get_pipe("stdin", 'r'),self.get_pipe("stdout"), self.get_pipe("stderr")))                    
-                pid = subprocess.Popen(command_str, shell=self.shell, env=self.envs, cwd=cwd,\
+                                    self.get_pipe("stdin", 'r'),self.get_pipe("stdout"), self.get_pipe("stderr")))
+                pid = subprocess.Popen(command_str, shell=self.shell, env=env_dict, cwd=cwd,\
                                           bufsize=self.bufsize, stdin = self.get_pipe("stdin", 'r'),\
                                           stdout = self.get_pipe("stdout"), stderr = self.get_pipe("stderr"))
                 #Waiting for process to complete
@@ -452,6 +490,7 @@
         self.shell = self.__solve_ref(self.shell)
         self.bufsize = self.__solve_ref(self.bufsize)
         self.cwd = self.__solve_ref(self.cwd)
+        self.envs = self.__solve_ref(self.envs)
         for argument in self.arguments:
             self.arguments[self.arguments.index(argument)] = self.__solve_ref(argument) 
         for pipe in self.pipes.keys():
--- a/configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/__init__.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/__init__.py	Tue Aug 10 14:29:28 2010 +0300
@@ -18,19 +18,5 @@
 # Path to the directory where this file is located
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
 
-# Import common plug-in initialization
-PLUGINS_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../../../..'))
-assert os.path.split(PLUGINS_ROOT)[1] == 'plugins'
-if PLUGINS_ROOT not in sys.path: sys.path.append(PLUGINS_ROOT)
-import plugin_utils
-
+from testautomation import plugin_utils
 plugin_utils.plugin_test_init(ROOT_PATH)
-
-def collect_suite():
-    return plugin_utils.collect_test_suite_from_dir(ROOT_PATH)
-
-def runtests():
-    unittest.TextTestRunner(verbosity=2).run(collect_suite())
-
-if __name__ == '__main__':
-    runtests()
--- a/configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/project/assets/s60/implml/file2.commandml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/project/assets/s60/implml/file2.commandml	Tue Aug 10 14:29:28 2010 +0300
@@ -5,7 +5,7 @@
     
     <!-- This should be executed, since the value of RealSetting is 3.14 -->
     <condition value="${BasicSettingTypesTest.RealSetting} &gt; 4e-3">
-        <command executable="python" bufsize="0" cwd="." env="{'MYVAR':'123'}">
+        <command executable="python" shell="true" bufsize="0" cwd=".">
             <argument value="project/tools/print_hello.py"/>
             <argument value="-c some_config.txt" />
             <argument value="-d some_dir" />
@@ -40,4 +40,14 @@
         <argument value='-c "import os; print os.getcwd()"'/>
         <pipe name="stdout" value="exec_in_output_test.log"/>
     </command>
+
+    <!-- ====================================== -->
+    <!-- Creating output files                  -->
+    <!-- ====================================== -->
+    <!-- Create output directory, or the next command will fail if it doesn't exist -->
+    <command executable="python" shell="true">
+        <argument value='project/tools/helloworld.py "%CONE_OUT%"'/>
+    </command>
+
+
 </commandml>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/project/assets/s60/implml/file3.commandml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<container xmlns="http://www.symbianfoundation.org/xml/implml/1">
+    <tempVariable ref="TempBrowserIcon" type="boolean" value="true"/>
+
+    <commandml xmlns="http://www.s60.com/xml/commandml/1">
+	    <condition value="${TempBrowserIcon} == True">
+            <command executable="echo" shell="True">
+			    <argument value="jeejee" />
+		    </command>
+        </condition>
+        
+         <condition value="${TempBrowserIcon} == False">
+            <command executable="echo" shell="True">
+			<argument value="jeejee" />
+		</command>
+        </condition>
+    </commandml>
+</container>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/project/tools/helloworld.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,23 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+import os, sys
+
+output = sys.argv[1]
+outputfile = os.path.join(output, "helloworld.txt")
+
+f = open(outputfile, "w")
+f.write("Hello World!!!") 
+f.close()
--- a/configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/project/tools/print_hello.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/project/tools/print_hello.py	Tue Aug 10 14:29:28 2010 +0300
@@ -16,5 +16,4 @@
 import os, sys
 
 print "Hello"
-print "Cmd line args: %r" % sys.argv[1:]
-print "Env: %r" % os.environ
\ No newline at end of file
+print "Cmd line args: %r" % sys.argv[1:]
\ No newline at end of file
--- a/configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/runtests.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/runtests.py	Tue Aug 10 14:29:28 2010 +0300
@@ -14,6 +14,6 @@
 # Description: 
 #
 
-import __init__
-
-__init__.runtests()
+if __name__ == '__main__':
+    import nose
+    nose.core.run(argv=['collector','--include=unittest', '--verbosity=3'])
--- a/configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/unittest_commandml_plugin.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/unittest_commandml_plugin.py	Tue Aug 10 14:29:28 2010 +0300
@@ -16,12 +16,10 @@
 
 import unittest, os, shutil
 
-import __init__	
-from cone.public import exceptions,plugin,api
+# import __init__	
+from cone.public import plugin, api, utils
 from cone.storage import filestorage
-from cone.confml import implml
 from testautomation.base_testcase import BaseTestCase
-from commandplugin import commandml
 
 # Hardcoded value of testdata folder that must be under the current working dir
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
@@ -41,27 +39,35 @@
         try:
             OUTPUT_DIR = os.path.join(ROOT_PATH, 'output')
             self.remove_if_exists(OUTPUT_DIR)
+            self.remove_if_exists(['hello.log', 'exec_in_output_test.log',])
             
             fs = filestorage.FileStorage(testdata)
             p = api.Project(fs)
             config = p.get_configuration('product.confml')
+            context = plugin.GenerationContext(configuration=config,
+                                               output=OUTPUT_DIR)
             impls = plugin.get_impl_set(config,'file2\.commandml$')
-            impls.output = OUTPUT_DIR
-            impls.generate()
+            #impls.output = OUTPUT_DIR
+            impls.generate(context)
             
             self.assert_file_content_equals('hello.log',
-                "Hello\r\n" +
-                "Cmd line args: ['-c', 'some_config.txt', '-d', 'some_dir', '-x']\r\n" +
-                "Env: {'MYVAR': '123'}\r\n")
+                "Hello" + os.linesep +
+                "Cmd line args: ['-c', 'some_config.txt', '-d', 'some_dir', '-x']" + os.linesep)
             
             self.assert_file_content_equals('exec_in_output_test.log',
-                os.path.normpath(OUTPUT_DIR) + '\r\n')
+                os.path.normpath(OUTPUT_DIR) + os.linesep)
             
             # Check that the log file of the command that should not be
             # executed does not exist
             self.assertFalse(os.path.exists("should_not_be_created.log"))
+            self.assertTrue(os.path.exists(os.path.join(OUTPUT_DIR,"helloworld.txt")))
+            
+            self.assertEquals(len(context.generation_output), 1)
+            self.assertEquals(utils.relpath(context.generation_output[0].name, OUTPUT_DIR), 'helloworld.txt')
+            self.assertEquals(context.generation_output[0].implementation.ref, 'assets/s60/implml/file2.commandml')
         finally:
             os.chdir(orig_workdir)
+
         
 if __name__ == '__main__':
   unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/unittest_commandml_utils.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,57 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+import unittest, os, shutil
+
+from commandplugin import commandml 
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+TMP_PATH = os.path.join(ROOT_PATH, 'temp')
+TMP_FILE1 = os.path.join(TMP_PATH, 'sub/one.txt')
+TMP_FILE2 = os.path.join(TMP_PATH, 'foobar/two.txt')
+TMP_FILE3 = os.path.join(TMP_PATH, 'three.txt')
+
+def norm(path):
+    return os.path.normpath(path)
+
+def create_file(path):
+    if not os.path.exists(os.path.dirname(path)):
+        os.makedirs(os.path.dirname(path))
+    f = open(path, "w")
+    f.write('something...')
+    f.close()
+        
+class TestCommandUtil(unittest.TestCase):
+    def test_get_folder_set(self):
+        if os.path.exists(TMP_PATH):
+            shutil.rmtree(TMP_PATH)
+        os.mkdir(TMP_PATH)
+        create_file(TMP_FILE1)
+        fset1 = commandml.get_folder_set(TMP_PATH)
+
+        self.assertEquals(len(fset1), 1)
+        self.assertEquals(fset1, set([norm('sub/one.txt')]))
+        
+        create_file(TMP_FILE2)
+        create_file(TMP_FILE3)
+        fset2 = commandml.get_folder_set(TMP_PATH)
+        nset = fset2 - fset1
+        self.assertEquals(nset, set([norm('foobar/two.txt'), 
+                                     norm('three.txt')]))
+        
+
+if __name__ == '__main__':
+    unittest.main()
--- a/configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/unittest_parse_commandml.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/unittest_parse_commandml.py	Tue Aug 10 14:29:28 2010 +0300
@@ -16,7 +16,7 @@
 
 import unittest, os, re, subprocess
 
-import __init__
+# import __init__
 from cone.public import api, plugin
 from cone.storage import filestorage
 from testautomation.base_testcase import BaseTestCase
@@ -44,7 +44,7 @@
         self.assertEquals(cmd.shell, False)
         self.assertEquals(cmd.bufsize, 0)
         self.assertEquals(cmd.cwd, r'c:\program1')
-        self.assertEquals(cmd.envs, {'MYVAR': '123'})
+        self.assertEquals(cmd.envs, "{'MYVAR':'123'}")
         self.assertEquals(cmd.arguments, ['-c some_config.txt',
                                           '-d some_dir',
                                           '-x'])
@@ -67,7 +67,7 @@
     
     def test_parse_file2(self):
         impl = self._get_impl('file2.commandml')
-        self.assertEquals(len(impl.reader.elements), 4)
+        self.assertEquals(len(impl.reader.elements), 5)
         
         self.assertTrue(isinstance(impl.reader.elements[0], Condition))
         self.assertTrue(isinstance(impl.reader.elements[1], Condition))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/tests/unittest_read_temp_variable.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,57 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+import unittest, os, re, subprocess
+
+# import __init__
+from cone.public import api, plugin
+from cone.storage import filestorage
+from testautomation.base_testcase import BaseTestCase
+from commandplugin.commandml import Command, Condition
+from cone.public.api import Configuration
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+testdata  = os.path.join(ROOT_PATH,'project')
+
+class TestParseCommandMl(BaseTestCase):
+    def _get_impl_and_set(self, ref):
+        fs = filestorage.FileStorage(testdata)
+        p = api.Project(fs)
+        config = p.get_configuration('product.confml')
+        impl_set = plugin.get_impl_set(config, re.escape(ref) + '$')
+        self.assertEquals(len(impl_set), 1)
+        return iter(impl_set).next(), impl_set
+        
+    def test_parse_file3(self):
+        impl, impl_set = self._get_impl_and_set('file3.commandml')
+        self.assertEquals(len(impl[0].reader.elements), 2)
+ 
+        cond1 = impl.impls[0].reader.elements[0]
+        cond2 = impl.impls[0].reader.elements[1]
+        
+        # Create temporary variables
+        impl_set.create_temp_features(impl_set.generation_context.configuration)
+
+        self.assertTrue(isinstance(cond1, Condition))
+        self.assertTrue(isinstance(cond2, Condition))
+
+
+        self.assertEquals(True, cond1._solve_condition(cond1.condition, impl_set.generation_context))
+        self.assertEquals(False, cond2._solve_condition(cond2.condition, impl_set.generation_context))
+        
+        
+if __name__ == '__main__':
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeCommandPlugin/commandplugin/xsd/commandml.xsd	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema 
+	xmlns:xs="http://www.w3.org/2001/XMLSchema" 
+	targetNamespace="http://www.s60.com/xml/commandml/1" 
+	xmlns:commandml="http://www.s60.com/xml/commandml/1" 
+	elementFormDefault="qualified">
+	
+	<xs:complexType name="tagType">
+		<xs:attribute name="name" type="xs:string" use="required"/>
+		<xs:attribute name="value" type="xs:string"/>
+	</xs:complexType>
+	
+	<xs:complexType name="filterType">
+		<xs:attribute name="severity" type="xs:string"/>
+		<xs:attribute name="condition" type="xs:string"/>
+		<xs:attribute name="input" type="xs:string"/>
+        <xs:attribute name="formatter" type="xs:string"/>
+	</xs:complexType>
+
+	
+	<xs:complexType name="pipeType">
+		<xs:attribute name="name" type="xs:string" use="required"/>
+        <xs:attribute name="value" type="xs:string" use="required"/>
+	</xs:complexType>
+    
+    <xs:complexType name="argumentType">
+        <xs:attribute name="value" type="xs:string" use="required"/>
+	</xs:complexType>
+	
+    <xs:complexType name="commandType">
+		<xs:choice minOccurs="0" maxOccurs="unbounded">
+			<xs:element name="argument" type="commandml:argumentType"/>
+            <xs:element name="pipe" type="commandml:pipeType"/>
+            <xs:element name="filter" type="commandml:filterType"/>
+		</xs:choice>
+		<xs:attribute name="executable" type="xs:string" use="required"/>
+        <xs:attribute name="cwd" type="xs:string"/>
+        <xs:attribute name="shell" type="xs:string"/>
+        <xs:attribute name="bufsize" type="xs:string"/>
+        <xs:attribute name="env" type="xs:string"/>
+	</xs:complexType>
+    
+    <xs:complexType name="conditionType">
+		<xs:choice minOccurs="0" maxOccurs="unbounded">
+			<xs:element name="command" type="commandml:commandType"/>
+		</xs:choice>
+		<xs:attribute name="value" type="xs:string" use="required"/>
+	</xs:complexType>
+	
+	<xs:element name="commandml">
+        <xs:complexType>
+            <xs:choice minOccurs="0" maxOccurs="unbounded">
+                <xs:element name="tag" type="commandml:tagType"/>
+                <xs:element name="condition" type="commandml:conditionType"/>
+                <xs:element name="command" type="commandml:commandType"/>
+            </xs:choice>
+        </xs:complexType>
+    </xs:element>
+		
+</xs:schema>
\ No newline at end of file
--- a/configurationengine/source/plugins/common/ConeCommandPlugin/setup.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeCommandPlugin/setup.py	Tue Aug 10 14:29:28 2010 +0300
@@ -22,6 +22,7 @@
     name = "conecommandplugin",
     version = __version__,
     packages = find_packages(exclude=["*.tests"]),
+    package_data = {'commandplugin': ['xsd/*.xsd']},
     test_suite = "commandplugin.tests.collect_suite",
 
     # metadata for upload to PyPI
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/__init__.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,16 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
--- a/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/contentml.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/contentml.py	Tue Aug 10 14:29:28 2010 +0300
@@ -23,6 +23,7 @@
 import sys
 import logging
 import shutil
+import pkg_resources
             
 import __init__
 
@@ -46,6 +47,8 @@
         self.desc = ""
         self.logger = logging.getLogger('cone.content(%s)' % self.ref)
         self.errors = False
+        self.context = plugin.GenerationContext(configuration=configuration)
+
 
     def list_output_files(self):
         """
@@ -76,7 +79,7 @@
                     self.logger.info('Content copy items from %s to %s' % (input.dir,os.path.join(self.output,output.dir)))
                 
                 if input.__class__.__name__ == "ContentInput":
-                    copylist = self.create_copy_list(content=self.configuration.layered_content(),
+                    copylist = self.create_copy_list(content=self.configuration.layered_content(empty_folders=True),
                                                      input=input.dir,
                                                      output=os.path.join(self.output,output.dir),
                                                      include_pattern=input.get_include_pattern(),
@@ -91,13 +94,20 @@
                     else:
                         fulldir = self.configuration.get_project().get_storage().get_path()
                     
-                    data = container.DataContainer()                     
+                    data = container.DataContainer()
                     for root, dirs, files in os.walk(fulldir):
-                        for f in files:                            
+                        for f in files:
                             filepath = utils.resourceref.norm(os.path.join(root, f))
                             key = utils.resourceref.replace_dir(filepath,fulldir,"")
                             data.add_value(key,filepath)
-                            #data.add_value(filepath,filepath)
+                        
+                        # If the root contains no directories and no files, it is
+                        # an empty directory and needs to be added
+                        if not dirs and not files:
+                            filepath = utils.resourceref.norm(root)
+                            key = utils.resourceref.replace_dir(filepath,fulldir,"")
+                            data.add_value(key,filepath)
+                    
                     copylist = self.create_copy_list(content=data,
                                                      input=input.dir,
                                                      output=os.path.join(self.output,output.dir),
@@ -111,13 +121,18 @@
                     logging.getLogger('cone.content').warning("Unknown input %s" % (input.__class__.__name__))
                 
                 fullcopylist += copylist
-                 
+        
+        # Sort to make automated testing easier (list always in same order)
+        fullcopylist.sort()
+        
         return fullcopylist
 
     def generate(self, context=None):
         """
         Generate the given implementation.
         """
+        #assert context, "No Context given for generation!"
+        self.context = context
         self.logger.info('Generating')
         self.create_output()
         return 
@@ -127,31 +142,47 @@
         Create the output directory from the content folder files
         """
         if not self.errors:
-            datacontainer = self.configuration.layered_content(layers)
-            #root = self.configuration.get_root()
             copylist = self.get_full_copy_list(True)
             for copy_item in copylist:
-                sourceref = copy_item[0]
-                targetfile = copy_item[1]
-                external = copy_item[2]                                
+                source_path = copy_item[0]
+                target_path = copy_item[1]
+                external = copy_item[2]
+                
+                self.logger.info('Copy from %s to %s' % (source_path,target_path))
                 
-                self.logger.info('Copy from %s to %s' % (sourceref,targetfile))                   
-                if not os.path.exists(os.path.dirname(targetfile)):
-                    os.makedirs(os.path.dirname(targetfile))
-                if not external:
-                    outfile = open(targetfile,"wb")
-                    res = self.configuration.get_storage().open_resource(sourceref,"rb")
-                    outfile.write(res.read())
+                # Open file resource if the source is a file
+                file_res = None
+                if not external and not self.configuration.get_storage().is_folder(source_path):
+                    file_res = self.configuration.get_storage().open_resource(source_path, "rb")
+                elif external and os.path.isfile(source_path):
+                    file_res = open(source_path, 'rb')
+                
+                # Copy file or create empty directory
+                if file_res:
+                    try:        self._copy_file(file_res, target_path)
+                    finally:    file_res.close()
                 else:
-                    shutil.copyfile(sourceref,targetfile)
+                    path = os.path.join(self.context.output, target_path)
+                    if not os.path.exists(path): os.makedirs(path)
             return 
         else:
-            self.logger.error('Plugin had errors! Bailing out!')                   
-            
+            self.logger.error('Plugin had errors! Bailing out!')
+    
+    def _copy_file(self, source_file, target_file_path):
+        outfile = self.context.create_file(target_file_path, implementation=self)
+        try:
+            # Copy data in chunks of max 2 MB to avoid
+            # memory errors with very large files
+            while True:
+                data = source_file.read(2 * 1024 * 1024)
+                if data:    outfile.write(data)
+                else:       break
+        finally:
+            outfile.close()
 
     def create_copy_list(self, **kwargs):
         """
-        Return a list copy list where each element is a (from,to) tuple 
+        Return a list copy list where each element is a (from, to, is_external) tuple 
         """
         datacontainer = kwargs.get('content',None)
         input_dir     = kwargs.get('input','')
@@ -169,7 +200,7 @@
         Then apply the possible filters. 
         """
         if input_dir == None:
-           self.logger.warning("Input dir is none!")
+            self.logger.warning("Input dir is none!")
 
         
         if files != []:
@@ -199,7 +230,11 @@
             sourcefile = ""
             targetfile = ""
             
-            if input_dir != None and outfile.startswith(input_dir):
+            # For the startswith() check, make sure that input dir has a trailing slash
+            if input_dir and input_dir[-1] != '/':  input_dir_check = input_dir + '/'
+            else:                                   input_dir_check = input_dir
+            
+            if input_dir != None and (input_dir == outfile or outfile.startswith(input_dir_check)):
                 sourcefile = datacontainer.get_value(outfile)
                 if flatten:
                     targetfile = utils.resourceref.join_refs([output_dir, os.path.basename(outfile)])
@@ -220,11 +255,35 @@
             if output_file:
                 #Renaming output if defined
                 targetfile = targetfile.replace(os.path.basename(targetfile), output_file)
-                    
-            if sourcefile and targetfile:                
-                copylist.append((sourcefile,targetfile, external))
+                
+            if sourcefile and targetfile:
+                copylist.append((sourcefile,targetfile,external))
         return copylist
-
+    
+    def uses_layer(self, layer):
+        layered_content = layer.layered_content().list_keys()
+        for f in self.get_full_copy_list():
+            for file in layered_content:
+                if utils.resourceref.norm(os.path.join(utils.resourceref.get_path(layer.get_path()), 'content', file)) == f[0]:
+                    return True
+        return False
+    
+    def uses_layers(self, layers, context):
+        # Use the base implementation to check with refs first
+        if super(ContentImpl, self).uses_layers(layers, context):
+            return True
+        
+        # Then check if any of the files in the copy list come from the layers
+        copy_list = self.get_full_copy_list()
+        for layer in layers:
+            layered_content = layer.layered_content().list_keys()
+            for f in copy_list:
+                for file in layered_content:
+                    if utils.resourceref.norm(os.path.join(utils.resourceref.get_path(layer.get_path()), 'content', file)) == f[0]:
+                        return True
+        return False
+    
+    
 class ContentImplReaderBase(object):
     FILE_EXTENSIONS = ['content', 'contentml']
     
@@ -251,8 +310,20 @@
 
 class ContentImplReader1(ContentImplReaderBase, plugin.ReaderBase):
     NAMESPACE = 'http://www.s60.com/xml/content/1'
+    NAMESPACE_ID = 'contentml1'
+    ROOT_ELEMENT_NAME = 'content'
     parser_class = contentmlparser.Content1Parser
+    
+    @classmethod
+    def get_schema_data(cls):
+        return pkg_resources.resource_string('contentplugin', 'xsd/contentml.xsd')
 
 class ContentImplReader2(ContentImplReaderBase, plugin.ReaderBase):
     NAMESPACE = 'http://www.s60.com/xml/content/2'
+    NAMESPACE_ID = 'contentml2'
+    ROOT_ELEMENT_NAME = 'content'
     parser_class = contentmlparser.Content2Parser
+    
+    @classmethod
+    def get_schema_data(cls):
+        return pkg_resources.resource_string('contentplugin', 'xsd/contentml2.xsd')
--- a/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/contentmlparser.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/contentmlparser.py	Tue Aug 10 14:29:28 2010 +0300
@@ -60,8 +60,10 @@
         self.configuration = configuration
 
     def path_convert(self, path):
-        (drive, tail) = os.path.splitdrive(path)
-        return tail.lstrip('\\/')
+        match = re.match('([a-zA-Z]:)(.*)', path)
+        if match:
+            path = match.group(2)
+        return path.lstrip('\\/')
 
     def get_dir(self):
         if self.configuration and ConfmlRefs.is_confml_ref(self._dir):
@@ -151,7 +153,9 @@
                             # change None value to empty string
                             cvalue = dview.get_feature(cref).value or ''
                             if utils.is_list(cvalue):
-                                cvalue = ", ".join(cvalue)
+                                # Allow only strings (mainly filter out Nones)
+                                cvalue = filter(lambda x: isinstance(x, basestring), cvalue)
+                                cvalue = ", ".join([v or '' for v in cvalue])
                             key_list[index] = cvalue
                         except exceptions.NotFound:
                             logging.getLogger('cone.content').error("Feature ref '%s' in include key '%s' not found." % (cref,key))
@@ -448,5 +452,5 @@
                 if not ref in ret:
                     ret.append(matchref.group(1))
             else:
-				ret.append(p)
+                ret.append(p)
         return ret
\ No newline at end of file
--- a/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/__init__.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/__init__.py	Tue Aug 10 14:29:28 2010 +0300
@@ -13,24 +13,11 @@
 #
 # Description: 
 #
+
 import sys, os, unittest
 
 # Path to the directory where this file is located
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
 
-# Import common plug-in initialization
-PLUGINS_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../../../..'))
-assert os.path.split(PLUGINS_ROOT)[1] == 'plugins'
-if PLUGINS_ROOT not in sys.path: sys.path.append(PLUGINS_ROOT)
-import plugin_utils
-
+from testautomation import plugin_utils
 plugin_utils.plugin_test_init(ROOT_PATH)
-
-def collect_suite():
-    return plugin_utils.collect_test_suite_from_dir(ROOT_PATH)
-
-def runtests():
-    unittest.TextTestRunner(verbosity=2).run(collect_suite())
-
-if __name__ == '__main__':
-    runtests()
Binary file configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/confml/content.confml has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/implml/empty_input_file_from_sequence.content	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<content xmlns="http://www.s60.com/xml/content/2">
+    <output dir="widget/temp" flatten="true">
+        <input>
+            <include files="${content.inputseq.inputfile_empty.localPath}" /> 
+        </input>
+    </output>
+</content>
--- a/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/implml/test_external_input.content	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/assets/s60/implml/test_external_input.content	Tue Aug 10 14:29:28 2010 +0300
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <content xmlns="http://www.s60.com/xml/content/2">
     <desc>Copy only prod</desc>
-    <output dir="content_external">
+    <output dir="content_external2">
     	<externalinput dir="external_content/folder1"/>
     </output>    
     <output dir="content_external">
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/contentproject/family/product/content/test/test_CAP_letters.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,1 @@
+S60 product layer
--- a/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/runtests.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/runtests.py	Tue Aug 10 14:29:28 2010 +0300
@@ -14,6 +14,6 @@
 # Description: 
 #
 
-import __init__
-
-__init__.runtests()
+if __name__ == '__main__':
+    import nose
+    nose.core.run(argv=['collector','--include=unittest', '--verbosity=3'])
Binary file configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/testdata/emptydircopy/external_content.zip has changed
Binary file configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/testdata/emptydircopy/project.zip has changed
--- a/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/unittest_confmlrefs.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/unittest_confmlrefs.py	Tue Aug 10 14:29:28 2010 +0300
@@ -29,11 +29,6 @@
         except ImportError:
             from xml.etree import ElementTree
 
-try:
-	pkg_resources.require('ConeContentPlugin')
-except pkg_resources.DistributionNotFound:
-	import __init__
-		
 from contentplugin import contentmlparser
 
 class TestConfmlRefs(unittest.TestCase):    
--- a/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/unittest_content_copy.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/unittest_content_copy.py	Tue Aug 10 14:29:28 2010 +0300
@@ -16,11 +16,7 @@
 
 import unittest, os
 import pkg_resources 
-try:
-    pkg_resources.require('ConeContentPlugin')
-except pkg_resources.DistributionNotFound:
-    import __init__
-    
+
 from cone.public.exceptions import NotSupportedException
 from contentplugin import contentml
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/unittest_content_copy_empty_dirs.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,175 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+import os, shutil
+import unittest
+
+from cone.public import plugin, api
+from testautomation.base_testcase import BaseTestCase
+from testautomation.unzip_file import unzip_file
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+TESTDATA_DIR  = os.path.join(ROOT_PATH, 'testdata')
+TEMP_DIR = os.path.join(ROOT_PATH, 'temp/emptydircopy')
+
+class TestContentCopyEmptyDirs(BaseTestCase):
+    
+    def _get_project_and_config(self, workdir, storage_type):
+        # Create the working directory for the test
+        self.remove_if_exists(workdir)
+        os.makedirs(workdir)
+        
+        # Unpack or copy the project into the working directory
+        project_source_zip = os.path.join(TESTDATA_DIR, 'emptydircopy/project.zip')
+        if storage_type == 'fs':
+            project_location = os.path.join(workdir, 'project')
+            unzip_file(project_source_zip, project_location)
+        elif storage_type == 'zs':
+            project_location = os.path.join(workdir, 'project.zip')
+            shutil.copy(project_source_zip, project_location)
+        else:
+            raise ValueError('Invalid storage type %r' % storage_type)
+        
+        # Copy the external content directory
+        unzip_file(os.path.join(TESTDATA_DIR, 'emptydircopy/external_content.zip'),
+                   os.path.join(workdir, 'external_content'))
+        
+        project = api.Project(api.Storage.open(project_location, 'r'))
+        config = project.get_configuration('root.confml')
+        return project, config
+    
+    def test_get_copy_list(self):
+        workdir = os.path.join(TEMP_DIR, 'get_copy_list')
+        proj, conf = self._get_project_and_config(workdir, 'fs')
+        proj.close()
+        impls = plugin.get_impl_set(conf)
+        
+        orig_dir = os.getcwd()
+        os.chdir(workdir)
+        try:
+            self.assertEquals(1, len(impls))
+            impl = iter(impls).next()
+            self.assertEquals(8, len(impl.impls))
+            
+            # Normal inputs
+            # -------------
+            def check(impl_index, expected):
+                self.assertEquals(sorted(impl.impls[impl_index].get_full_copy_list()),
+                                  sorted(expected))
+            check(0, [
+                ('layer2/content/foobar/layer2_emptydir',       'foobar_out/layer2_emptydir', False),
+                ('layer1/content/foobar/layer1_emptydir',       'foobar_out/layer1_emptydir', False),
+                ('layer1/content/foobar/layer1_emptydir2/foo',  'foobar_out/layer1_emptydir2/foo', False),
+                ('layer2/content/foobar/layer2.txt',            'foobar_out/layer2.txt', False),
+                ('layer1/content/foobar/layer1.txt',            'foobar_out/layer1.txt', False)
+            ])
+            check(1, [
+                #('layer2/content/foobar_filtered/layer2_filtered_emptydir', 'foobar_out/layer2_filtered_emptydir', False),
+                #('layer1/content/foobar_filtered/layer1_filtered_emptydir', 'foobar_out/layer1_filtered_emptydir', False),
+                ('layer1/content/foobar_filtered/bar.txt', 'foobar_out_filtered/bar.txt', False),
+            ])
+            check(2, [('layer1/content/empty', 'empty_out', False)])
+            check(3, [])
+            
+            
+            # External inputs
+            # ---------------
+            def check(impl_index, expected):
+                expected = [(os.path.abspath(src).replace('\\', '/'), tgt, ext) for src, tgt, ext in expected]
+                self.assertEquals(sorted(impl.impls[impl_index].get_full_copy_list()),
+                                  sorted(expected))
+            check(4, [
+                ('external_content/foobar/emptydir',       'ext_out/foobar_out/emptydir', True),
+                ('external_content/foobar/emptydir2/foo',  'ext_out/foobar_out/emptydir2/foo', True),
+                ('external_content/foobar/x.txt',          'ext_out/foobar_out/x.txt', True)
+            ])
+            check(5, [
+                #('external_content/foobar_filtered/layer1_filtered_emptydir', 'ext_out/foobar_out/layer1_filtered_emptydir', False),
+                ('external_content/foobar_filtered/bar.txt', 'ext_out/foobar_out_filtered/bar.txt', True),
+            ])
+            check(6, [('external_content/empty', 'ext_out/empty_out', True)])
+            check(7, [])
+        finally:
+            os.chdir(orig_dir)
+            self.remove_if_exists(workdir)
+    
+    def test_copy_empty_dirs_filestorage(self):
+        workdir = os.path.join(TEMP_DIR, 'filestorage')
+        proj, conf = self._get_project_and_config(workdir, 'fs')
+        
+        orig_dir = os.getcwd()
+        os.chdir(workdir)
+        try:
+            self._run_test_copy_empty_dirs(workdir, conf)
+        finally:
+            os.chdir(orig_dir)
+            proj.close()
+            self.remove_if_exists(workdir)
+    
+    def test_copy_empty_dirs_zipstorage(self):
+        workdir = os.path.join(TEMP_DIR, 'zipstorage')
+        proj, conf = self._get_project_and_config(workdir, 'zs')
+        
+        orig_dir = os.getcwd()
+        os.chdir(workdir)
+        try:
+            self._run_test_copy_empty_dirs(workdir, conf)
+        finally:
+            os.chdir(orig_dir)
+            proj.close()
+            self.remove_if_exists(workdir)
+    
+    def _run_test_copy_empty_dirs(self, workdir, config):
+        output_dir = os.path.join(workdir, 'output')
+        context = plugin.GenerationContext(configuration=config, output=output_dir)
+        impl_set = plugin.get_impl_set(config)
+        impl_set.generate(context)
+        
+        created_dirs = []
+        created_files = []
+        def strip(path):
+            return path[len(output_dir):].replace('\\', '/').strip('/')
+        for root, dirs, files in os.walk(output_dir):
+            for d in dirs:  created_dirs.append(strip(os.path.join(root, d)))
+            for f in files: created_files.append(strip(os.path.join(root, f)))
+        
+        self.assertEquals(sorted(created_dirs), sorted(
+            ['empty_out',
+             'ext_out',
+             'ext_out/empty_out',
+             'ext_out/foobar_out',
+             'ext_out/foobar_out/emptydir',
+             'ext_out/foobar_out/emptydir2',
+             'ext_out/foobar_out/emptydir2/foo',
+             'ext_out/foobar_out_filtered',
+             'foobar_out',
+             'foobar_out/layer1_emptydir',
+             'foobar_out/layer1_emptydir2',
+             'foobar_out/layer1_emptydir2/foo',
+             'foobar_out/layer2_emptydir',
+             'foobar_out_filtered'
+             #'foobar_out_filtered/layer1_emptydir',
+             #'foobar_out_filtered/layer2_emptydir',
+             ]))
+        self.assertEquals(sorted(created_files), sorted(
+            ['ext_out/foobar_out/x.txt',
+             'ext_out/foobar_out_filtered/bar.txt',
+             'foobar_out/layer1.txt',
+             'foobar_out/layer2.txt',
+             'foobar_out_filtered/bar.txt']))
+
+if __name__ == '__main__':
+    unittest.main()
--- a/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/unittest_content_parseimpl.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/unittest_content_parseimpl.py	Tue Aug 10 14:29:28 2010 +0300
@@ -29,11 +29,6 @@
         except ImportError:
             from xml.etree import ElementTree
 
-try:
-	pkg_resources.require('ConeContentPlugin')
-except pkg_resources.DistributionNotFound:
-	import __init__
-		
 from contentplugin import contentmlparser
 
 
@@ -319,6 +314,8 @@
         conout = contentmlparser.ContentOutput()
         self.assertEquals(conout.path_convert('z:\\test\\foo\\bar.txt'), 'test\\foo\\bar.txt')
         self.assertEquals(conout.path_convert('z:/test/foo/bar.txt'), 'test/foo/bar.txt')
+        self.assertEquals(conout.path_convert('/test/foo/bar.txt'), 'test/foo/bar.txt')
+        self.assertEquals(conout.path_convert('foo/bar.txt'), 'foo/bar.txt')
 
 class TestContentInput(unittest.TestCase):    
     def test_content_input_dir(self):
--- a/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/unittest_content_plugin.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/tests/unittest_content_plugin.py	Tue Aug 10 14:29:28 2010 +0300
@@ -18,8 +18,7 @@
 import os, shutil
 import sys
 import logging
-import __init__
-		
+
 from cone.public import exceptions,plugin,api,container
 from cone.storage import filestorage
 from contentplugin import contentml
@@ -103,7 +102,6 @@
         impls = plugin.ImplFactory.get_impls_from_file(resource_ref, configuration)
         self.assertEquals(len(impls), 1)
         impl = impls[0]
-        impl.set_output_root(self.output)
         return impl
 
     def test_configuration_parse_resource(self):
@@ -142,24 +140,25 @@
     def test_configuration_content_get_full_copy_list(self):
         impl = self.load_impl('assets/s60/implml/copy_files.content')
         files = impl.get_full_copy_list()
-        self.assertEquals(files[0],('family/content/test/override.txt', 'output/content/test/override.txt', False))
+        self.assertEquals(files,
+            [('assets/s60/content/test/s60.txt', 'content/test/s60.txt', False),
+             ('family/content/test/override.txt', 'content/test/override.txt', False)])
 
     def test_configuration_content_list_output_files(self):
         config = self.load_config()
         impls = plugin.get_impl_set(config,'\.content$')
-        impls.output = self.output
         files = impls.list_output_files()
-        self.assertTrue('output/content/test/override.txt' in files)
+        self.assertTrue('content/test/override.txt' in files)
 
     def test_configuration_content_list_output_files_with_refs_filter(self):
         impl = self.load_impl('assets/s60/implml/test_content_with_sequence_refs.content')
         files = impl.list_output_files()
-        self.assertEquals(files[0],'output/content/override.txt')
+        self.assertEquals(files[0],'content/override.txt')
 
     def test_configuration_content_list_output_files_with_exclude_filter(self):
         impl = self.load_impl('assets/s60/implml/test_filter_both.content')
         files = impl.list_output_files()
-        self.assertEquals(files[0],'output/content/prodX/jee/ProdX_specific.txt')
+        self.assertEquals(files[0],'content/prodX/jee/ProdX_specific.txt')
 #
     def test_configuration_get_input_with_ref(self):
         impl = self.load_impl('assets/s60/implml/test_content_with_refs.content')
@@ -169,69 +168,71 @@
     def test_configuration_get_include_with_refs(self):
         impl = self.load_impl('assets/s60/implml/test_content_with_sequence_refs.content')
         self.assertEquals(impl.outputs[0].inputs[0].include['files'], ['test/override.txt'])
-        self.assertEquals(impl.list_output_files(), ['output/content/override.txt'])
+        self.assertEquals(impl.list_output_files(), ['content/override.txt'])
 
-    def test_configuration_get_include_with_refs(self):
+    def test_configuration_get_include_with_refs2(self):
         impl = self.load_impl('assets/s60/implml/copy.content')
-        expected = ['output/content/prodX/jee/ProdX_specific.txt', 
-                    'output/content/test/shout.txt', 
-                    'output/content/test/override.txt', 
-                    'output/content/test/s60.txt',
-                    'output/content/test/test_CAP_letters.txt']
+        expected = ['content/prodX/jee/ProdX_specific.txt', 
+                    'content/test/shout.txt', 
+                    'content/test/override.txt', 
+                    'content/test/s60.txt',
+                    'content/test/test_CAP_letters.txt']
         actual = impl.list_output_files()
         self.assertEquals(sorted(actual), sorted(expected))
 
     def test_configuration_content_create_output(self):
         impl = self.load_impl('assets/s60/implml/copy.content')
-        impl.set_output_root(self.output)
         impl.logger.setLevel(logging.DEBUG)
         impl.create_output()
-        self.assertTrue(os.path.exists(impl.output))
-        self.assertTrue(os.path.exists(os.path.join(impl.output,'content/prodX/jee/ProdX_specific.txt')))
+        self.assertTrue(os.path.exists(os.path.join(self.output,'content/prodX/jee/ProdX_specific.txt')))
 
     def test_configuration_content_generate(self):
         config = self.load_config()
         impls = plugin.get_impl_set(config,'\.content$')
-        impls.output = self.output
-        results = impls.generate()
+        context = plugin.GenerationContext(output=self.output)
+        results = impls.generate(context)
         self.assertTrue(os.path.exists(impls.output))
-        self.assertTrue(os.path.exists(os.path.join(impls.output,'content/prodX/jee/ProdX_specific.txt')))
+        self.assertTrue(os.path.exists(os.path.join(context.output,'content/prodX/jee/ProdX_specific.txt')))
 
     def test_configuration_content_generate_with_include_refs(self):
         impl = self.load_impl('assets/s60/implml/test_content_with_sequence_refs.content')
-        impl.set_output_root(self.output)
-        results = impl.generate()
-        self.assertTrue(os.path.exists(impl.output))
-        self.assertTrue(os.path.exists(os.path.join(impl.output,'content/override.txt')))
+        context = plugin.GenerationContext(output=self.output)
+        results = impl.generate(context)
+        self.assertTrue(os.path.exists(os.path.join(context.output,'content/override.txt')))
+
+    def test_configuration_content_generate_with_external_input(self):
+        impl = self.load_impl('assets/s60/implml/test_external_input.content')
+        context = plugin.GenerationContext(output=self.output)
+        results = impl.generate(context)
+        self.assertTrue(os.path.exists(os.path.join(context.output,'content_external/abc.txt')))
+        self.assertTrue(os.path.exists(os.path.join(context.output,'content_external/folder1/data.txt')))
+        self.assertTrue(os.path.exists(os.path.join(context.output,'content_external2/folder2/setting.txt')))
 
     def test_configuration_content_generate_with_multi_output(self):
         impl = self.load_impl('assets/s60/implml/content2_with_multi_outputs.content')
-        impl.set_output_root(self.output)
-        results = impl.generate()
-        self.assertTrue(os.path.exists(impl.output))
-        self.assertTrue(os.path.exists(os.path.join(impl.output,'content/test/override.txt')))
-        self.assertTrue(os.path.exists(os.path.join(impl.output,'include/s60.txt')))
+        context = plugin.GenerationContext(output=self.output)
+        results = impl.generate(context)
+        self.assertTrue(os.path.exists(os.path.join(context.output,'content/test/override.txt')))
+        self.assertTrue(os.path.exists(os.path.join(context.output,'include/s60.txt')))
 
     def test_configuration_content_generate_with_refs(self):
         impl = self.load_impl('assets/s60/implml/test_content_with_refs2.content')
-        impl.set_output_root(self.output)
-        results = impl.generate()
-        self.assertTrue(os.path.exists(impl.output))
-        self.assertTrue(os.path.exists(os.path.join(impl.output,'content2p1/content2p2/override.txt')))
+        context = plugin.GenerationContext(output=self.output)
+        results = impl.generate(context)
+        self.assertTrue(os.path.exists(os.path.join(context.output,'content2p1/content2p2/override.txt')))
         
     def test_configuration_content_generate_with_refs2(self):
         impl = self.load_impl('assets/s60/implml/test_content_with_refs3.content')
-        impl.set_output_root(self.output)
-        results = impl.generate()
-        self.assertTrue(os.path.exists(impl.output))
-        self.assertTrue(os.path.exists(os.path.join(impl.output,'example/content2p2/override.txt')))
+        context = plugin.GenerationContext(output=self.output)
+        results = impl.generate(context)
+        self.assertTrue(os.path.exists(os.path.join(self.output,'example/content2p2/override.txt')))
        
     def test_configuration_content_generate_capital_letters(self):
         impl = self.load_impl('assets/s60/implml/test_content_capital_file_input.content')
-        impl.set_output_root(self.output)
-        results = impl.generate()
-        self.assertTrue(os.path.exists(impl.output))
-        self.assertTrue(os.path.exists(os.path.join(impl.output,'content/test_CAP_letters.txt')))
+        context = plugin.GenerationContext(output=self.output)
+        results = impl.generate(context)
+        self.assertTrue(os.path.exists(context.output))
+        self.assertTrue(os.path.exists(os.path.join(context.output,'content/test_CAP_letters.txt')))
 
     def test_get_refs(self):
         def check(filename, expected_refs):
@@ -257,5 +258,20 @@
         check('test_external_with_ref.content', ['CTD_Special.InputPath'])
         check('test_filter_both.content', None)
 
+    def test_uses_layer(self):
+        project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'contentproject')))
+        root_config = project.get_configuration('product.confml')
+        
+        impl = self.load_impl('assets/s60/implml/test_content_capital_file_input.content')
+        self.assertFalse(impl.uses_layer(root_config.get_configuration_by_index(0)))
+        self.assertFalse(impl.uses_layer(root_config.get_configuration_by_index(1)))
+        self.assertTrue(impl.uses_layer(root_config.get_configuration_by_index(2)))
+    
+    def test_get_copy_list_with_empty_file_input_from_sequence(self):
+        impl = self.load_impl('assets/s60/implml/empty_input_file_from_sequence.content')
+        copylist = impl.get_full_copy_list()
+        # There should be nothing in the copy list
+        self.assertEquals(copylist, [])
+        
 if __name__ == '__main__':
     unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/xsd/contentml.xsd	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema 
+	xmlns:xs="http://www.w3.org/2001/XMLSchema" 
+	targetNamespace="http://www.s60.com/xml/content/1" 
+	xmlns:content="http://www.s60.com/xml/content/1" 
+	elementFormDefault="qualified">
+	
+	<xs:complexType name="tagType">
+		<xs:attribute name="name" type="xs:string"/>
+		<xs:attribute name="value" type="xs:string"/>
+	</xs:complexType>
+	
+	<xs:complexType name="includeType">
+		<xs:attribute name="files" type="xs:string"/>
+		<xs:attribute name="dir" type="xs:string"/>
+		<xs:attribute name="pattern" type="xs:string"/>
+	</xs:complexType>
+
+	
+	<xs:complexType name="outputType">
+		<xs:attribute name="dir" type="xs:string"/>
+		<xs:attribute name="flatten" type="xs:string"/>
+	</xs:complexType>
+	
+	<xs:complexType name="excludeType">
+		<xs:attribute name="files" type="xs:string"/>
+		<xs:attribute name="dir" type="xs:string"/>
+		<xs:attribute name="pattern" type="xs:string"/>
+	</xs:complexType>
+
+	
+		
+	<xs:complexType name="inputType">
+		<xs:choice minOccurs="0" maxOccurs="unbounded">
+			<xs:element name="include" type="content:includeType"/>
+			<xs:element name="exclude" type="content:excludeType"/>
+		</xs:choice>
+		<xs:attribute name="file" type="xs:string"/>
+        <xs:attribute name="dir" type="xs:string"/>
+	</xs:complexType>
+
+
+	<xs:complexType name="contentRootType">
+        <xs:sequence>
+            <xs:choice minOccurs="0" maxOccurs="unbounded">
+                <xs:element name="desc" type="xs:string"/>
+                <xs:element name="tag" type="content:tagType"/>
+            </xs:choice>
+            
+            <!-- There has got to be a better way to do this... -->
+			<xs:choice>
+                <xs:sequence>
+                    <xs:element name="input" type="content:inputType" minOccurs="1" maxOccurs="1"/>
+                    <xs:element name="output" type="content:outputType" minOccurs="1" maxOccurs="1"/>
+                </xs:sequence>
+                <xs:sequence>
+                    <xs:element name="output" type="content:outputType" minOccurs="1" maxOccurs="1"/>
+                    <xs:element name="input" type="content:inputType" minOccurs="1" maxOccurs="1"/>
+                </xs:sequence>
+            </xs:choice>
+        </xs:sequence>
+        <xs:attribute name="phase" type="xs:string"/>
+    </xs:complexType>
+	
+	<xs:element name="content" type="content:contentRootType"/>
+		
+</xs:schema>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/contentplugin/xsd/contentml2.xsd	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema 
+	xmlns:xs="http://www.w3.org/2001/XMLSchema" 
+	targetNamespace="http://www.s60.com/xml/content/2" 
+	xmlns:content2="http://www.s60.com/xml/content/2" 
+	elementFormDefault="qualified">
+
+	
+	<xs:complexType name="tagType">
+		<xs:attribute name="name" type="xs:string"/>
+		<xs:attribute name="value" type="xs:string"/>
+	</xs:complexType>
+	
+	<xs:complexType name="includeType">
+		<xs:attribute name="files" type="xs:string"/>
+		<xs:attribute name="dir" type="xs:string"/>
+		<xs:attribute name="pattern" type="xs:string"/>
+	</xs:complexType>
+
+	<xs:complexType name="excludeType">
+		<xs:attribute name="files" type="xs:string"/>
+		<xs:attribute name="dir" type="xs:string"/>
+		<xs:attribute name="pattern" type="xs:string"/>
+	</xs:complexType>
+	
+		
+	<xs:complexType name="inputType">
+		<xs:choice minOccurs="0" maxOccurs="unbounded">
+			<xs:element name="include" type="content2:includeType"/>
+			<xs:element name="exclude" type="content2:excludeType"/>
+		</xs:choice>
+		<xs:attribute name="file" type="xs:string"/>
+        <xs:attribute name="dir" type="xs:string"/>
+	</xs:complexType>
+    
+    <xs:complexType name="externalInputType">
+		<xs:choice minOccurs="0" maxOccurs="unbounded">
+			<xs:element name="include" type="content2:includeType"/>
+			<xs:element name="exclude" type="content2:excludeType"/>
+		</xs:choice>
+		<xs:attribute name="file" type="xs:string"/>
+        <xs:attribute name="dir" type="xs:string"/>
+	</xs:complexType>
+
+
+	<xs:complexType name="outputType">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+            <xs:element name="input" type="content2:inputType"/>
+            <xs:element name="externalinput" type="content2:externalInputType"/>
+        </xs:choice>
+		<xs:attribute name="file" type="xs:string"/>
+		<xs:attribute name="dir" type="xs:string"/>
+		<xs:attribute name="flatten" type="xs:string"/>
+	</xs:complexType>
+	
+	
+	<xs:complexType name="contentRootType">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+			<xs:element name="tag" type="content2:tagType"/>
+            <xs:element name="output" type="content2:outputType"/>
+			<xs:element name="desc" type="xs:string"/>
+        </xs:choice>
+        <xs:attribute name="phase" type="xs:string"/>
+    </xs:complexType>
+	
+	<xs:element name="content" type="content2:contentRootType"/>
+		
+</xs:schema>
\ No newline at end of file
--- a/configurationengine/source/plugins/common/ConeContentPlugin/setup.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeContentPlugin/setup.py	Tue Aug 10 14:29:28 2010 +0300
@@ -22,6 +22,7 @@
     name = "conecontentplugin",
     version = __version__,
     packages = find_packages(exclude=["*.tests"]),
+    package_data = {'contentplugin': ['xsd/*.xsd']},
     test_suite = "contentplugin.tests.collect_suite",
 
     # metadata for upload to PyPI
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/__init__.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,16 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/__init__.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,17 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+__version__ = 0.1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/__init__.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,17 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+__version__ = 0.1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/accesspoint_id_counter.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,365 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+'''
+Ruleml eval extension to count accesspoint id's
+'''
+
+import logging
+
+logger = logging.getLogger('cone.ruleplugin.evals.accesspoint_id_counter')
+
+def get_apindex_by_apname(aps, dns, apname):
+    """
+    Returns AccessPoint index by given AccessPoint name
+    """
+    cnt = _get_ApDnContainer_(aps, dns)
+    return cnt.get_apindex_by_apname(apname)
+
+def get_apid_by_apname(aps, dns, apname, wlan_support=True):
+    """
+    Returns AccessPoint id by given AccessPoint name
+    """
+    cnt = _get_ApDnContainer_(aps, dns, wlan_support)
+    return cnt.get_apid_by_apname(apname)
+
+def get_dnid_by_dnname(aps, dns, dnname, wlan_support=True):
+    """
+    Return DestinationNetwork id by given DestinationNetworks name
+    """
+    cnt = _get_ApDnContainer_(aps, dns, wlan_support)
+    return cnt.get_dnid_by_dnname(dnname)
+
+def get_apid_by_dnname_and_apname(aps, dns, dnname, apname, wlan_support=True):
+    """
+    Returns AccessPoint id by given DestinationNetwork name and AccessPoint name.
+    """
+    cnt = _get_ApDnContainer_(aps, dns, wlan_support)
+    return cnt.get_apid_by_dnname_and_apname(dnname, apname)
+
+def get_all_in_array(aps, dns, wlan_support=True):
+    """
+    Returns array containing all data:
+        [DN name],[DN id], [IAPS names], [IAPS ids], [IAPS indexes] 
+    """
+    cnt = _get_ApDnContainer_(aps, dns, wlan_support)
+    return cnt.get_all_in_array()
+
+def _get_ApDnContainer_(aps, dns, wlan_support=True):
+    """
+    Returns populated ApDnContainer
+    """
+    cnt = ApDnContainer()
+    
+    _read_dns_(dns, cnt)
+    _read_aps_(aps, cnt)
+    
+    cnt._calc_dn_ids_()
+    
+    if wlan_support:
+        cnt._calc_ap_ids_(2)
+    else:
+        cnt._calc_ap_ids_(1)
+    
+    cnt._calc_ap_indexes_(1)
+    
+    return cnt
+
+def _read_dns_(dns, cnt):
+    """
+    Reads DNs to internal objects to ApDnContainer.
+    """
+    
+    dn_names = None
+    dn_ids = None
+    dn_iaps = [None]*10
+    
+    for dn in dns.DN:
+        if dn.ref == 'Name':
+            dn_names = dn.value
+        if dn.ref == 'DNId':
+            dn_ids = dn.value
+        if dn.ref == 'IAP':
+            dn_iaps[0] = dn.value
+        if dn.ref == 'IAP2':
+            dn_iaps[1] = dn.value
+        if dn.ref == 'IAP3':
+            dn_iaps[2] = dn.value
+        if dn.ref == 'IAP4':
+            dn_iaps[3] = dn.value
+        if dn.ref == 'IAP5':
+            dn_iaps[4] = dn.value
+        if dn.ref == 'IAP6':
+            dn_iaps[5] = dn.value
+        if dn.ref == 'IAP7':
+            dn_iaps[6] = dn.value
+        if dn.ref == 'IAP8':
+            dn_iaps[7] = dn.value
+        if dn.ref == 'IAP9':
+            dn_iaps[8] = dn.value
+        if dn.ref == 'IAP10':
+            dn_iaps[9] = dn.value
+    
+    logger.info('Parsed DN names: %s' % dn_names)
+    logger.info('Parsed DN ids: %s' % dn_ids)
+    logger.info('Parsed DN iaps: %s' % dn_iaps)
+    
+    for i in range(len(dn_names)):
+        mydn = Dn()
+        mydn.set_id(dn_ids[i])
+        mydn.set_name(dn_names[i])
+        myiaps = [None]*10
+        for j in range(10):
+            myiaps[j] = dn_iaps[j][i]
+        mydn.set_iaps(myiaps)
+        cnt.add_dn(mydn)
+    return cnt
+
+def _read_aps_(aps, cnt):
+    """
+    Reads APs to internal objects to ApDnContainer.
+    """
+    ap_names = None
+    ap_ids1 = None
+    
+    for ap in aps.AP:
+        if ap.ref == 'ConnectionName':
+            ap_names = ap.value
+        if ap.ref == 'ConnectionId':
+            ap_ids1 = ap.value
+    
+    ap_ids2 = [None]*len(ap_names)
+    if ap_ids1 == None:
+        ap_ids1 = []
+    
+    
+    for i in range(len(ap_ids1)):
+        ap_ids2[i] = ap_ids1[i]
+        
+    
+    logger.info('Parsed AP names: %s' % ap_names)
+    logger.info('Parsed AP ids: %s' % ap_ids2)
+    
+    for i in range(len(ap_names)):
+        myap = Ap()
+        myap.set_id(ap_ids2[i])
+        myap.set_name(ap_names[i])
+        cnt.add_ap(myap)
+    return cnt
+
+def _get_next_free_id_(bases, start_index=1):
+    """
+    Returns next id as a string that is not in use.
+    """
+    
+    biggest_id = int(start_index)
+    
+    for base in bases:
+        current_id = base.get_id()
+        if current_id != None or current_id != '':
+            if current_id > biggest_id:
+                biggest_id = current_id
+    
+    return str(int(biggest_id) + 1)
+
+
+class ApDnContainer(object):
+    """
+    Container for AccessPoints and DestinationNetworks, that provides various access and search methods to them.
+    """
+    
+    def __init__(self):
+        self.dns = []
+        self.aps = []
+
+    def __str__(self):
+        return "ApDnContainer(dns: " + str(self.dns) + ", aps:" + str(self.aps) + ")"
+
+    def add_dn(self, dn):
+        self.dns.append(dn)
+    
+    def add_ap(self, ap):
+        self.aps.append(ap)
+
+    def get_all_dns(self):
+        return self.dns
+    
+    def get_all_aps(self):
+        return self.aps
+    
+    def _calc_dn_ids_(self):
+        for dn in self.dns:
+            if dn.get_id() == None or dn.get_id() == '':
+                dn.set_id(_get_next_free_id_(self.dns, 1))
+
+    def _calc_ap_indexes_(self, ind=1):
+        index = ind
+        
+        for dn in self.dns:
+            for iap in dn.get_iaps():
+                if iap != None:
+                    for ap in self.aps:
+                        if ap.get_name() == iap and ap.get_index() == '':
+                            ap.set_index(str(index))
+                            index += 1
+
+    def _calc_ap_ids_(self, start_index=1):
+        """
+        Calculates unique index for every AccessPoint, if Easy_WLAN is given it always have index 1.
+        """
+        
+        for ap in self.aps:
+            if ap.name == 'Easy WLAN':
+                ap.set_id('1')
+                logger.info('Easy_WLAN AP found. Setting 1 to AP id.')
+                
+        for ap in self.aps:
+            if ap.get_id() == None or ap.get_id() == '':
+                ap.set_id(_get_next_free_id_(self.aps, int(start_index)))
+    
+    def get_apid_by_apname(self, apname):
+        """
+        Returns Accesspoint id by given AccessPoint name
+        """
+    
+        for ap in self.aps:
+            if ap.name == apname:
+                return ap.get_id()
+        return None
+    
+    def get_apindex_by_apname(self, apname):
+        """
+        Returns Accesspoint index by given AccessPoint name
+        """
+        
+        for ap in self.aps:
+            if ap.get_name() == apname:
+                return ap.get_index()
+        return None
+    
+    
+    def get_dnid_by_dnname(self, dnname):
+        """
+        Return DestinationNetwork id by given DestinationNetworks name
+        """
+        for dn in self.dns:
+            if dn.name == dnname:
+                return dn.id
+        return None
+    
+    def get_apid_by_dnname_and_apname(self, dnname, apname):
+        """
+        Returns AccessPoint id by given DestinationNetwork name and AccessPoint name.
+        """
+        for dn in self.dns:
+            if dn.name == dnname:
+                iaps = dn.get_iaps()
+                for iap in range(len(iaps)):
+                    if iaps[iap] != None and iaps[iap] == apname:
+                        return self.get_apid_by_apname(apname)
+        return None
+    
+    def get_all_in_array(self):
+        """
+        Returns array containing all data:
+            [DN name],[DN id], [IAPS names], [IAPS ids] [IAPS index]
+        """
+        ret = [None]*len(self.dns)
+        
+        for i in range(len(self.dns)):
+            line = [None]*5
+            line[0] = self.dns[i].get_name()
+            line[1] = self.dns[i].get_id()
+            line[2] = self.dns[i].get_iaps()
+            
+            ap_ids = [None]*10
+            
+            for j in range(10):
+                ap_ids[j] = self.get_apid_by_apname(self.dns[i].get_iaps()[j])
+            
+            line[3] = ap_ids
+            
+            ap_indexes = [None]*10
+            
+            for j in range(10):
+                ap_indexes[j] = self.get_apindex_by_apname(self.dns[i].get_iaps()[j])
+            
+            line[4] = ap_indexes
+            
+            ret[i] = line
+            
+        return ret
+
+class Base(object):
+    """
+    Base data classes for AP and DN classes.
+    """
+    def __init__(self):
+        self.name = ''
+        self.id = ''
+
+    def set_name(self, name):
+        self.name = name
+    
+    def get_name(self):
+        return self.name
+    
+    def set_id(self, id):
+        self.id = id
+    
+    def get_id(self):
+        return self.id
+
+class Dn(Base):
+    """
+    Destination network
+    """
+    
+    def __init__(self):
+        self.name = None
+        self.id = None
+        self.iaps = [None]*10
+    
+    def __str__(self):
+        return "Dn(name: " + self.name + ", id:" + self.id + ", iaps:" + str(self.iaps) + ")"
+    
+    def set_iaps(self, iaps):
+        self.iaps = iaps
+
+    def set_iap(self, index, value):
+        self.iaps[index] = value
+    
+    def get_iap(self, index):
+        return self.iaps[index]
+    
+    def get_iaps(self):
+        return self.iaps
+    
+class Ap(Base):
+    
+    def __init__(self):
+        self.name = ''
+        self.id = ''
+        self.index = ''
+    
+    def __str__(self):
+        return "Ap(name: " + self.name + ", id:" + self.id + ")"
+    
+    def set_index(self, index):
+        self.index = index
+    
+    def get_index(self):
+        return self.index
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/layer_utils.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,119 @@
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+'''
+Ruleml eval extension to check is passed ref changed on given layer(range).
+'''
+
+from cone.public import api
+
+import logging
+
+logger = logging.getLogger('cone.ruleplugin.evals.layer_utils')
+
+def give_changed_layers(feat):
+    """
+    Returns a list of booleans where True means that feature is changed in that layer. Index is
+    same than in configuration root's get_configuration_by_index(). 
+    """
+    
+    logger.debug('Checking feature: %s' % feat.fqr)
+    
+    root_conf = feat.get_root_configuration()
+    nro_of_layers = len(root_conf.list_configurations())
+    result = [False] * nro_of_layers
+    
+    for i in range(0, nro_of_layers):
+        conf = root_conf.get_configuration_by_index(i)
+        logger.debug("Traversing data from configuration: %s" % conf.get_path())
+        datas = conf._traverse(type=api.Data, filters=[lambda d: d.fqr==feat.fqr])
+        for data in datas:
+            try:
+                if data.get_value() != None:
+                    logger.debug("Feature '%s' is changed in layer %s with data '%s'" % (feat.fqr, i, data.get_value()))
+                    result[i] = True
+            except Exception, e:
+                logger.debug("Failed to check Feature '%s' data in layer %s:", (e,i))
+        if result[i] == False:
+            logger.debug("Feature '%s' is not changed in layer: %s" % (feat.fqr, i))
+    logger.debug("Feature '%s' is changed in layers: %s" % (feat.fqr, result))
+    return result
+
+def changed_on_last_layer(feat):
+    """
+    Returns True if feature is changed in the last layer.
+    """
+    
+    root_conf = feat.get_root_configuration()
+    conf = root_conf.get_configuration_by_index(-2)#autoconfig layer is ignored 
+    
+    def check(node):
+        if isinstance(node, api.Data) and node.fqr == feat.fqr:
+            return True
+        for obj in node._objects():
+            if check(obj):
+                return True
+    
+    if check(conf):
+        return True
+    else:
+        return False
+
+def changed_on_autoconfig_layer(feat):
+    """
+    Returns True if feature is changed in the autoconfig layer.
+    """
+    
+    root_conf = feat.get_root_configuration()
+    conf = root_conf.get_configuration_by_index(-1) 
+    
+    def check(node):
+        if isinstance(node, api.Data) and node.fqr == feat.fqr:
+            return True
+        for obj in node._objects():
+            if check(obj):
+                return True
+    
+    if check(conf):
+        return True
+    else:
+        return False
+
+def changed_on_layer(feat, layer):
+    """
+    Returns True if feature is changed in the given layer.
+    """
+    try:
+        return give_changed_layers(feat)[layer]
+    except IndexError, e:
+        logger.warning("Given layer is not found: %s" % (layer))
+        return False
+
+def changed_on_layers(feat, findex, tindex):
+    """
+    Returns True if feature is changed in layer of given range.
+    """
+    layers = give_changed_layers(feat)
+    
+    if findex == tindex:
+        return changed_on_layer(feat, findex)
+    
+    for i in range(findex, tindex):
+        if i > len(layers):
+            continue
+        if layers != None and layers[i] != None and layers[i]:
+            return True
+    return False
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/shortcuts_conversion.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,95 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import os
+
+def get_fixed_target_path(feature, setting):
+	type_ref = setting + '_type'
+	type = feature.get_feature(type_ref)
+	type_value = type.get_value()
+	ret = ""
+	if type_value == '1':
+		None
+	elif type_value == '2':
+		icon = feature.get_feature(setting + '_icon')
+		if icon != None:
+			ret = get_fixed_icon_target(icon)
+	else:
+		None
+		
+	return ret
+
+def get_fixed_icon_target(icon):
+	targetPath = icon.get_feature('targetPath').get_value()
+	localPath = icon.get_feature('localPath').get_value()
+	target = get_target_without_extension(targetPath)
+	extension = get_correct_extension(localPath)
+	fixed = ""
+	if extension != None:
+		if len(target) > 0 and len(extension) > 0:
+			fixed = target + extension
+	return fixed
+
+def get_target_without_extension(targetPath):
+	(target,_) = os.path.splitext(targetPath)
+	return target
+
+def get_correct_extension(localPath):
+	
+	if localPath != None:
+		(_,extension) = os.path.splitext(localPath)
+		if extension == '.bmp':
+			return '.mbm'
+		elif extension == '.svg':
+			return '.mif'
+		else:
+			return extension
+	else:
+		return None
+
+def get_shortcut_string(feature, setting):
+	type_ref = setting + '_type'
+	type_value = feature.get_feature(type_ref).get_value()
+	ret = ""
+	if type_value == '1':
+		app_ref = setting + '_app'
+		application = feature.get_feature(app_ref).get_value()
+		ret = application
+	elif type_value == '2':
+		url = feature.get_feature(setting+'_URL').get_value()
+		title = feature.get_feature(setting+'_title').get_value()
+
+		if title == None:
+			title = ""
+		else:
+			title = 'customtitle=' + title
+		
+		icon = feature.get_feature(setting + '_icon')
+		image_path = icon.get_feature('targetPath').get_value()
+		
+		icon_str = ""
+		
+		if image_path != None and image_path != "":
+			icon_str = 'iconmifpath='
+			if image_path.endswith('.mif'): index = '16384'
+			else:                           index = '0'
+			icon_str = icon_str + image_path + ';' + index + '&'
+			
+		ret = url + '?custom?' + icon_str + title
+	return ret
+
+#print get_shortcut_string('1', '2', '3')
+#http://www.nokia2.com?custom?iconmifpath=Z:\\resource\\apps\\icon2.mbm;1&amp;customtitle=Nokia2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/__init__.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,15 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/layerproject/layer1/confml/test.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration name="testdata" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
+	<feature name="String feature" ref="StringFeatureTest">
+		<setting name="Value 1" ref="Value1" type="string" />
+		<setting name="Value 2" ref="Value2" type="string" />
+	</feature>
+	<data>
+		<StringFeatureTest>
+			<Value1>String 1</Value1>
+		</StringFeatureTest>
+	</data>
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/layerproject/layer1/implml/test1.ruleml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ruleml xmlns="http://www.s60.com/xml/ruleml/2">
+	<rule>{% changed_on_layer( @{StringFeatureTest.Value1}, -1) %} configures result1 = True</rule>
+	<eval_globals file="../../layer_utils.py"/>
+</ruleml>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/layerproject/layer1/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,3 @@
+<configuration name="testdata" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
+  <xi:include href="confml/test.confml" />
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/layerproject/layer2/confml/test.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration name="testdata" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
+	<feature name="String feature" ref="StringFeatureTest">
+		<setting name="Value 1" ref="Value1" type="string" />
+	</feature>
+	<data>
+		<StringFeatureTest>
+			<Value1>String 2</Value1>
+			<Value2>String 2</Value2>
+		</StringFeatureTest>
+	</data>
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/layerproject/layer2/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,3 @@
+<configuration name="testdata" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
+  <xi:include href="confml/test.confml" />
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/layerproject/layer3/confml/test.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration name="testdata" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
+	<feature name="String feature" ref="StringFeatureTest">
+		<setting name="Value 1" ref="Value1" type="string" />
+	</feature>
+	<data>
+		<StringFeatureTest>
+			<Value1>String 3</Value1>
+			<Value2>String 3</Value2>
+		</StringFeatureTest>
+	</data>
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/layerproject/layer3/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,3 @@
+<configuration name="testdata" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
+  <xi:include href="confml/test.confml" />
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/layerproject/layer4/confml/test.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration name="testdata" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
+	<feature name="String feature" ref="StringFeatureTest">
+		<setting name="Value 1" ref="Value1" type="string" />
+	</feature>
+	<data>
+		<StringFeatureTest>
+			<Value1>String 4</Value1>
+		</StringFeatureTest>
+	</data>
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/layerproject/layer4/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,3 @@
+<configuration name="testdata" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
+  <xi:include href="confml/test.confml" />
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/layerproject/layer5/confml/test.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration name="testdata" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
+	<feature name="String feature" ref="StringFeatureTest">
+		<setting name="Value 1" ref="Value1" type="string" />
+	</feature>
+	<data>
+		<StringFeatureTest>
+			<Value1>String 5</Value1>
+		</StringFeatureTest>
+	</data>
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/layerproject/layer5/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,3 @@
+<configuration name="testdata" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
+  <xi:include href="confml/test.confml" />
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/layerproject/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,7 @@
+<configuration name="layer_utils" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
+  <xi:include href="layer1/root.confml" />
+  <xi:include href="layer2/root.confml" />
+  <xi:include href="layer3/root.confml" />
+  <xi:include href="layer4/root.confml" />
+  <xi:include href="layer5/root.confml" />
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/ruleproject/ctd/confml/CTD_commsdat.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,460 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/1" name="CTD_commsdat" version="">
+
+
+<feature ref="KCRUidSuplSettings" type="selection">
+    <setting ref="CTD_KSuplSettingsIAP" name="A-GPS access point" type="selection">
+        <desc>Selection for A-GPS access point</desc>
+        <option map="CTD_APs/AP"/>
+        <option map="CTD_WLAN_APs/WLAN_AP"/>
+   </setting>     
+</feature>
+
+<feature ref="MMSEngineSettings" relevant="">
+    <setting ref="CTD_MMS_AP" name="MMS access point" type="selection">
+        <desc>Selection for MMS access point</desc>
+        <option map="CTD_APs/AP"/>
+        <option map="CTD_WLAN_APs/WLAN_AP"/>
+   </setting>     
+</feature>
+<feature ref="KCRUidBrowser" name="Browser Settings">
+     <setting ref="CTD_Browser_AP" name="Access point" type="selection" relevant="KWmlBrowserAccessPointSelectionMode='0'">
+        <desc>Selection for Browser access point</desc>
+        <option map="CTD_APs/AP"/>
+        <option map="CTD_WLAN_APs/WLAN_AP"/>
+        </setting>
+        
+      
+     <setting ref="CTD_Browser_SNAP" name="Destination Network" type="selection" relevant="KWmlBrowserAccessPointSelectionMode='2'">
+          <desc>Setting for the default Destination Network</desc>
+          <option name="Internet" value="1"/>
+          <option name="MMS" value="2"/>
+          <option name="Wap Services" value="3"/>
+     </setting>
+</feature>
+<feature ref="KCRUidBrowser1" name="Browser Settings1">
+     <setting ref="CTD_Browser_autoupdate_AP" name="Access point for web feeds autoupdate" type="selection">
+        <desc>Selection for web feeds autoupdate access point</desc>
+        <option map="CTD_APs/AP"/>
+        <option map="CTD_WLAN_APs/WLAN_AP"/>
+        </setting>
+</feature>
+<feature ref="Mailbox1" name="Mailbox 1">
+    <setting ref="CTD_Email_AP1" name="Email access point for mailbox 1" type="selection">
+        <desc>Selection for Email access point</desc>
+        <option map="CTD_APs/AP"/>
+        <option map="CTD_WLAN_APs/WLAN_AP"/>
+    </setting>  
+</feature>     
+<feature ref="Mailbox2" name="Mailbox 2">
+    <setting ref="CTD_Email_AP2" name="Email access point for mailbox 2" type="selection">
+        <desc>Selection for Email access point</desc>
+        <option map="CTD_APs/AP"/>
+        <option map="CTD_WLAN_APs/WLAN_AP"/>
+    </setting>  
+</feature>
+     
+<feature ref="Mailbox3" name="Mailbox 3">
+   <setting ref="CTD_Email_AP3" name="Email access point for mailbox 3" type="selection">
+        <desc>Selection for Email access point</desc>
+        <option map="CTD_APs/AP"/>
+        <option map="CTD_WLAN_APs/WLAN_AP"/>
+   </setting>  
+</feature>
+    
+<feature ref="Mailbox4" name="Mailbox4">
+   <setting ref="CTD_Email_AP4" name="Email access point for mailbox 4" type="selection">
+        <desc>Selection for Email access point</desc>
+        <option map="CTD_APs/AP"/>
+        <option map="CTD_WLAN_APs/WLAN_AP"/>
+    </setting>  
+</feature>    
+<feature ref="Mailbox5" name="Mailbox 5">
+   <setting ref="CTD_Email_AP5" name="Email access point for mailbox 5" type="selection">
+        <desc>Selection for Email access point</desc>
+        <option map="CTD_APs/AP"/>
+        <option map="CTD_WLAN_APs/WLAN_AP"/>
+    </setting>  
+</feature>
+<feature ref="Mailbox6" name="Mailbox 6">
+    <setting ref="CTD_Email_AP6" name="Email access point for mailbox 6" type="selection">
+        <desc>Selection for Email access point</desc>
+        <option map="CTD_APs/AP"/>
+        <option map="CTD_WLAN_APs/WLAN_AP"/>
+    </setting>  
+</feature>
+
+  <feature ref="CTD_APs" name="GPRS Access Points" relevant="">
+    <desc>GPRS connection method (CM) definitions</desc>
+    <setting ref="AP" name="GPRS" type="sequence" constraint="" relevant="" minOccurs="0" maxOccurs="99" mapKey="ConnectionName" mapValue="ConnectionName">
+      <setting ref="ConnectionName" name="Connection Name" type="string">
+        <desc>The access point name that is visible to the user.</desc>
+      </setting>
+      <setting ref="GPRS_AP_Name" name="GPRS Access Point Name" type="string">
+        <desc>The access point name for this GPRS connection</desc>
+      </setting>
+                  <setting ref="CTD_GPRSAddtoDN" name="Add access point to destination" type="selection">
+        <desc>Define the destination network that the access point will be added to. Can be left empty.</desc>
+        <option name="Internet Destination" value="1"/>
+        <option name="MMS Destination" value="2"/>
+        <option name="WAP Services Destination" value="3"/>
+      </setting>
+      <setting ref="Seamlessness" name="Use access point" type="selection">
+        <desc>Defines whether an IAP can be roamed to.</desc>
+        <option name="Confirm First" value="After confirmation"/>
+        <option name="Show Progress" value="Automatically"/>
+      </setting>
+      <setting ref="NetworkType" name="Network type" type="selection">
+        <desc>Addressing that the network uses.</desc>
+        <option name="IPv4" value="IPv4"/>
+        <option name="IPv6" value="IPv6"/>
+      </setting>
+      <setting ref="UserName" name="User Name" type="string">
+        <desc>User name</desc>
+      </setting>
+      <setting ref="PromptPassword" name="Prompt Password" type="selection">
+        <desc>Prompt password at connection time.</desc>
+        <option name="No" value="No"/>
+        <option name="Yes" value="Yes"/>
+      </setting>
+      <setting ref="Password" name="Password" type="string">
+        <desc>Password.</desc>
+      </setting>
+      <setting ref="PasswordAuthenticationType" name="Password authentication type" type="selection">
+        <desc>Password authentication method.</desc>
+        <option name="Normal" value="Normal"/>
+        <option name="Secure" value="Secure"/>
+      </setting>
+      <setting ref="StartingPage" name="Homepage" type="string">
+        <desc>Access point homepage in URL format.</desc>
+      </setting>
+
+      <setting ref="ProxyServerAddress" name="Proxy Server Address" type="string">
+        <desc>Address of the HTTP/HTTPS proxy server.</desc>
+      </setting>
+      <setting ref="ProxyPortNumber" name="Proxy Port Number" type="string">
+        <desc>Port number of the HTTP/HTTPS proxy server.</desc>
+      </setting>
+
+      <setting ref="PrimaryNameServer" name="IPv4 Primary Name Server" type="string" relevant="NetworkType = 'IPv4'">
+        <desc>Address of the primary DNS server that resolves host names. 
+        Typically allocated automatically so this can be left empty.</desc>
+      </setting>
+      <setting ref="SecondaryNameServer" name="IPv4 Secondary Name Server" type="string" relevant="NetworkType = 'IPv4'">
+        <desc>Address of the secondary DNS server to connect if the primary DNS server is not available.
+        Typically allocated automatically so this can be left empty.</desc>
+      </setting>
+      <setting ref="PrimaryIP6NameServer" name="IPv6 Primary Name Server" type="string" relevant="NetworkType = 'IPv6'">
+        <desc>Address of the primary DNS server that resolves host names.
+        Typically allocated automatically so this can be left empty.</desc>
+      </setting>
+      <setting ref="SecondaryIP6NameServer" name="IPv6 Secondary Name Server" type="string" relevant="NetworkType = 'IPv6'">
+        <desc>Address of the secondary DNS server to connect if the primary DNS server is not available.
+        Typically allocated automatically so this can be left empty.</desc>
+      </setting>
+
+    </setting>
+  </feature>
+
+  <feature ref="CTD_WLAN_APs" name="WLAN Access Points" relevant="" >
+    <desc>WLAN connection method (CM) definitions</desc>
+    <setting ref="WLAN_AP" name="WLAN" type="sequence" constraint="" relevant="" minOccurs="0" maxOccurs="99" mapKey="ConnectionName" mapValue="ConnectionName">
+      <setting ref="ConnectionName" name="Connection Name" type="string" constraint="" required="">
+        <desc>The access point name that is visible to the user.</desc>
+      </setting>
+      <setting ref="Seamlessness" name="Use access point" type="selection">
+        <desc>Defines whether an IAP can be roamed to.</desc>
+        <option name="Confirm First" value="After confirmation"/>
+        <option name="Show Progress" value="Automatically"/>
+      </setting>
+      <setting ref="NetworkName" name="Network Name" type="string">
+        <desc>Service set identifier (SSID) of the primary WLAN network.</desc>
+      </setting>
+    <setting ref="CTD_WLANAddtoDN" name="Add access point to destination" type="selection">
+        <desc>Define the destination network that the access point will be added to. Can be left empty.</desc>
+        <option name="Internet Destination" value="1"/>
+        <option name="MMS Destination" value="2"/>
+        <option name="WAP Services Destination" value="3"/>
+      </setting>
+      <setting ref="StartingPage" name="Homepage" type="string">
+        <desc>Access point homepage in URL format.</desc>
+      </setting>
+      <setting ref="NetworkMode" name="Network Mode" type="selection">
+        <desc>Determines the network infrastructure. 
+        If there is a WLAN access point in the network then this should be Infrastructure.</desc>
+        <option name="Infrastructure" value="Infrastructure"/>
+        <option name="Ad-hoc" value="Ad-hoc"/>
+      </setting>
+      
+            <setting ref="WLANScanSSID" name="Network Status" type="selection">
+        <desc>Defines whether the SSID should be actively scanned. 
+        This is needed if the SSID is hidden (not broadcasted by the AP) </desc>
+        <option name="Public" value="No"/>
+        <option name="Hidden" value="Yes"/>
+      </setting>
+
+      <setting ref="PrimaryNameServer" name="IPv4 Primary Name Server" type="string" relevant="NetworkType = 'IPv4'">
+        <desc>Address of the primary DNS server that resolves host names.
+        Typically allocated automatically in which case this should be empty.</desc>
+      </setting>
+      <setting ref="SecondaryNameServer" name="IPv4 Secondary Name Server" type="string" relevant="NetworkType = 'IPv4'">
+        <desc>Address of the secondary DNS server to connect if the primary DNS server is not available.
+        Typically allocated automatically in which case this should be empty.</desc>
+      </setting>
+      <setting ref="PrimaryIP6NameServer" name="IPv6 Primary Name Server" type="string" relevant="NetworkType = 'IPv6'">
+        <desc>Address of the primary DNS server that resolves host names.
+        Typically allocated automatically in which case this should be empty.</desc>
+      </setting>
+      <setting ref="SecondaryIP6NameServer" name="IPv6 Secondary Name Server" type="string" relevant="NetworkType = 'IPv6'">
+        <desc>Address of the secondary DNS server to connect if the primary DNS server is not available.
+        Typically allocated automatically in which case this should be empty.</desc>
+      </setting>
+      <setting ref="ProxyServerAddress" name="Proxy Server Address" type="string">
+        <desc>Address of the HTTP/HTTPS proxy server.</desc>
+      </setting>
+      <setting ref="ProxyPortNumber" name="Proxy Port Number" type="string">
+        <desc>Port number of the HTTP/HTTPS proxy server.</desc>
+      </setting>
+      <setting ref="ProxyProtocolName" name="Proxy protocol Name" type="string">
+        <desc>Name of the protocol for which this proxy can be used. 
+        Typically http or https.</desc>
+      </setting>
+      <setting ref="WlanChannelId" name="WLAN Channel ID" type="string" relevant="NetworkMode = 'Ad-hoc'">
+        <desc>
+      	802.11 Channel ID (1-14). Used only when connecting/setting up adhoc network.
+      	</desc>
+      </setting>
+            <setting ref="SecurityMode" name="Security Mode" type="selection">
+        <desc>Security mode of the WLAN network.</desc>
+        <option name="Open" value="Open"/>
+        <option name="WEP" value="WEP"/>
+        <option name="802.1x" value="802.1x"/>
+        <option name="WPA" value="WPA"/>
+        <option name="WPA2" value="WPA2"/>
+      </setting>
+      <setting ref="WEPKeyInUse" name="WEP Key In Use" type="selection" relevant="SecurityMode = 'WEP'">
+        <desc>Index of default WEP key. Used only when security mode is WEP.</desc>
+        <option name="key1" value="key1"/>
+        <option name="key2" value="key2"/>
+        <option name="key3" value="key3"/>
+        <option name="key4" value="key4"/>
+      </setting>
+      <setting ref="WEPAuthType" name="WEP Auth Type" type="selection" relevant="SecurityMode = 'WEP'">
+        <desc>WEP authentication mode. Only used when security mode is WEP.</desc>
+        <option name="Shared" value="Shared"/>
+        <option name="Open" value="Open"/>
+      </setting>
+      <setting ref="WEPKey1Length" name="WEP Key1 Length" type="selection" relevant="SecurityMode = 'WEP'">
+        <desc>WEP key length in bits.</desc>
+        <option name="64" value="64"/>
+        <option name="128" value="128"/>
+        <option name="256" value="256"/>
+      </setting>
+      <setting ref="WEPKey1Format" name="WEP Key1 Format" type="selection" relevant="SecurityMode = 'WEP'">
+        <desc>WEP key format.</desc>
+        <option name="ASCII" value="ASCII"/>
+        <option name="Hexadecimal" value="Hexadecimal"/>
+      </setting>
+      <setting ref="WEPKey1Data" name="WEP Key1 Data" type="string" relevant="SecurityMode = 'WEP'">
+        <desc>WEP key data (in format specified by corresponding WEP key format field).</desc>
+      </setting>
+      <setting ref="WEPKey2Length" name="WEP Key2 Length" type="selection" relevant="SecurityMode = 'WEP'">
+        <desc>WEP key length in bits.</desc>
+        <option name="64" value="64"/>
+        <option name="128" value="128"/>
+        <option name="256" value="256"/>
+      </setting>
+      <setting ref="WEPKey2Format" name="WEP Key2 Format" type="selection" relevant="SecurityMode = 'WEP'">
+        <desc>WEP key format.</desc>
+        <option name="ASCII" value="ASCII"/>
+        <option name="Hexadecimal" value="Hexadecimal"/>
+      </setting>
+      <setting ref="WEPKey2Data" name="WEP Key2 Data" type="string" relevant="SecurityMode = 'WEP'">
+        <desc>WEP key data (in format specified by corresponding WEP key format field).</desc>
+      </setting>
+      <setting ref="WEPKey3Length" name="WEP Key3 Length" type="selection" relevant="SecurityMode = 'WEP'">
+        <desc>WEP key length in bits.</desc>
+        <option name="64" value="64"/>
+        <option name="128" value="128"/>
+        <option name="256" value="256"/>
+      </setting>
+      <setting ref="WEPKey3Format" name="WEP Key3 Format" type="selection" relevant="SecurityMode = 'WEP'">
+        <desc>WEP key format.</desc>
+        <option name="ASCII" value="ASCII"/>
+        <option name="Hexadecimal" value="Hexadecimal"/>
+      </setting>
+      <setting ref="WEPKey3Data" name="WEP Key3 Data" type="string" relevant="SecurityMode = 'WEP'">
+        <desc>WEP key data (in format specified by corresponding WEP key format field).</desc>
+      </setting>
+      <setting ref="WEPKey4Length" name="WEP Key4 Length" type="selection" relevant="SecurityMode = 'WEP'">
+        <desc>WEP key length in bits.</desc>
+        <option name="64" value="64"/>
+        <option name="128" value="128"/>
+        <option name="256" value="256"/>
+      </setting>
+      <setting ref="WEPKey4Format" name="WEP Key4 Format" type="selection" relevant="SecurityMode = 'WEP'">
+        <desc>WEP key format.</desc>
+        <option name="ASCII" value="ASCII"/>
+        <option name="Hexadecimal" value="Hexadecimal"/>
+      </setting>
+      <setting ref="WEPKey4Data" name="WEP Key4 Data" type="string" relevant="SecurityMode = 'WEP'">
+        <desc>WEP key data (in format specified by corresponding WEP key format field).</desc>
+      </setting>
+
+      <setting ref="WPAUseOfPresharedKey" name="WPA Use of Pre-shared Key" type="selection" relevant="SecurityMode = 'WPA' or SecurityMode = 'WPA2'">
+        <desc>Specifies that when the security mode is WPA or WPA2 if the PSK mode is enabled. 
+        If this is off then EAP mode is used and the list of EAPs needs to be defined.</desc>
+        <option name="No" value="No"/>
+        <option name="Yes" value="Yes"/>
+      </setting>
+      <setting ref="WPAKeyLength" name="WPA Pre-shared key length" relevant="WPAUseOfPresharedKey ='Yes'">
+        <desc>The length of the specified pre-shared key (in WPA pre-shared key field)</desc>
+      </setting>
+        <setting ref="WPAPresharedKey" name="WPA Pre-shared Key" type="string" relevant="WPAUseOfPresharedKey ='Yes'">
+        <desc>WPA/WPA2 pre-shared key in plain text. ASCII character set values between 32-126 must be used. Minimum length is 8 characters and maximum 63.
+        You need to also define the WPA pre-shared key length field accordingly</desc>
+
+      </setting>
+          <setting ref="CTD_EAPkey1" name="EAP Key 1" type="selection" relevant="WPAUseOfPresharedKey ='No'">
+        <desc>Eap Key 1</desc>
+        <option name="EAP-SIM Active" value="EAP-SIM Active"/>
+        <option name="EAP-AKA Active" value="EAP-AKA Active"/>
+        <option name="EAP-TLS Active" value="EAP-TLS Active"/>
+        <option name="EAP-PEA ActiveP" value="EAP-PEAP Active"/>
+        <option name="EAP-TTLS Active" value="EAP-TTLS Active"/>
+        <option name="EAP-LEAP Active" value="EAP-LEAP Active"/>
+        <option name="EAP-FAST Active" value="EAP-FAST Active"/>
+                <option name="EAP-SIM Inactive" value="EAP-SIM Inactive"/>
+        <option name="EAP-AKA Inactive" value="EAP-AKA Inactive"/>
+        <option name="EAP-TLS Inactive" value="EAP-TLS Inactive"/>
+        <option name="EAP-PEAP Inactive" value="EAP-PEAP Inactive"/>
+        <option name="EAP-TTLS Inactive" value="EAP-TTLS Inactive"/>
+        <option name="EAP-LEAP Inactive" value="EAP-LEAP Inactive"/>
+        <option name="EAP-FAST Inactive" value="EAP-FAST Inactive"/>
+      </setting>
+          <setting ref="CTD_EAPkey2" name="EAP Key 2" type="selection" relevant="WPAUseOfPresharedKey ='No'">
+        <desc>Eap Key 1</desc>
+        <option name="EAP-SIM Active" value="EAP-SIM Active"/>
+        <option name="EAP-AKA Active" value="EAP-AKA Active"/>
+        <option name="EAP-TLS Active" value="EAP-TLS Active"/>
+        <option name="EAP-PEA ActiveP" value="EAP-PEAP Active"/>
+        <option name="EAP-TTLS Active" value="EAP-TTLS Active"/>
+        <option name="EAP-LEAP Active" value="EAP-LEAP Active"/>
+        <option name="EAP-FAST Active" value="EAP-FAST Active"/>
+                <option name="EAP-SIM Inactive" value="EAP-SIM Inactive"/>
+        <option name="EAP-AKA Inactive" value="EAP-AKA Inactive"/>
+        <option name="EAP-TLS Inactive" value="EAP-TLS Inactive"/>
+        <option name="EAP-PEAP Inactive" value="EAP-PEAP Inactive"/>
+        <option name="EAP-TTLS Inactive" value="EAP-TTLS Inactive"/>
+        <option name="EAP-LEAP Inactive" value="EAP-LEAP Inactive"/>
+        <option name="EAP-FAST Inactive" value="EAP-FAST Inactive"/>
+      </setting>
+                <setting ref="CTD_EAPkey3" name="EAP Key 3" type="selection" relevant="WPAUseOfPresharedKey ='No'">
+        <desc>Eap Key 1</desc>
+        <option name="EAP-SIM Active" value="EAP-SIM Active"/>
+        <option name="EAP-AKA Active" value="EAP-AKA Active"/>
+        <option name="EAP-TLS Active" value="EAP-TLS Active"/>
+        <option name="EAP-PEA ActiveP" value="EAP-PEAP Active"/>
+        <option name="EAP-TTLS Active" value="EAP-TTLS Active"/>
+        <option name="EAP-LEAP Active" value="EAP-LEAP Active"/>
+        <option name="EAP-FAST Active" value="EAP-FAST Active"/>
+                <option name="EAP-SIM Inactive" value="EAP-SIM Inactive"/>
+        <option name="EAP-AKA Inactive" value="EAP-AKA Inactive"/>
+        <option name="EAP-TLS Inactive" value="EAP-TLS Inactive"/>
+        <option name="EAP-PEAP Inactive" value="EAP-PEAP Inactive"/>
+        <option name="EAP-TTLS Inactive" value="EAP-TTLS Inactive"/>
+        <option name="EAP-LEAP Inactive" value="EAP-LEAP Inactive"/>
+        <option name="EAP-FAST Inactive" value="EAP-FAST Inactive"/>
+      </setting>
+                <setting ref="CTD_EAPkey4" name="EAP Key 4" type="selection" relevant="WPAUseOfPresharedKey ='No'">
+        <desc>Eap Key 1</desc>
+        <option name="EAP-SIM Active" value="EAP-SIM Active"/>
+        <option name="EAP-AKA Active" value="EAP-AKA Active"/>
+        <option name="EAP-TLS Active" value="EAP-TLS Active"/>
+        <option name="EAP-PEA ActiveP" value="EAP-PEAP Active"/>
+        <option name="EAP-TTLS Active" value="EAP-TTLS Active"/>
+        <option name="EAP-LEAP Active" value="EAP-LEAP Active"/>
+        <option name="EAP-FAST Active" value="EAP-FAST Active"/>
+                <option name="EAP-SIM Inactive" value="EAP-SIM Inactive"/>
+        <option name="EAP-AKA Inactive" value="EAP-AKA Inactive"/>
+        <option name="EAP-TLS Inactive" value="EAP-TLS Inactive"/>
+        <option name="EAP-PEAP Inactive" value="EAP-PEAP Inactive"/>
+        <option name="EAP-TTLS Inactive" value="EAP-TTLS Inactive"/>
+        <option name="EAP-LEAP Inactive" value="EAP-LEAP Inactive"/>
+        <option name="EAP-FAST Inactive" value="EAP-FAST Inactive"/>
+      </setting>
+                <setting ref="CTD_EAPkey5" name="EAP Key 5" type="selection" relevant="WPAUseOfPresharedKey ='No'">
+        <desc>Eap Key 1</desc>
+        <option name="EAP-SIM Active" value="EAP-SIM Active"/>
+        <option name="EAP-AKA Active" value="EAP-AKA Active"/>
+        <option name="EAP-TLS Active" value="EAP-TLS Active"/>
+        <option name="EAP-PEA ActiveP" value="EAP-PEAP Active"/>
+        <option name="EAP-TTLS Active" value="EAP-TTLS Active"/>
+        <option name="EAP-LEAP Active" value="EAP-LEAP Active"/>
+        <option name="EAP-FAST Active" value="EAP-FAST Active"/>
+                <option name="EAP-SIM Inactive" value="EAP-SIM Inactive"/>
+        <option name="EAP-AKA Inactive" value="EAP-AKA Inactive"/>
+        <option name="EAP-TLS Inactive" value="EAP-TLS Inactive"/>
+        <option name="EAP-PEAP Inactive" value="EAP-PEAP Inactive"/>
+        <option name="EAP-TTLS Inactive" value="EAP-TTLS Inactive"/>
+        <option name="EAP-LEAP Inactive" value="EAP-LEAP Inactive"/>
+        <option name="EAP-FAST Inactive" value="EAP-FAST Inactive"/>
+      </setting>
+                <setting ref="CTD_EAPkey6" name="EAP Key 6" type="selection" relevant="WPAUseOfPresharedKey ='No'">
+        <desc>Eap Key 1</desc>
+        <option name="EAP-SIM Active" value="EAP-SIM Active"/>
+        <option name="EAP-AKA Active" value="EAP-AKA Active"/>
+        <option name="EAP-TLS Active" value="EAP-TLS Active"/>
+        <option name="EAP-PEA ActiveP" value="EAP-PEAP Active"/>
+        <option name="EAP-TTLS Active" value="EAP-TTLS Active"/>
+        <option name="EAP-LEAP Active" value="EAP-LEAP Active"/>
+        <option name="EAP-FAST Active" value="EAP-FAST Active"/>
+                <option name="EAP-SIM Inactive" value="EAP-SIM Inactive"/>
+        <option name="EAP-AKA Inactive" value="EAP-AKA Inactive"/>
+        <option name="EAP-TLS Inactive" value="EAP-TLS Inactive"/>
+        <option name="EAP-PEAP Inactive" value="EAP-PEAP Inactive"/>
+        <option name="EAP-TTLS Inactive" value="EAP-TTLS Inactive"/>
+        <option name="EAP-LEAP Inactive" value="EAP-LEAP Inactive"/>
+        <option name="EAP-FAST Inactive" value="EAP-FAST Inactive"/>
+      </setting>
+                <setting ref="CTD_EAPkey7" name="EAP Key 7" type="selection" relevant="WPAUseOfPresharedKey ='No'">
+        <desc>Eap Key 1</desc>
+        <option name="EAP-SIM Active" value="EAP-SIM Active"/>
+        <option name="EAP-AKA Active" value="EAP-AKA Active"/>
+        <option name="EAP-TLS Active" value="EAP-TLS Active"/>
+        <option name="EAP-PEA ActiveP" value="EAP-PEAP Active"/>
+        <option name="EAP-TTLS Active" value="EAP-TTLS Active"/>
+        <option name="EAP-LEAP Active" value="EAP-LEAP Active"/>
+        <option name="EAP-FAST Active" value="EAP-FAST Active"/>
+                <option name="EAP-SIM Inactive" value="EAP-SIM Inactive"/>
+        <option name="EAP-AKA Inactive" value="EAP-AKA Inactive"/>
+        <option name="EAP-TLS Inactive" value="EAP-TLS Inactive"/>
+        <option name="EAP-PEAP Inactive" value="EAP-PEAP Inactive"/>
+        <option name="EAP-TTLS Inactive" value="EAP-TTLS Inactive"/>
+        <option name="EAP-LEAP Inactive" value="EAP-LEAP Inactive"/>
+        <option name="EAP-FAST Inactive" value="EAP-FAST Inactive"/>
+      </setting>      
+      </setting>
+  </feature>
+  <data>
+
+    <CTD_APs>
+      <AP template="true">
+        <Seamlessness>ConfirmFirst</Seamlessness>
+        <NetworkType>IPv4</NetworkType>
+        <PromptPassword>No</PromptPassword>
+        <PasswordAuthenticationType>Normal</PasswordAuthenticationType>
+      </AP>
+    </CTD_APs>
+
+
+    <CTD_WLAN_APs>
+      <WLAN_AP template="true">
+        <Seamlessness>ConfirmFirst</Seamlessness>
+        <NetworkMode>Infrastructure</NetworkMode>
+        <SecurityMode>Open</SecurityMode>
+        <WPAKeyLength>0</WPAKeyLength>
+      </WLAN_AP>
+    </CTD_WLAN_APs>
+ </data>
+</configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/ruleproject/ctd/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,3 @@
+<configuration name="imaker" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
+  <xi:include href="confml/CTD_commsdat.confml" />
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/ruleproject/layer1/.metadata	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="ASCII"?>
+<metadata xmlns="http://www.nokia.com/xml/ns/confml-core/metadata-2.0">
+  <property name="cpf.rootFile" value="root.confml" />
+</metadata>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/ruleproject/layer1/confml/ap.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,21 @@
+<configuration name="Eval test data" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
+  <feature ref="APIDCTest" name="Test settings for accesspoint id count">
+    <setting ref="FullSequence" name="Full sequence" type="sequence">
+      <setting ref="StringSubSetting" name="String sub-setting" type="string"/>
+    </setting>
+  </feature>
+  
+  <data>
+    <APIDCTest>
+      <FullSequence template="true">
+        <StringSubSetting>Default</StringSubSetting>
+      </FullSequence>
+      <FullSequence>
+        <StringSubSetting>Full 1</StringSubSetting>
+      </FullSequence>
+      <FullSequence>
+        <StringSubSetting>Full 2</StringSubSetting>
+      </FullSequence>
+    </APIDCTest>
+  </data>
+</configuration>
Binary file configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/ruleproject/layer1/confml/commsdatcreator.confml has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/ruleproject/layer1/confml/testdata.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration name="imaker interface" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
+  <feature name="iMaker Image creation" ref="imaker">
+    <setting name="IMAGE_TARGET" ref="imagetarget" type="selection">
+      <option name="core" value="0" />
+    <option name="rofs2" value="1" />
+    <option name="rofs3" value="2" />
+    <option name="rofs4" value="3" />
+    <option name="uda" value="4" />
+    <option name="rofs3_uda" value="4" />
+    </setting>
+  <setting name="iMaker api makefile" ref="makefilename" type="string" />
+  </feature>
+<feature name="iMaker API" ref="imakerapi">
+    <setting name="IMAGE_TYPE" ref="imagetype" type="selection">
+      <option name="rnd" value="0" />
+    <option name="subcon" value="1" />
+    <option name="prd" value="2" />
+    </setting>
+  <setting name="ROFS3_VERSION" ref="rofs3version" type="string" />
+  <setting name="PRODUCT_NAME" ref="productname" type="string" />
+  <setting name="OUTPUT_LOCATION" ref="outputLocation" type="string" />
+  <setting name="OUTPUT_LOCATIONY" ref="outputLocationY" type="string" />
+  </feature>
+<feature name="ar operations" ref="operations">
+    <setting name="MINUS" ref="minus" type="int" />
+  <setting name="MINUS1" ref="minus1" type="int" />
+  <setting name="MINUS2" ref="minus2" type="int" />
+  <setting name="MINUS3" ref="minus3" type="int" />
+  <setting name="MINUS4" ref="minus4" type="int" />
+  <setting name="MINUS5" ref="minus5" type="int" />
+  <setting name="MINUS6" ref="minus6" type="int" />
+  <setting name="MINUS7" ref="minus7" type="int" />
+  <setting name="MINUS8" ref="minus8" type="int" />
+  </feature>
+<feature name="String concatenation test" ref="StringConcatenationTest">
+    <setting name="Value 1" ref="Value1" type="string" />
+  <setting name="Value 2" ref="Value2" type="string" />
+  <setting name="Result 1" ref="Result1" type="string" />
+  <setting name="Result 2" ref="Result2" type="string" />
+  <setting name="Result 3" ref="Result3" type="string" />
+  <setting name="Result 4" ref="Result4" type="string" />
+  <setting name="Result 5" ref="Result5" type="string" />
+  <setting name="Result 6" ref="Result6" type="string" />
+  </feature>
+<feature name="Unicode test feature" ref="ударениÑ">
+    <setting name="Unicode test setting" ref="ελληνικά" type="string" />
+  </feature>
+<data>
+    <imaker>
+      <imagetarget>2</imagetarget>
+    <makefilename>image_conf_imakerapi.mk</makefilename>
+    </imaker>
+  <imakerapi>
+      <imagetype>0</imagetype>
+    <rofs3version>V .50.2009.04.0113 RND</rofs3version>
+    <productname>myProduct</productname>
+    <outputLocation>myProduct</outputLocation>
+    <outputLocationY />
+    </imakerapi>
+  <operations>
+      <minus>5</minus>
+    <minus1>25</minus1>
+    <minus2>7</minus2>
+    <minus3>5</minus3>
+    <minus4>10</minus4>
+    <minus5>2</minus5>
+    <minus6>5</minus6>
+    <minus7>10</minus7>
+    <minus8>8</minus8>
+    </operations>
+  <StringConcatenationTest>
+      <Value1>String 1</Value1>
+    <Value2>String 2</Value2>
+    <Result1>x</Result1>
+    <Result2>x</Result2>
+    <Result3>x</Result3>
+    <Result4>x</Result4>
+    <Result5>x</Result5>
+    <Result6>x</Result6>
+    </StringConcatenationTest>
+    
+    <ударениÑ>
+      <ελληνικά>カタカナ</ελληνικά>
+    </ударениÑ>
+  </data>
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/ruleproject/layer1/implml/accesspoint_id_counter.ruleml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ruleml xmlns="http://www.s60.com/xml/ruleml/2">
+	<rule>True configures APIDCTest.FullSequence.StringSubSetting = {% apid( @{APs}, @{DNs} ) %}
+    </rule>
+	<eval_globals file="../../accesspoint_id_counter.py"/>
+</ruleml>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/ruleproject/layer1/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,5 @@
+<configuration name="imaker" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
+  <xi:include href="confml/testdata.confml" />
+  <xi:include href="confml/ap.confml" />
+  <xi:include href="confml/commsdatcreator.confml" />
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/ruleproject/layer2/.metadata	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="ASCII"?>
+<metadata xmlns="http://www.nokia.com/xml/ns/confml-core/metadata-2.0">
+  <property name="cpf.rootFile" value="root.confml" />
+</metadata>
\ No newline at end of file
Binary file configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/ruleproject/layer2/confml/data.confml has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/ruleproject/layer2/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,3 @@
+<configuration name="imaker" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
+  <xi:include href="confml/data.confml" />
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/ruleproject/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<configuration name="imaker" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
+  <xi:include href="layer1/root.confml" />
+  <xi:include href="layer2/root.confml" />
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/runtests.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,19 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+if __name__ == '__main__':
+    import nose
+    nose.core.run(argv=['collector','--include=unittest', '--verbosity=3'])
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/unittest_accesspoint_id_counter.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,123 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+import unittest
+import os, shutil
+import sys
+import pkg_resources
+import re
+
+from legacyruleplugin import ruleml, relations
+from cone.public import api, exceptions
+from legacyruleplugin.evals import accesspoint_id_counter
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+class TestAPIDC(unittest.TestCase):
+    def test_get_ApDnContainer(self):
+        project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'ruleproject')))
+        config = project.get_configuration('root.confml')
+        dview = config.get_default_view()
+        
+        container = accesspoint_id_counter._get_ApDnContainer_(dview.get_feature("APs"), dview.get_feature("DNs"), True)
+        
+        self.assertEquals('Internet', container.get_all_dns()[0].get_name())
+        self.assertEquals('1', container.get_all_dns()[0].get_id())
+        self.assertEquals(['IAP11', 'IAP12', 'IAP13', None, None, None, None, None, None, None], container.get_all_dns()[0].get_iaps())
+        
+        self.assertEquals('MMS', container.get_all_dns()[1].get_name())
+        self.assertEquals('2', container.get_all_dns()[1].get_id())
+        self.assertEquals(['IAP21', 'IAP22', 'IAP23', 'IAP13', None, None, None, None, None, None], container.get_all_dns()[1].get_iaps())
+        
+        self.assertEquals('Operator', container.get_all_dns()[2].get_name())
+        self.assertEquals('3', container.get_all_dns()[2].get_id())
+        self.assertEquals(['IAP31', 'IAP32', 'IAP33', None, None, None, None, None, None, None], container.get_all_dns()[2].get_iaps())
+
+        self.assertEquals('IAP11', container.get_all_aps()[0].get_name())
+        self.assertEquals('1', container.get_all_aps()[0].get_id())
+        
+    def test_get_apid_by_apname(self):
+        project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'ruleproject')))
+        config = project.get_configuration('root.confml')
+        dview = config.get_default_view()
+        
+        container = accesspoint_id_counter._get_ApDnContainer_(dview.get_feature("APs"), dview.get_feature("DNs"), True)
+        
+        self.assertEquals('1', container.get_apid_by_apname('IAP11'))
+        self.assertEquals('2', container.get_apid_by_apname('IAP12'))
+        self.assertEquals('7', container.get_apid_by_apname('IAP13'))
+
+    def test_get_dnid_by_dnname(self):
+        project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'ruleproject')))
+        config = project.get_configuration('root.confml')
+        dview = config.get_default_view()
+        
+        container = accesspoint_id_counter._get_ApDnContainer_(dview.get_feature("APs"), dview.get_feature("DNs"), True)
+        
+        self.assertEquals('1', container.get_dnid_by_dnname('Internet'))
+        self.assertEquals('2', container.get_dnid_by_dnname('MMS'))
+        self.assertEquals('3', container.get_dnid_by_dnname('Operator'))
+
+
+    def test_get_apid_by_dnname_and_apname(self):
+        project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'ruleproject')))
+        config = project.get_configuration('root.confml')
+        dview = config.get_default_view()
+        
+        container = accesspoint_id_counter._get_ApDnContainer_(dview.get_feature("APs"), dview.get_feature("DNs"), True)
+        
+        self.assertEquals('2', container.get_apid_by_dnname_and_apname('Internet', 'IAP12'))
+
+    def test_calc_ap_ids(self):
+        project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'ruleproject')))
+        config = project.get_configuration('root.confml')
+        dview = config.get_default_view()
+        
+        container = accesspoint_id_counter._get_ApDnContainer_(dview.get_feature("APs"), dview.get_feature("DNs"), True)
+
+        self.assertEquals('9', container.get_all_aps()[6].get_id())
+
+    def test_all_in_array(self):
+        project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'ruleproject')))
+        config = project.get_configuration('root.confml')
+        dview = config.get_default_view()
+        
+        container = accesspoint_id_counter._get_ApDnContainer_(dview.get_feature("APs"), dview.get_feature("DNs"), True)
+
+        self.assertEquals(container.get_all_in_array(), [['Internet', '1', ['IAP11', 'IAP12', 'IAP13', None, None, None, None, None, None, None], ['1', '2', '7', None, None, None, None, None, None, None], ['1', '2', '3', None, None, None, None, None, None, None]], ['MMS', '2', ['IAP21', 'IAP22', 'IAP23', 'IAP13', None, None, None, None, None, None], ['4', '8', '6', '7', None, None, None, None, None, None], ['4', '5', '6', '3', None, None, None, None, None, None]], ['Operator', '3', ['IAP31', 'IAP32', 'IAP33', None, None, None, None, None, None, None], [None, None, '9', None, None, None, None, None, None, None], [None, None, '7', None, None, None, None, None, None, None]]])
+
+    def test_get_next_free_id(self):
+        project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'ruleproject')))
+        config = project.get_configuration('root.confml')
+        dview = config.get_default_view()
+        
+        container = accesspoint_id_counter._get_ApDnContainer_(dview.get_feature("APs"), dview.get_feature("DNs"), True)
+        
+        self.assertEquals("4", accesspoint_id_counter._get_next_free_id_(container.get_all_dns()))
+        self.assertEquals("10", accesspoint_id_counter._get_next_free_id_(container.get_all_aps()))
+
+    def test_get_apindex_by_apname(self):
+        project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'ruleproject')))
+        config = project.get_configuration('root.confml')
+        dview = config.get_default_view()
+        
+        container = accesspoint_id_counter._get_ApDnContainer_(dview.get_feature("APs"), dview.get_feature("DNs"), True)
+        
+        self.assertEquals("4", container.get_apindex_by_apname("IAP21"))
+        self.assertEquals("1", container.get_apindex_by_apname("IAP11"))
+
+        
+if __name__ == "__main__":
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/evals/tests/unittest_layer_utils.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,90 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+import unittest
+import os, shutil
+import sys
+import pkg_resources
+import re
+import logging
+
+from legacyruleplugin import ruleml, relations
+from cone.public import api, exceptions
+from legacyruleplugin.evals import layer_utils
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+#logger = logging.getLogger("cone.ruleplugin.evals.layer_utils")
+#logger.setLevel(logging.DEBUG)
+#ch = logging.StreamHandler()
+#ch.setLevel(logging.DEBUG)
+#logger.addHandler(ch)
+
+class TestLayerUtils(unittest.TestCase):
+    def setUp(self):
+        pass
+    
+    def test_give_changed_layers(self):
+        project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'layerproject')))
+        config = project.get_configuration('root.confml')
+        dview = config.get_default_view()
+        
+        self.assertEquals(layer_utils.give_changed_layers(dview.get_feature("StringFeatureTest.Value1")), [True, True, True, True, True])
+        self.assertEquals(layer_utils.give_changed_layers(dview.get_feature("StringFeatureTest.Value2")), [False, True, True, False, False])
+        
+    def test_changed_on_last_layer(self):
+        project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'layerproject')))
+        config = project.get_configuration('root.confml')
+        dview = config.get_default_view()
+        
+        self.assertTrue(layer_utils.changed_on_last_layer(dview.get_feature("StringFeatureTest.Value1")))
+        self.assertFalse(layer_utils.changed_on_last_layer(dview.get_feature("StringFeatureTest.Value2")))
+
+    def test_changed_on_layer(self):
+        project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'layerproject')))
+        config = project.get_configuration('root.confml')
+        dview = config.get_default_view()
+        
+        self.assertTrue(layer_utils.changed_on_layer(dview.get_feature("StringFeatureTest.Value1"),-1))
+        self.assertTrue(layer_utils.changed_on_layer(dview.get_feature("StringFeatureTest.Value1"),0))
+        self.assertTrue(layer_utils.changed_on_layer(dview.get_feature("StringFeatureTest.Value1"),1))
+        self.assertTrue(layer_utils.changed_on_layer(dview.get_feature("StringFeatureTest.Value1"),2))
+        self.assertTrue(layer_utils.changed_on_layer(dview.get_feature("StringFeatureTest.Value1"),3))
+        self.assertTrue(layer_utils.changed_on_layer(dview.get_feature("StringFeatureTest.Value1"),4))
+        self.assertFalse(layer_utils.changed_on_layer(dview.get_feature("StringFeatureTest.Value1"),5))
+        self.assertFalse(layer_utils.changed_on_layer(dview.get_feature("StringFeatureTest.Value2"),-1))
+        self.assertFalse(layer_utils.changed_on_layer(dview.get_feature("StringFeatureTest.Value2"),0))
+        self.assertTrue(layer_utils.changed_on_layer(dview.get_feature("StringFeatureTest.Value2"),1))
+        self.assertTrue(layer_utils.changed_on_layer(dview.get_feature("StringFeatureTest.Value2"),2))
+        self.assertFalse(layer_utils.changed_on_layer(dview.get_feature("StringFeatureTest.Value2"),3))
+        self.assertFalse(layer_utils.changed_on_layer(dview.get_feature("StringFeatureTest.Value2"),4))
+        self.assertFalse(layer_utils.changed_on_layer(dview.get_feature("StringFeatureTest.Value2"),5))
+
+    def test_changed_on_layers(self):
+        project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'layerproject')))
+        config = project.get_configuration('root.confml')
+        dview = config.get_default_view()
+        
+        self.assertTrue(layer_utils.changed_on_layers(dview.get_feature("StringFeatureTest.Value1"),0,4))
+        self.assertTrue(layer_utils.changed_on_layers(dview.get_feature("StringFeatureTest.Value1"),2,3))
+        self.assertTrue(layer_utils.changed_on_layers(dview.get_feature("StringFeatureTest.Value1"),2,2))
+        self.assertTrue(layer_utils.changed_on_layers(dview.get_feature("StringFeatureTest.Value1"),1,7))
+        self.assertFalse(layer_utils.changed_on_layers(dview.get_feature("StringFeatureTest.Value1"),8,9))
+        self.assertFalse(layer_utils.changed_on_layers(dview.get_feature("StringFeatureTest.Value2"),0,1))
+        self.assertTrue(layer_utils.changed_on_layers(dview.get_feature("StringFeatureTest.Value2"),1,5))
+
+        
+if __name__ == "__main__":
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/relations.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,391 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+'''
+implementation for ruleml relations.
+'''
+import os
+import StringIO
+import logging
+import operator as ops
+import re
+import sys, traceback
+
+log = logging.getLogger('cone.ruleplugin.relations')
+
+from legacyruleplugin import rules
+from cone.public import api, utils, exceptions, plugin
+
+class RelationFactory(api.FactoryBase):
+    @ classmethod
+    def get_relation_by_name(cls, relation_name):
+        """
+        Get the class name by file extension.
+        """
+        try:
+            return rules.RELATIONS.get(relation_name)
+        except KeyError:
+            raise exceptions.NotSupportedException("No Relation class found for name %s" % relation_name)
+
+    @ classmethod
+    def get_relations(cls, configuration, relation):
+        try:
+            relations = []
+            (left_expression,relation_name,right_expression) = parse_rule(relation)
+            relation = cls.get_relation_by_name(relation_name)(configuration, left_expression, right_expression)
+            relations.append(relation)
+            propagated_relations = cls.get_relations(configuration, right_expression)
+            if propagated_relations:
+                for relation in propagated_relations:
+                    relations.append(relation)
+            return relations
+        except exceptions.ParseError:
+            return None
+    
+
+class ConfigurationContext(rules.DefaultContext):
+    
+    def __init__(self, data):
+        rules.DefaultContext.__init__(self, data)
+        
+        # Callback called with the setting reference when a setting is dereferenced
+        # as a terminal expression
+        self.ref_terminal_callback = None
+        
+        # Callback called with the setting reference when a setting is dereferenced
+        # inside an EvalExpression
+        self.ref_eval_callback = None
+        
+        # Callback called with the setting reference when the value of a setting
+        # is set inside a SetExpression
+        self.ref_set_callback = None
+        
+    def handle_terminal(self, expression):
+        try:
+            value = self.data.get_default_view().get_feature(expression).get_value()
+            
+            # Got a valid ref, call the callback
+            if self.ref_terminal_callback:
+                self.ref_terminal_callback(expression)
+            
+            return value
+        except exceptions.NotFound,e:
+            """ return the expression itself if it is not a fearef """
+            #print "handle_terminal constant %s" % (expression)
+            try:
+                return eval(expression)
+            except (NameError,SyntaxError), e:
+                return expression
+
+    def eval(self, ast, expression, value):
+        #print "expression %s = %s" % (expression,value)
+        pass
+        
+class ConfigurationBaseRelation(rules.BaseRelation):
+    def __init__(self, data, left, right):
+        self.context = ConfigurationContext(data)
+        super(ConfigurationBaseRelation, self).__init__(data, left, right)
+
+class RequireRelation(ConfigurationBaseRelation):
+    KEY = 'requires'
+    def __init__(self, data, left, right):
+        super(RequireRelation, self).__init__(data, left, right)
+        self.context = ConfigurationContext(data)
+
+class ConfigureRelation(ConfigurationBaseRelation):
+    KEY = 'configures'
+    def __init__(self, data, left, right):
+        self.context = ConfigurationContext(data)
+        super(ConfigureRelation, self).__init__(data, left, right)
+        
+        # A plugin.RelationExecutionResult object is stored here
+        self._execution_result = None
+        
+    
+    def execute(self, context=None):
+        self._execution_result = None
+        exec_results = []
+        
+        result = rules.BaseRelation.execute(self, context)
+        
+        if len(exec_results) > 0:
+            # There should be only one ConfigureExpression inside a ConfigureRelation
+            if len(exec_results) > 1:
+                log.warning("Execution of ConfigureRelation returned more than one result, ignoring all except the first")
+            self._execution_result = exec_results[0]
+        
+        return result
+    
+    def get_execution_result(self):
+        """
+        Return the execution result from the most recent call to execute().
+        """
+        return self._execution_result
+
+def handle_configure(self, left, right):
+    if left and right:
+        return True
+    elif not left:
+        return True
+    return False
+
+def handle_set(self, left, right):
+    left.set_value(right)
+
+def handle_filenamejoin(self, left, right):
+    def extract_dirname(path):
+        """Extract directory name (will always contain a trailing slash or backslash)"""
+        pos = max(path.rfind('/'), path.rfind('\\'))
+        if pos == -1:   return path + '/'
+        else:           return path[:pos + 1]
+    
+    def extract_filename(path):
+        pos = max(path.rfind('/'), path.rfind('\\'))
+        if pos == -1:   return path
+        else:           return path[pos + 1:]
+    
+    return extract_dirname(left) + extract_filename(right)
+
+def handle_plus(self, left, right):
+    return left + right
+
+def handle_minus(self, left, right):
+    return left - right
+
+def handle_multiply(self, left, right):
+    return left * right
+
+def handle_divide(self, left, right):
+    return left / right
+
+class ConfigureExpression(rules.TwoOperatorExpression):
+    PRECEDENCE = rules.PRECEDENCES['RELATION_OPERATORS']
+    KEY = 'configures'
+    OP = handle_configure
+
+    def eval(self, context, **kwargs):
+        input_refs = []
+        affected_refs = []
+        
+        # Evaluate the left-hand side expression, catching refs for the result
+        try:
+            context.ref_terminal_callback = lambda ref: input_refs.append(ref)
+            context.ref_eval_callback = lambda ref: input_refs.append(ref)
+            evaluated_left = self.left.eval(context, **kwargs)
+        finally:
+            context.ref_terminal_callback = None
+            context.ref_eval_callback = None
+        
+        if evaluated_left:
+            # If left evaluated to True, evaluate the right-hand side and
+            # catch refs from SetExpression evaluations
+            try:
+                context.ref_set_callback = lambda ref: affected_refs.append(ref)
+                self.value = self.right.eval(context, **kwargs)
+            finally:
+                context.ref_set_callback = None
+        else:
+            self.value = True
+        
+        if not self.value:
+            left_keys = []
+            for ref in self.ast.extract_refs(str(self.left)):
+                for key in context.get_keys(ref):
+                    left_keys.append(key)
+
+            for key in left_keys:
+                self.ast.add_error(key, { 'error_string' : 'CONFIGURES right side value is "False"',
+                                          'left_key' : key,
+                                          'rule' : self.ast.expression
+                                          })
+        
+        return self.value
+
+class MultiplyExpression(rules.TwoOperatorExpression):
+    expression = "multiply_operation"
+    PRECEDENCE = rules.PRECEDENCES['MULDIV_OPERATORS']
+    KEY= '*'
+    OP = handle_multiply
+
+class DivideExpression(rules.TwoOperatorExpression):
+    expression = "divide_operation"
+    PRECEDENCE = rules.PRECEDENCES['MULDIV_OPERATORS']
+    KEY= '/'
+    OP = handle_divide
+
+class PlusExpression(rules.TwoOperatorExpression):
+    expression = "plus_operation"
+    PRECEDENCE = rules.PRECEDENCES['ADDSUB_OPERATORS']
+    KEY= '+'
+    OP = handle_plus
+
+class MinusExpression(rules.TwoOperatorExpression):
+    expression = "minus_operation"
+    PRECEDENCE = rules.PRECEDENCES['ADDSUB_OPERATORS']
+    KEY= '-'
+    OP = handle_minus
+
+class EvalExpression(rules.OneParamExpression):
+    expression = "__eval__"
+    PRECEDENCE = rules.PRECEDENCES['PREFIX_OPERATORS']
+    KEY = '__eval__'
+    
+    def __init__(self, ast, expression):
+        super(EvalExpression, self).__init__(ast, expression)
+        self.expression = expression
+        self._str_to_eval = eval(expression.expression)
+        #self.default_view = default_view
+    
+    def extract_refs(self):
+        result = []
+        result.extend(utils.extract_delimited_tokens(self._str_to_eval, delimiters=('${', '}')))
+        result.extend(utils.extract_delimited_tokens(self._str_to_eval, delimiters=('@{', '}')))
+        return result
+    
+    def eval(self, context, **kwargs):
+        # Using the configuration to pass the eval globals dictionary to here,
+        # since there isn't any easy way to do this more elegantly
+        globals_and_locals = {}
+        if hasattr(context, '_eval_expression_globals_dict'):
+            globals_and_locals = context._eval_expression_globals_dict
+        
+        str_to_eval = self._str_to_eval
+        
+        def expand_feature_ref(ref, index):
+            var_name = "__fea_%05d" % index
+            globals_and_locals[var_name] = context.configuration.get_default_view().get_feature(ref)
+            if context.ref_eval_callback:
+                context.ref_eval_callback(ref)
+            return var_name
+        def expand_value_ref(ref, index):
+            var_name = "__feaval_%05d" % index
+            globals_and_locals[var_name] = context.configuration.get_default_view().get_feature(ref).get_value()
+            if context.ref_eval_callback:
+                context.ref_eval_callback(ref)
+            return var_name
+        
+        str_to_eval = utils.expand_delimited_tokens(str_to_eval, expand_feature_ref, delimiters=('@{', '}'))
+        str_to_eval = utils.expand_delimited_tokens(str_to_eval, expand_value_ref, delimiters=('${', '}'))
+        
+        # Strip leading and trailing whitespace to avoid indentation problems
+        str_to_eval = str_to_eval.strip()
+        
+        ret = None
+        
+        try:
+            ret = eval(str_to_eval, globals_and_locals)
+            return ret
+        except SyntaxError, e:
+            logging.getLogger('cone.ruleml').warning("Invalid syntax in eval: %s" % (str_to_eval) )
+            self.ast.add_error(self.expression, { 'error_string' : 'Invalid syntax in eval', 'str_to_eval' : str_to_eval, 'rule' : self.ast.expression })
+        except Exception, e:
+            logging.getLogger('cone.ruleml').warning("Execution failed for eval: %s %s: %s" % (str_to_eval, type(e), e) )
+            self.ast.add_error(self.expression, { 'error_string' : 'Execution failed for eval', 'str_to_eval' : str_to_eval, 'rule' : self.ast.expression })
+
+rules.OPERATORS[EvalExpression.KEY] = EvalExpression
+
+class FilenamejoinExpression(rules.TwoOperatorExpression):
+    expression = "filenamejoin"
+    PRECEDENCE = rules.PRECEDENCES['ADDSUB_OPERATORS']
+    KEY = 'filenamejoin'
+    OP = handle_filenamejoin
+    
+rules.OPERATORS[FilenamejoinExpression.KEY] = FilenamejoinExpression
+    
+class SetExpression(rules.TwoOperatorExpression):
+    PRECEDENCE = rules.PRECEDENCES['SET_OPERATORS']
+    KEY= '='
+    OP = handle_set
+
+#    def eval(self, context):
+#        try:
+#            variable = context.configuration.get_default_view().get_feature(self.left.expression)
+#            value = self.right.eval(context)
+#            variable.set_value(value)
+#            logging.getLogger('cone.ruleml').info("Set %r = %r from %r" % (self.left.expression, value, self.right.expression) )
+#            if context.ref_set_callback:
+#                context.ref_set_callback(self.left.expression)
+#            return True
+#        except exceptions.NotFound,e:
+#            self.ast.add_error(self.left.expression, { 'error_string' : 'Setting value failed, because of %s' % e,
+#                               'left_key' : self.left.expression,
+#                               'rule' : self.ast.expression})
+#            return False
+
+    def eval(self, context, **kwargs):
+        
+        value = self.right.eval(context, **kwargs)
+        ref = self.left.get_ref()
+        context.set(ref, value, **kwargs)
+        return True
+
+_relations_and_operators_backup = None
+
+def register():
+    """
+    Register the relations and operators to ConE rules.
+    """
+    global _relations_and_operators_backup
+    if _relations_and_operators_backup is None:
+        # Create the backup copies of the dictionaries
+        rels_backup = rules.RELATIONS.copy()
+        ops_backup = rules.OPERATORS.copy()
+        assert rels_backup is not rules.RELATIONS
+        assert ops_backup is not rules.OPERATORS
+        _relations_and_operators_backup = (rels_backup, ops_backup)
+        
+        # Register relations and operators to rules
+        rules.RELATIONS[RequireRelation.KEY] = RequireRelation
+        rules.RELATIONS[ConfigureRelation.KEY] = ConfigureRelation
+        rules.OPERATORS[ConfigureExpression.KEY] = ConfigureExpression
+        rules.OPERATORS[PlusExpression.KEY] = PlusExpression
+        rules.OPERATORS[SetExpression.KEY] = SetExpression
+        rules.OPERATORS[MinusExpression.KEY] = MinusExpression
+        rules.OPERATORS[MultiplyExpression.KEY] = MultiplyExpression
+        rules.OPERATORS[DivideExpression.KEY] = DivideExpression
+
+def unregister():
+    """
+    Undo the changes made by a call to register().
+    """
+    global _relations_and_operators_backup
+    if _relations_and_operators_backup is not None:
+        rules.RELATIONS = _relations_and_operators_backup[0]
+        rules.OPERATORS = _relations_and_operators_backup[1]
+        _relations_and_operators_backup = None
+
+def parse_rule(rulestring):
+    """
+    Divide the given rule string into (left side, relation, right side) components. 
+    @return: Triple (left side, relation, right side)
+    """
+    left_expression = ''
+    relation_name = None
+    right_expression = ''
+    for token in rules.get_tokens(rulestring):
+        if relation_name == None:
+            if token in rules.RELATIONS.keys():
+                relation_name = token
+            else:
+                left_expression += ' ' + token
+        else:
+            right_expression += ' ' + token
+    
+    if relation_name == None:
+        raise exceptions.ParseError('invalid rule definition %s' % rulestring)
+    
+    return (left_expression,relation_name,right_expression)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/ruleml.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,303 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+'''
+Legacy RuleML plug-in to support RuleML 1 and 2 after rule engine changes
+in cone.public.rules. The new RuleML version is 3, and it uses the setting
+reference format ${MyFeature.MySetting} in the rules.
+
+The rule engine (rules.py) before the change is contained in this plug-in.
+
+NOTE THAT THIS PLUG-IN WILL NOT BE MAINTAINED, ALL NEW DEVELOPMENT SHOULD
+HAPPEN IN THE NEW RULE PLUG-IN. IF NEW FUNCTIONALITY IS REQUIRED IN AN
+EXISTING RULEML FILE, THE CHANGES SHOULD BE MADE TO THE NEW RULE PLUG-IN
+AND THE EXISTING RULEML FILE CONVERTED TO RULEML 3.
+'''
+
+
+import os
+import sys
+import logging
+import shutil
+import pkg_resources
+
+import __init__
+import re
+
+from legacyruleplugin import relations, rules
+from cone.public import exceptions,plugin,utils,api
+
+class RuleImpl(plugin.ImplBase):
+    """
+    MakeImpl plugin finds feature references that are configured in a .ruleml file
+    and generate a rule from them
+    """
+    IMPL_TYPE_ID = 'ruleml'
+    DEFAULT_INVOCATION_PHASE = 'pre'
+    
+    def __init__(self, ref, configuration, relation_container):
+        """
+        Overloading the default constructor
+        """
+        plugin.ImplBase.__init__(self,ref,configuration)
+        self.relation_container = relation_container
+
+    def list_output_files(self):
+        """
+        Return a list of output files as an array. 
+        """
+        return []
+    
+    def generate(self, context=None):
+        relation_container = self.get_relation_container()
+        relation_container.context = context
+        return relation_container.execute(context)
+    
+    def has_tag(self, tags, policy=None):
+        # RuleML should always be executed, regardless of the tags
+        return True
+    
+    def get_relation_container(self):
+        return self.relation_container
+    
+    def get_refs(self):
+        """
+        Return a list of all ConfML setting references that affect this
+        implementation. May also return None if references are not relevant
+        for the implementation.
+        """
+        refs = []
+        relations = self.get_relations()
+        for relation in relations:
+            # get refs from relation return a tuple (left side refs, right side refs)
+            # only the left side refs are the "input" refs  
+            refs += relation.get_refs()
+        # If the rules do not have any references return None to disable filter by refs 
+        if refs == []: 
+            refs = None
+        return refs
+    
+    def get_relations(self):
+        return self.relation_container.get_relations()
+
+class RuleBuiltinsModule(object):
+    pass
+
+class RulemlRelationContainer(plugin.RelationContainer):
+    """
+    Relation container for RuleML rules.
+    
+    Basically this is a wrapper for rules.RelationContainer that adapts
+    it to the interface of plugin.RelationContainer.
+    """
+    def __init__(self, configuration, source, rule_list, eval_globals):
+        plugin.RelationContainer.__init__(self, configuration, source=source)
+        self.configuration = configuration
+        self.relation_container = rules.RelationContainerImpl()
+        self.eval_globals = eval_globals
+        self.context = None
+        for rule in rule_list:
+            self.relation_container.add_relation(rule)
+    
+    def execute(self, context=None):
+        results = []
+        
+        # Create the autoconfig if not done already
+        autoconfig = plugin.get_autoconfig(self.configuration)
+        
+        # Register relations etc. to the rule engine.
+        # Due to unit test issues the relations are not registered
+        # in the relations module, but only for the duration of
+        # rule parsing and execution
+        relations.register()
+        try:
+            # Using the configuration to pass the eval globals dict to the
+            # eval expression. The configuration only contains the globals
+            # dict for the duration of the rule execution, so hopefully this
+            # shouldn't mess anything up
+            self._set_builtin_eval_globals()
+            context._eval_expression_globals_dict = self.eval_globals
+            for i, rel in enumerate(self.relation_container):
+                index = i + 1
+                
+                # Execute
+                self._execute_relation_and_log_error(rel, self.source, index, context)
+                
+                # Collect execution result if supported
+                if hasattr(rel, 'get_execution_result'):
+                    result = rel.get_execution_result()
+                    if isinstance(result, plugin.RelationExecutionResult):
+                        result.source = self.source
+                        result.index = index
+                        results.append(result)
+            
+            del context._eval_expression_globals_dict
+            
+            if self.relation_container.has_errors():
+                for error in self.relation_container.get_errors():
+                    logging.getLogger('cone.ruleml_relation_container(%s)' % self.source).error(error)
+            
+            if self.context:
+                self.context.results += results
+                self.context.add_changed_refs(autoconfig.list_leaf_datas())
+            return results
+        finally:
+            relations.unregister()
+    
+    def get_relation_count(self):
+        return len(self.relation_container)
+    
+    def get_relations(self):
+        return list(self.relation_container)
+    
+    def _set_builtin_eval_globals(self):
+        """
+        Add built-in attributes into the eval globals dictionary.
+        """
+                
+        builtins = RuleBuiltinsModule()
+        builtins.configuration = self.configuration
+        
+        self.eval_globals['ruleml'] = builtins
+
+class RuleImplReaderBase(plugin.ReaderBase):
+    NAMESPACE = None # Used as a base class, so should have no namespace
+    FILE_EXTENSIONS = ['ruleml']
+    
+    def __init__(self, resource_ref, configuration):
+        self.resource_ref = resource_ref
+        self.configuration = configuration
+        
+    @classmethod
+    def read_impl(cls, resource_ref, configuration, etree):
+        reader = cls(resource_ref, configuration)
+        
+        # Register relations etc. to the rule engine.
+        # Due to unit test issues the relations are not registered
+        # in the relations module, but only for the duration of
+        # rule parsing and execution
+        relations.register()
+        try:
+            rules = reader.parse_rules(resource_ref, etree)
+            eval_globals = reader.parse_eval_globals(etree)
+            lineno = utils.etree.get_lineno(etree)
+            
+            # Create an ImplContainer to hold each rule as its own
+            # RuleML implementation
+            main_impl = plugin.ImplContainer(resource_ref, configuration)
+            main_impl.lineno = lineno
+            
+            for rule in rules:
+                relation_container = RulemlRelationContainer(
+                    configuration   = configuration,
+                    source          = "%s:%d" % (resource_ref, rule.lineno),
+                    rule_list       = [rule],
+                    eval_globals    = eval_globals)
+            
+                impl = RuleImpl(resource_ref, configuration, relation_container)
+                impl.lineno = rule.lineno
+                rule.implml = impl
+                
+                main_impl.append(impl)
+        finally:
+            relations.unregister()
+        
+        return main_impl
+        
+class RuleImplReader1(RuleImplReaderBase):
+    NAMESPACE = 'http://www.s60.com/xml/ruleml/1'
+    NAMESPACE_ID = 'ruleml1'
+    ROOT_ELEMENT_NAME = 'ruleml'
+    
+    def __init__(self, resource_ref, configuration):
+        RuleImplReaderBase.__init__(self, resource_ref, configuration)
+    
+    @classmethod
+    def get_schema_data(cls):
+        return pkg_resources.resource_string('legacyruleplugin', 'xsd/ruleml.xsd')
+    
+    def parse_rules(self, ref, etree):
+        rules = []
+        for elem in etree.getiterator("{%s}rule" % self.NAMESPACE):
+            lineno = utils.etree.get_lineno(elem)
+            for rule in relations.RelationFactory.get_relations(self.configuration, elem.text):
+                rule.ref = ref
+                rule.lineno = lineno
+                rules.append(rule)
+        return rules
+    
+    def parse_eval_globals(self, etree):
+        return {}
+
+class RuleImplReader2(RuleImplReaderBase):
+    NAMESPACE = 'http://www.s60.com/xml/ruleml/2'
+    NAMESPACE_ID = 'ruleml2'
+    ROOT_ELEMENT_NAME = 'ruleml'
+    
+    def __init__(self, resource_ref, configuration):
+        RuleImplReaderBase.__init__(self, resource_ref, configuration)
+    
+    @classmethod
+    def get_schema_data(cls):
+        return pkg_resources.resource_string('legacyruleplugin', 'xsd/ruleml2.xsd')
+    
+    def parse_rules(self, ref, etree):
+        rules = []
+        for elem in etree.getiterator("{%s}rule" % self.NAMESPACE):
+            lineno = utils.etree.get_lineno(elem)
+            for rule in relations.RelationFactory.get_relations(self.configuration, self._replace_eval_blocks(elem.text)):
+                rule.ref = ref
+                rule.lineno = lineno
+                rules.append(rule)
+        return rules
+    
+    def parse_eval_globals(self, etree):
+        eval_globals = {}
+        for elem in etree.getiterator("{%s}eval_globals" % self.NAMESPACE):
+            text = ""
+            if elem.get('file') != None:
+                self._read_eval_globals_from_file(elem.get('file'), eval_globals)
+            else:
+                try: 
+                    # Strip surrounding whitespace, otherwise there might be Python
+                    # indentation errors
+                    text = elem.text.strip()
+                    exec(text, eval_globals)
+                except Exception, e:
+                    logging.getLogger('cone.ruleml(%s)' % self.resource_ref).warning('Failed to evaluate eval_globals block, exception: %s' % (e))
+        return eval_globals
+    
+    def _read_eval_globals_from_file(self, relative_path, eval_globals):
+        # Get the actual path (relative to the current implementation file)
+        base_path = os.path.dirname(self.resource_ref)
+        pyfile_path = os.path.normpath(os.path.join(base_path, relative_path)).replace('\\', '/')
+        # Read the data and execute
+        try:
+            resource = None
+            resource = self.configuration.get_resource(pyfile_path)
+            text = resource.read()
+            exec(text.replace('\r', ''), eval_globals)
+        except Exception, e:
+            logging.getLogger('cone.ruleml(%s)' % self.resource_ref).warning('Cannot import eval file: %s. Exception: %s' % (pyfile_path, e))
+        finally:
+            if resource is not None: resource.close()
+        
+    
+    @classmethod
+    def _replace_eval_blocks(cls, code):
+        return utils.expand_delimited_tokens(
+            string          = code,
+            expander_func   = lambda ref, index: '__eval__ %r' % ref,
+            delimiters      =('{%', '%}'))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/rules.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,801 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+# 
+
+import operator as ops
+import logging
+import tokenize
+from token import ENDMARKER, NAME, ERRORTOKEN
+import StringIO
+
+from cone.public import container
+
+RELATIONS = {}
+
+def abstract():
+    import inspect
+    caller = inspect.getouterframes(inspect.currentframe())[1][3]
+    raise NotImplementedError(caller + ' needs to be implemented')
+
+def get_tokens(tokenstr):
+    result = []
+    tokens = []
+    tokenstr = tokenstr.replace('\r', '')
+    name_buffer = [] # Temp buffer for reading name tokens
+    last_epos = None
+    for toknum, tokval, spos, epos, _  in tokenize.generate_tokens(StringIO.StringIO(unicode(tokenstr)).readline):
+        #print "toknum: %r, tokval: %r, spos: %r, epos: %r" % (toknum, tokval, spos, epos)
+        val = tokval.strip('\r\n\t ')
+        
+        if toknum == ENDMARKER and name_buffer:
+            tokens.append(''.join(name_buffer))
+        
+        # Ignore whitespace (this ignores also the end marker,
+        # since its value is empty)
+        if val == '': continue
+        
+        # Put NAME, and ERRORTOKEN tokens through the temp
+        # buffer
+        if toknum in (NAME, ERRORTOKEN):
+            # If this and the previous token in the temp buffer are not adjacent,
+            # they belong to separate tokens
+            if name_buffer and spos[1] != last_epos[1]:
+                tokens.append(''.join(name_buffer))
+                name_buffer = []
+            
+            name_buffer.append(val)
+            last_epos = epos
+        # Other tokens can just go directly to the token list
+        else:
+            if name_buffer:
+                tokens.append(''.join(name_buffer))
+                name_buffer = []
+            tokens.append(val)
+    
+    while len(tokens) > 0:
+        val = tokens.pop(0)
+        # Join the refs with dot in between them to make them dotted refs
+        if val == '.':
+            newval = ".".join([result.pop(),tokens.pop(0)])
+            result.append( newval )
+        else:
+            result.append( val )
+
+    return result
+
+class RelationException(Exception):
+    pass
+
+#### The containers are here ####
+
+
+class RelationBase(object):
+    """
+    RelationBase defines a base class for all named relations that can be applied between objects. 
+    e.g. Relation depends, that can be applied in Rule
+    """
+    relation_name = "RelationBase"
+    def __init__(self, data, left, right):
+        self.description = ""
+        self.data = data or container.DataContainer()
+        self.left = left
+        self.right = right
+
+    def __str__(self):
+        """
+        @return: A string presentation of the relation object
+        """
+        return "%s %s %s" % (self.left,self.relation_name,self.right)
+    
+    def __repr__(self):
+        return "%s(ref=%r, lineno=%r)" % (self.__class__.__name__,
+                                          getattr(self, 'ref', None),
+                                          getattr(self, 'lineno', None))
+
+    def get_name(self):
+        """
+        @return: The relation name.
+        """
+        return self.relation_name
+
+    def get_description(self):
+        """
+        @return: a possible description of the relation.
+        """
+        return self.description
+        
+    def execute(self):
+        """
+        Execute the relation object.
+        """
+        pass
+
+
+class RelationContainer(RelationBase, list):
+    """
+    This class provides the RelationContainer interface for collecting
+    relation sets into one place which can be executed through the container.
+    """
+    def __init__(self, data=None):
+        super(RelationContainer, self).__init__(data, 'LContainer', 'RContainer')
+        self.value_list = list()
+
+    def append(self, value):
+        self.value_list.append(value)
+
+    def __iter__(self):
+        return self.value_list.__iter__()
+
+    def __len__(self):
+        return len(self.value_list)
+
+    def __or__(self, other):
+        """
+        This function adds two RelationContainers to each other and removes
+        duplicates from the result.
+        The modification is inplace and the returned value is called object.
+        """
+        self.value_list = set(self.value_list) | set(other.value_list)
+        return self
+
+    def __unicode__(self):
+        if self:
+            ret = ''
+            for value in self:
+                ret += unicode(value)
+        else:
+            ret = 'No relations'
+        return ret
+
+    def find_relations(self, refs): abstract()
+    def add_relation(self, relation): abstract()
+    def has_errors(self): abstract()
+
+class RelationContainerImpl(RelationContainer):
+    """ Base implementation for RelationContainer to use in ConE rules
+    """
+    def execute(self):
+        ret = True
+        i = 0
+        for relation in self:
+            i += 1
+            r = relation.execute()
+            ret = ret and r
+        return ret
+
+    def find_relations(self, refs):
+        relations = []
+        for ref in refs:
+            for relation in self:
+                if relation.has_ref(ref):
+                    relations.append(relation)
+        return relations
+
+    def add_relation(self, relation):
+        self.append(relation)
+
+    def has_ref(self, refs):
+        for ref in refs:
+            for relation in self:
+                if relation.has_ref(ref):
+                    return True
+        return False
+
+    def has_errors(self):
+        for relation in self:
+            if relation.has_errors():
+                return True
+        return False
+            
+    def get_errors(self):
+        errors = []
+        for relation in self:
+            errors += relation.get_errors()
+        return errors
+
+#### The relations are here ####
+
+class BaseRelation(RelationBase):
+    """ BaseRelation implements the basic evaluation logic for relations
+    This class abstract and should be extended for concrete implementation of
+    relation type.
+
+    Subclasses need to set their own context in their constructor before this
+    class's constructor is called if custom context is needed. If context not
+    set then DefaultContext is used.
+    """
+    KEY = 'base_relation'
+
+    def __init__(self, data, left, right):
+        # Context needs to be overridden for special purposes
+        try:
+            self.__getattribute__('context')
+        except AttributeError:
+            self.context = DefaultContext(data)
+
+        left = self.expand_rule_elements(left)
+        right = self.expand_rule_elements(right)
+        super(BaseRelation, self).__init__(data, left, right)
+        self.interpreter = ASTInterpreter(context=self.context)
+
+    def execute(self, context=None):
+        """
+        @return Returns error dictionary
+
+        In the client code proper way to check if the rule applies:
+        info = relation.execute()
+        if not info.has_errors():
+        else: HANDLE ERRORS
+        """
+        # logger.debug("Interpreter context %s" % self.interpreter.context)
+        self.interpreter.create_ast('%s %s %s' % (self.left, self.KEY, self.right))
+        ret = self.interpreter.eval(context, relation=self)
+        return ret
+
+    def get_keys(self):
+        """ Returns the references from this relation.
+        """
+        refs = ASTInterpreter.extract_refs(self.left)
+        refs += ASTInterpreter.extract_refs(self.right)
+        return refs
+
+    def has_ref(self, ref):
+        """ Returns if the 'ref' is included in this relation
+        """
+        return ref in self.get_keys()
+
+    def has_errors(self):
+        return bool(self.interpreter.errors)
+
+    def get_refs(self):
+        extracted_refs = ASTInterpreter.extract_refs(self.left)
+        
+        # Handle eval expressions (a somewhat ugly hack,
+        # but this is a legacy plug-in so...)
+        interpreter = ASTInterpreter(self.left)
+        for expression in interpreter.parse_tree:
+            if hasattr(expression, 'extract_refs'):
+                extracted_refs.extend(expression.extract_refs())
+        
+        # Filter out entries that evaluate successfully as Python code
+        # e.g. True or 123
+        result = []
+        for item in extracted_refs:
+            try:    eval(item)
+            except: result.append(item)
+            else:   pass
+        return result
+
+    def _eval_rside_value(self, value): abstract()
+    def _compare_value(self, value): abstract()
+
+    def extract_erroneus_features_with_values(self):
+        """
+        Extract references who have errors.
+
+        Returns dictionary { 'reference' : 'value' }
+        """
+        data_dict = {}
+        for ref in ASTInterpreter.extract_refs(self.right):
+            value = self.data.get_feature(ref)
+            if self._compare_value(value):
+                data_dict[ref] = value
+            elif value == None:
+                data_dict[ref] = None
+        return data_dict
+
+    def get_errors(self):
+        return self.interpreter.errors
+
+    def expand_rule_elements(self, rule):
+        """ Expans rule elements base on the reference.
+        Context is used for fetching the child elements for parent references
+        which uses asterisk identifier for selecting all child features: 
+        'parent_feature.*' -> 'child_fea_1 and child_fea_2'.
+        """
+        tokens = get_tokens(rule) # [token for token in rule.split()]
+
+        expanded_rule = ""
+        for token in tokens:
+            if token.endswith('.*'):
+                index = token.index('.*')
+                parent_ref = token[:index]
+                children = self.context.get_children_for_reference(parent_ref)
+                expanded_element = ' and '.join([child.reference for child in children])
+                if expanded_rule:
+                    expanded_rule = '%s and %s' % (expanded_rule, expanded_element.rstrip())
+                else:
+                    expanded_rule = expanded_element.rstrip()
+            elif token.lower() in OPERATORS:
+                expanded_rule += ' %s ' % token
+            else:
+                if expanded_rule:
+                    expanded_rule += '%s'% token
+                else:
+                    expanded_rule = token
+        return expanded_rule.strip()
+
+class RequireRelation(BaseRelation):
+    KEY = 'requires'
+RELATIONS[RequireRelation.KEY] = RequireRelation
+
+class ExcludesRelation(BaseRelation):
+    KEY = 'excludes'
+
+RELATIONS['excludes'] = ExcludesRelation
+
+################################
+# Abstract syntax tree builder #
+################################
+
+def nor(expression, a, b):
+    return not ops.or_(a, b)
+
+def nand(expression, a, b):
+    return not ops.and_(a, b)
+
+def truth_and(expression, a, b):
+    return ops.truth(a) and ops.truth(b)
+
+class DefaultContext(object):
+    """ DefaultContext implements ConE specific context for handling rules
+    """
+    def __init__(self, data):
+        self.data = data
+
+    def eval(self, ast, expression, value):
+        pass
+
+    def get_keys(self, refs):
+        return ASTInterpreter.extract_refs(refs)
+
+    def get_children_for_reference(self, reference):
+        # implement ConE specific children expansion
+        pass
+
+    def handle_terminal(self, expression):
+        try:
+            return int(expression)
+        except:
+            return expression
+
+PRECEDENCES = {
+    'PREFIX_OPERATORS' : 10,
+    'MULDIV_OPERATORS' : 8,
+    'ADDSUB_OPERATORS' : 7,
+    'SHIFT_OPERATORS' : 6,
+    'BITWISE_OPERATORS' : 5,
+    'COMPARISON_OPERATORS' : 4,
+    'SET_OPERATORS' : 3,
+    'BOOLEAN_OPERATORS' : 2, 
+    'RELATION_OPERATORS' : 1,
+    'NOT_DEFINED' : 0
+}
+
+class Expression(object):
+    PRECEDENCE = PRECEDENCES['NOT_DEFINED']
+    KEY = 'base_expression'
+
+    def __init__(self, ast):
+        self.ast = ast
+        self.value = None
+
+    def get_title(self):
+        return self.KEY
+
+    def eval(self, context, **kwargs): pass
+
+class OneParamExpression(Expression):
+    PARAM_COUNT = 1
+    def __init__(self, ast, expression):
+        super(OneParamExpression, self).__init__(ast)
+        self.expression = expression
+
+    def __unicode__(self):
+        return u'%s %s' % (self.KEY, self.expression)
+
+    def eval(self, context, **kwargs):
+        self.value = self.OP(self.expression.eval(context, **kwargs))
+        context.eval(self.ast, self, self.value)
+        return self.value
+
+class TwoOperatorExpression(Expression):
+    PARAM_COUNT = 2
+    OP = None
+    EVAL_AS_BOOLS = True
+
+    def __init__(self, ast, left, right):
+        super(TwoOperatorExpression, self).__init__(ast)
+        self.left = left
+        self.right = right
+
+    def __unicode__(self):
+        return u'%s %s %s' % (self.left, self.KEY, self.right)
+
+    def eval(self, context, **kwargs):
+        self.value = self.OP(self.left.eval(context, **kwargs), self.right.eval(context, **kwargs))
+        context.eval(self.ast, self, self.value)
+        return self.value
+
+class TwoOperatorBooleanExpression(TwoOperatorExpression):
+    def eval(self, context, **kwargs):
+        self.value = self.OP(bool(self.left.eval(context, **kwargs)), bool(self.right.eval(context, **kwargs)))
+        context.eval(self.ast, self, self.value)
+        return self.value         
+
+class TerminalExpression(Expression):
+    KEY = 'terminal'
+
+    def __init__(self, ast, expression):
+        super(TerminalExpression, self).__init__(ast)
+        self.expression = expression
+
+    def eval(self, context, **kwargs):
+        """ Use context to eval the value
+        Expression on TerminalExpression is feature reference or value
+        context should handle the reference conversion to correct value
+        """
+        from cone.public import exceptions
+        try:
+            context.configuration.get_default_view().get_feature(self.expression)
+            self.value = context.handle_terminal(self.expression)
+        except exceptions.NotFound:
+            self.value = context.convert_value(self.expression)
+            
+        return self.value
+
+    def __unicode__(self):
+        return self.expression
+    
+    def __repr__(self):
+        return self.expression
+
+    def get_ref(self):
+        """
+        @return: The setting reference, e.g. 'MyFeature.MySetting'
+        """
+        return self.expression
+
+
+class NegExpression(OneParamExpression):
+    PRECEDENCE = PRECEDENCES['PREFIX_OPERATORS']
+    KEY= '-'
+    OP = ops.neg
+
+class AndExpression(TwoOperatorBooleanExpression):
+    PRECEDENCE = PRECEDENCES['BOOLEAN_OPERATORS']
+    KEY= 'and'
+    OP = truth_and
+
+class NandExpression(TwoOperatorBooleanExpression):
+    PRECEDENCE = PRECEDENCES['BOOLEAN_OPERATORS']
+    KEY = 'nand'
+    OP = nand
+
+class OrExpression(TwoOperatorBooleanExpression):
+    PRECEDENCE = PRECEDENCES['BOOLEAN_OPERATORS']
+    KEY = 'or'
+    OP = ops.or_
+
+class XorExpression(TwoOperatorBooleanExpression):
+    PRECEDENCE = PRECEDENCES['BOOLEAN_OPERATORS']
+    KEY = 'xor'
+    OP = ops.xor
+
+class NorExpression(TwoOperatorBooleanExpression):
+    PRECEDENCE = PRECEDENCES['BOOLEAN_OPERATORS']
+    KEY = 'nor'
+    OP = nor
+
+class EqualExpression(TwoOperatorExpression):
+    PRECEDENCE = PRECEDENCES['COMPARISON_OPERATORS']
+    KEY = '=='
+    OP = ops.eq
+
+class NotEqualExpression(TwoOperatorExpression):
+    PRECEDENCE = PRECEDENCES['COMPARISON_OPERATORS']
+    KEY = '!='
+    OP = ops.ne
+
+class LessThanExpression(TwoOperatorExpression):
+    PRECEDENCE = PRECEDENCES['COMPARISON_OPERATORS']
+    KEY = '<'
+    OP = ops.lt
+
+class GreaterThanExpression(TwoOperatorExpression):
+    PRECEDENCE = PRECEDENCES['COMPARISON_OPERATORS']
+    KEY = '>'
+    OP = ops.gt
+
+class LessThanEqualExpression(TwoOperatorExpression):
+    PRECEDENCE = PRECEDENCES['COMPARISON_OPERATORS']
+    KEY = '<='
+    OP = ops.le
+
+class GreaterThanEqualExpression(TwoOperatorExpression):
+    PRECEDENCE = PRECEDENCES['COMPARISON_OPERATORS']
+    KEY = '>='
+    OP = ops.ge
+
+
+def handle_require(expression, left, right):
+    if left and right:
+        return True
+    elif not left:
+        return True
+    return False
+
+class RequireExpression(TwoOperatorExpression):
+    PRECEDENCE = PRECEDENCES['RELATION_OPERATORS']
+    KEY = 'requires'
+    OP = handle_require
+
+    def eval(self, context, **kwargs):
+        super(RequireExpression, self).eval(context, **kwargs)
+        if not self.value:
+            left_keys = []
+            for ref in self.ast.extract_refs(unicode(self.left)):
+                for key in context.get_keys(ref):
+                    left_keys.append(key)
+
+            for key in left_keys:
+                self.ast.add_error(key, { 'error_string' : 'REQUIRES right side value is "False"',
+                                          'left_key' : key,
+                                          'rule' : self.ast.expression
+                                          })
+        return self.value
+
+def handle_exclude(expression, left, right):
+    if left and not right:
+        return True
+    elif not left:
+        return True
+    return False
+
+class ExcludeExpression(TwoOperatorExpression):
+    PRECEDENCE = PRECEDENCES['RELATION_OPERATORS']
+    KEY = 'excludes'
+    OP = handle_exclude
+
+    def eval(self, context, **kwargs):
+        super(ExcludeExpression, self).eval(context, **kwargs)
+        if not self.value:
+            left_keys = []
+            for ref in self.ast.extract_refs(unicode(self.left)):
+                for key in context.get_keys(ref):
+                    left_keys.append(key)
+                    
+            for key in left_keys:
+                self.ast.add_error(key, { 'error_string' : 'EXCLUDE right side value is "True"',
+                                          'left_key' : key,
+                                          'rule' : self.ast.expression
+                                          })
+        return self.value
+
+
+class NotExpression(OneParamExpression):
+    PRECEDENCE = PRECEDENCES['PREFIX_OPERATORS']
+    KEY = 'not'
+    OP = ops.not_
+
+class TruthExpression(OneParamExpression):
+    PRECEDENCE = PRECEDENCES['PREFIX_OPERATORS']
+    KEY = 'truth'
+    OP = ops.truth
+
+LEFT_PARENTHESIS = '('
+RIGHT_PARENTHESIS = ')'
+class SimpleCondition(EqualExpression):
+    """
+    A simple condition object that can refer to a model object and evaluate if the value matches  
+    """
+    def __init__(self, left, right):
+        lterm = TerminalExpression(None, left)
+        rterm = TerminalExpression(None, right)
+        EqualExpression.__init__(self, None, lterm, rterm)
+
+
+# in format KEY : OPERATOR CLASS
+OPERATORS = {
+    'and' : AndExpression,
+    'nand' : NandExpression,
+    'or' : OrExpression,
+    'xor' : XorExpression,
+    'nor' : NorExpression,
+    'not' : NotExpression,
+    'truth' : TruthExpression,
+    '==' : EqualExpression,
+    '!=' : NotEqualExpression,
+    '<' : LessThanExpression,
+    '>' : GreaterThanExpression,
+    '<=' : LessThanEqualExpression,
+    '>=' : GreaterThanEqualExpression,
+    'requires' : RequireExpression,
+    'excludes' : ExcludeExpression,
+    '-' : NegExpression
+    }
+
+def add_operator(key, operator_class=None, baseclass=RequireExpression):
+    """
+    Add new operator key and operator class.
+    If operator class isn't provided the baseclass parameter is used as
+    operator base. The baseclass parameter is RequireExpression by default
+    which has success condition left_rule=True and right_rule=True
+    
+    """
+    OPERATORS[key] = operator_class or create_new_class(key, baseclass)
+
+def create_new_class(key, baseclass):
+    ns = baseclass.__dict__.copy()
+    ns['KEY'] = key
+    key_pieces = key.split('_')
+    class_prefix = ''.join([key_piece.capitalize() for key_piece in key_pieces])
+    new_class = type(class_prefix + 'Expression', (baseclass,), ns)
+    return new_class
+
+class ParseException(Exception): pass
+
+class ASTInterpreter(object):
+    def __init__(self, infix_expression=None, context=None):
+        """ Takes infix expression as string """
+        self.context = context or DefaultContext(None)
+        # logger.debug("AST init context: %s" % self.context)
+        self._init_locals(infix_expression)
+        if infix_expression:
+            self.create_ast()
+
+    def _init_locals(self, infix_expression):
+        # The result value of full eval of the parse_tree
+        self.value = None
+        self.warnings = {}
+        self.errors = {}
+        self.postfix_array = []
+        self.parse_tree = []
+        self.expression = infix_expression
+
+    def __unicode__(self):
+        s = ''
+        for expr in self.parse_tree:
+            s += unicode(expr)
+        return s
+
+    def add_error(self, key, error_dict):
+        if self.errors.has_key(key):
+            self.errors[key].append(error_dict)
+        else:
+            self.errors[key] = [error_dict]
+
+    def create_ast(self, infix_expression=None):
+        if infix_expression:
+            self._init_locals(infix_expression)
+        self._infix_to_postfix()
+        self._create_parse_tree()
+        return self.parse_tree
+
+    def _infix_to_postfix(self):
+        """
+        Shunting yard algorithm used to convert infix presentation to postfix.
+        """
+        if not self.expression:
+            raise ParseException('Expression is None')
+        tokens = get_tokens(self.expression) # [token for token in self.expression.split()]
+        stack = []
+        # logger.debug('TOKENS: %s' % tokens)
+        for token in tokens:
+            # logger.debug('TOKEN: %s' % token)
+            if token.lower() in OPERATORS:
+                op_class = OPERATORS.get(token)
+                if stack:
+                    while len(stack) != 0:
+                        top = stack[-1]
+                        if top in OPERATORS:
+                            top_operator = OPERATORS.get(top)
+                            if op_class.PRECEDENCE <= top_operator.PRECEDENCE:
+                                self.postfix_array.append(stack.pop())
+                            else:
+                                # Break from loop if top operator precedence is less.
+                                break
+                        else:
+                            # If top not operator break from loop
+                            break
+                stack.append(token)
+            elif token == LEFT_PARENTHESIS:
+                # logger.debug('Left parenthesis')
+                stack.append(token)
+            elif token == RIGHT_PARENTHESIS:
+                # logger.debug('Right parenthesis')
+                left_par_found = False
+                stack_token = stack.pop()
+                while stack_token:
+                    if stack_token != LEFT_PARENTHESIS:
+                        self.postfix_array.append(stack_token)
+                    else:
+                        left_par_found = True
+                        break
+                    if stack:
+                        stack_token = stack.pop()
+                    else:
+                        stack_token = None
+                        
+                if not left_par_found:
+                    raise ParseException('Mismatched parenthesis "%s".' % LEFT_PARENTHESIS)
+            else:
+                # logger.debug('Adding value to output. %s' % repr((token)))
+                self.postfix_array.append((token))
+            
+        # There should be only operators left in the stack
+        if stack:
+            # logger.debug('Operators in stack.')
+            operator = stack.pop()
+            while operator:
+                if operator != LEFT_PARENTHESIS:
+                    self.postfix_array.append(operator)
+                else:
+                    raise ParseException('Mismatched parenthesis "%s".' % LEFT_PARENTHESIS)
+                if stack:
+                    operator = stack.pop()
+                else:
+                    operator = None
+
+        # logger.debug('Infix to postfix conversion: %s' % self.postfix_array)
+        return self.postfix_array
+    
+    def _create_parse_tree(self):
+        self.parse_tree = []
+        for token in self.postfix_array:
+            if token in OPERATORS:
+                # logger.debug('OP: %s' % (token))
+                expression_class = OPERATORS[token]
+                params = []
+                for i in range(expression_class.PARAM_COUNT):
+                    try:
+                        params.append(self.parse_tree.pop())
+                    except IndexError, e:
+                        raise ParseException('Syntax error: "%s"' % self.expression)
+                params.reverse()
+                expression = expression_class(self, *params)
+
+                # logger.debug('The operation: %s' % expression)
+                self.parse_tree.append(expression)
+            else:
+                expression = TerminalExpression(self, token)
+                self.parse_tree.append(expression)
+
+        #logger.debug('THE STACK: %s' % self.parse_tree)
+        #for s in self.parse_tree:
+        #    logger.debug('Stack e: %s' % str(s))
+
+        return self.parse_tree
+
+    def eval(self, context=None, **kwargs):
+        """ Evals the AST
+        If empty expression is given, None is returned
+        """
+        for expression in self.parse_tree:
+            self.value = expression.eval(context, **kwargs)
+        return self.value
+
+    @staticmethod
+    def extract_refs(expression):
+        tokens = get_tokens(expression)
+        refs = []
+        for token in tokens:
+            if not token.lower() in OPERATORS and token != LEFT_PARENTHESIS and token != RIGHT_PARENTHESIS:
+                refs.append(token.strip('%s%s' % (LEFT_PARENTHESIS, RIGHT_PARENTHESIS)))
+        return refs
+
+##################################################################
+# Create and configure the main level logger
+logger = logging.getLogger('cone')
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/__init__.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,23 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+import sys, os, unittest
+
+# Path to the directory where this file is located
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+from testautomation import plugin_utils
+plugin_utils.plugin_test_init(ROOT_PATH)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/errorruleproject/test1/confml/testdata.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,10 @@
+<configuration name="Eval test data" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
+  <feature ref="EvalTest" name="Test settings for eval blocks">
+    <setting ref="StringLenResult" name="String length result" type="int" />
+  </feature>
+  <data>
+    <EvalTest>
+      <StringLenResult>0</StringLenResult>
+    </EvalTest>
+  </data>
+</configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/errorruleproject/test1/implml/terminalexpression.ruleml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ruleml xmlns="http://www.s60.com/xml/ruleml/2">
+  <rule>True configures EvalTest.StringLenResult = 22</rule>
+  <rule>True configures EvalTest.StringLenResult = {% SOME_VALUE %}</rule>
+  <eval_globals>SOME_VALUE = 12345</eval_globals>
+</ruleml>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/errorruleproject/test1/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,3 @@
+<configuration name="ruleml_test_config" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
+<xi:include href="confml/testdata.confml" />
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/errorruleproject/test2/confml/invalid_python_eval.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,10 @@
+<configuration name="Eval test data" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
+  <feature ref="EvalTest2" name="Test settings for eval blocks">
+    <setting ref="StringResult" name="String result" type="string" />
+  </feature>
+  <data>
+    <EvalTest2>
+      <StringResult>0</StringResult>
+    </EvalTest2>
+  </data>
+</configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/errorruleproject/test2/implml/invalid_python_eval.ruleml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ruleml xmlns="http://www.s60.com/xml/ruleml/2">
+  <rule>True configures EvalTest2.StringResult = {% -> this is invalid python code %}</rule>
+</ruleml>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/errorruleproject/test2/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,3 @@
+<configuration name="ruleml_test_config" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
+<xi:include href="confml/invalid_python_eval.confml" />
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/errorruleproject/test3/confml/invalid_python_eval.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,10 @@
+<configuration name="Eval test data" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
+  <feature ref="EvalTest3" name="Test settings for eval blocks">
+    <setting ref="StringResult" name="String result" type="string" />
+  </feature>
+  <data>
+    <EvalTest3>
+      <StringResult>0</StringResult>
+    </EvalTest3>
+  </data>
+</configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/errorruleproject/test3/implml/invalid_python_eval.ruleml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ruleml xmlns="http://www.s60.com/xml/ruleml/2">
+  <rule>True configures EvalTest3.StringResult = 22</rule>
+  <eval_globals file="scripts/test_eval.py"/>
+</ruleml>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/errorruleproject/test3/implml/scripts/test_eval.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,17 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+this is some other invalid python code
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/errorruleproject/test3/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,3 @@
+<configuration name="ruleml_test_config" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
+<xi:include href="confml/invalid_python_eval.confml" />
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/errorruleproject/test4/confml/invalid_python_eval.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,10 @@
+<configuration name="Eval test data" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
+  <feature ref="EvalTest4" name="Test settings for eval blocks">
+    <setting ref="StringResult" name="String result" type="string" />
+  </feature>
+  <data>
+    <EvalTest4>
+      <StringResult>0</StringResult>
+    </EvalTest4>
+  </data>
+</configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/errorruleproject/test4/implml/invalid_python_eval.ruleml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ruleml xmlns="http://www.s60.com/xml/ruleml/2">
+  <rule>True configures EvalTest4.StringResult = 22</rule>
+  <eval_globals file="scripts/not_valid_filename.py"/>
+</ruleml>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/errorruleproject/test4/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,3 @@
+<configuration name="ruleml_test_config" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
+<xi:include href="confml/invalid_python_eval.confml" />
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/errorruleproject/test5/confml/invalid_python_eval.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,10 @@
+<configuration name="Eval test data" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
+  <feature ref="EvalTest5" name="Test settings for eval blocks">
+    <setting ref="StringResult" name="String result" type="string" />
+  </feature>
+  <data>
+    <EvalTest5>
+      <StringResult>0</StringResult>
+    </EvalTest5>
+  </data>
+</configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/errorruleproject/test5/implml/invalid_python_eval.ruleml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ruleml xmlns="http://www.s60.com/xml/ruleml/2">
+  <rule>True configures EvalTest5.StringResult = {% 7/0 %}</rule>
+</ruleml>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/errorruleproject/test5/implml/scripts/test_eval.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,17 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+this is some other invalid python code
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/errorruleproject/test5/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,3 @@
+<configuration name="ruleml_test_config" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
+<xi:include href="confml/invalid_python_eval.confml" />
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/errorruleproject/test6/confml/invalid_python_eval.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,10 @@
+<configuration name="Eval test data" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
+  <feature ref="EvalTest6" name="Test settings for eval blocks">
+    <setting ref="StringResult" name="String result" type="string" />
+  </feature>
+  <data>
+    <EvalTest6>
+      <StringResult>0</StringResult>
+    </EvalTest6>
+  </data>
+</configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/errorruleproject/test6/implml/invalid_python_eval.ruleml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ruleml xmlns="http://www.s60.com/xml/ruleml/2">
+  <rule>True configures EvalTest6.StringResult = Invalid.setting</rule>
+</ruleml>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/errorruleproject/test6/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,3 @@
+<configuration name="ruleml_test_config" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
+<xi:include href="confml/invalid_python_eval.confml" />
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/rule/config_project/.metadata	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="ASCII"?>
+<metadata xmlns="http://www.nokia.com/xml/ns/confml-core/metadata-2.0">
+  <property name="cpf.name"/>
+  <property name="cpf.description"/>
+  <property name="cpf.viewId"/>
+  <property name="cpf.rootFile" value="terra_VF_UK_101.confml"/>
+  <property name="cpf.dataFile"/>
+  <property name="cpf.author"/>
+  <property name="cpf.version"/>
+  <property name="cpf.product"/>
+  <property name="cpf.customer"/>
+  <property name="cpf.platform"/>
+  <property name="cpf.release"/>
+  <property name="cpf.date"/>
+  <property name="cpf.owner"/>
+</metadata>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/rule/config_project/.project	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>config_project</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>com.nokia.tools.variant.confml.core.ConfMLLayerBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>com.nokia.tools.variant.confml.core.ConfMLLayerNature</nature>
+	</natures>
+</projectDescription>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/rule/config_project/platforms/customsw/.metadata	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="ASCII"?>
+<metadata xmlns="http://www.nokia.com/xml/ns/confml-core/metadata-2.0">
+  <property name="cpf.rootFile" />
+</metadata>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/rule/config_project/platforms/customsw/confml/actionpriorities.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,37 @@
+<configuration name="actionpriorities" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
+  <feature name="Contact Action Service" ref="KCRUidFsContactActionService">
+    <desc />
+  <setting name="Call GSM" ref="KFscCrUidCallGsm" type="string" />
+  </feature>
+<feature name="ar operations" ref="operations">
+    <setting name="MINUS" ref="minus" type="int" />
+  <setting name="MINUS1" ref="minus1" type="int" />
+  <setting name="MINUS2" ref="minus2" type="int" />
+  <setting name="MINUS3" ref="minus3" type="int" />
+  <setting name="MINUS4" ref="minus4" type="int" />
+  <setting name="MINUS5" ref="minus5" type="int" />
+  <setting name="MINUS6" ref="minus6" type="int" />
+  <setting name="MINUS7" ref="minus7" type="int" />
+  <setting name="MINUS8" ref="minus8" type="int" />
+  <setting name="STRING1" ref="string1" type="string" />
+  <setting name="STRING2" ref="string2" type="string" />
+  </feature>
+<data>
+    <KCRUidFsContactActionService>
+      <KFscCrUidCallGsm />
+    </KCRUidFsContactActionService>
+  <operations>
+      <minus>5</minus>
+    <minus1>25</minus1>
+    <minus2>7</minus2>
+    <minus3>5</minus3>
+    <minus4>10</minus4>
+    <minus5>2</minus5>
+    <minus6>6</minus6>
+    <minus7>10</minus7>
+    <minus8>9</minus8>
+    <string1>Hello</string1>
+    <string2>World</string2>
+    </operations>
+  </data>
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/rule/config_project/platforms/customsw/implml/gsm.ruleml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ruleml xmlns="http://www.s60.com/xml/ruleml/1">
+  <rule>operations.minus == 5 configures operations.minus = operations.minus1 - operations.minus2</rule>
+  <rule>operations.minus1 == 25 configures operations.minus1 = operations.minus3 * operations.minus2</rule>
+  <rule>operations.minus4 == 10 configures operations.minus4 = operations.minus4 / operations.minus5</rule>
+  <rule>operations.minus6 == 6 configures operations.minus6 = operations.minus7 + operations.minus8</rule>
+  <rule>operations.string1 == 'Hello' configures operations.string1 = operations.string1 + operations.string2</rule>
+</ruleml>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/rule/config_project/platforms/customsw/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<configuration name="platforms_customsw_root_confml" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
+  <xi:include href="confml/actionpriorities.confml" />
+<xi:include href="autodata.confml" />
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/ruleproject/rules/.metadata	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="ASCII"?>
+<metadata xmlns="http://www.nokia.com/xml/ns/confml-core/metadata-2.0">
+  <property name="cpf.rootFile" value="root.confml" />
+</metadata>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/ruleproject/rules/confml/arithmetic.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,91 @@
+<configuration name="Arithmetic operation test" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
+  <feature name="Test settings for arithmetic operations" ref="Arithmetic">
+    <!-- Values used in tests -->
+    <setting name="Value 1" ref="Value1" type="int" />
+    <setting name="Value 2" ref="Value2" type="int" />
+    
+    <setting name="Real value 1" ref="RealValue1" type="real" />
+    <setting name="Real value 2" ref="RealValue2" type="real" />
+    
+    <!-- Settings for storing the result of the calculation -->
+    <setting name="Addition result 1" ref="AdditionResult1" type="int" />
+    <setting name="Addition result 2" ref="AdditionResult2" type="int" />
+    <setting name="Addition result 3" ref="AdditionResult3" type="int" />
+    <setting name="Addition result 4" ref="AdditionResult4" type="int" />
+    
+    <setting name="Subtraction result 1" ref="SubtractionResult1" type="int" />
+    <setting name="Subtraction result 2" ref="SubtractionResult2" type="int" />
+    <setting name="Subtraction result 3" ref="SubtractionResult3" type="int" />
+    <setting name="Subtraction result 4" ref="SubtractionResult4" type="int" />
+    
+    <setting name="Multiplication result 1" ref="MultiplicationResult1" type="int" />
+    <setting name="Multiplication result 2" ref="MultiplicationResult2" type="int" />
+    <setting name="Multiplication result 3" ref="MultiplicationResult3" type="int" />
+    <setting name="Multiplication result 4" ref="MultiplicationResult4" type="int" />
+    
+    <setting name="Division result 1" ref="DivisionResult1" type="int" />
+    <setting name="Division result 2" ref="DivisionResult2" type="int" />
+    <setting name="Division result 3" ref="DivisionResult3" type="int" />
+    <setting name="Division result 4" ref="DivisionResult4" type="int" />
+    
+    <setting name="Mixed result 1" ref="MixedResult1" type="int" />
+    <setting name="Mixed result 2" ref="MixedResult2" type="int" />
+    <setting name="Mixed result 3" ref="MixedResult3" type="int" />
+    <setting name="Mixed result 4" ref="MixedResult4" type="int" />
+    <setting name="Mixed result 5" ref="MixedResult5" type="int" />
+    
+    <setting name="Real result 1" ref="RealResult1" type="real" />
+    <setting name="Real result 2" ref="RealResult2" type="real" />
+    <setting name="Real result 3" ref="RealResult3" type="real" />
+    <setting name="Real result 4" ref="RealResult4" type="real" />
+    
+    <setting name="Real calculation into int setting result" ref="RealCalcIntoIntResult" type="int" />
+    <setting name="Int calculation into real setting result" ref="IntCalcIntoRealResult" type="real" />
+
+
+  </feature>
+  
+  <data>
+    <Arithmetic>
+      <Value1>5</Value1>
+      <Value2>20</Value2>
+      
+      <RealValue1>5</RealValue1>
+      <RealValue2>20</RealValue2>
+      
+      <AdditionResult1>0</AdditionResult1>
+      <AdditionResult2>0</AdditionResult2>
+      <AdditionResult3>0</AdditionResult3>
+      <AdditionResult4>0</AdditionResult4>
+      
+      <SubtractionResult1>0</SubtractionResult1>
+      <SubtractionResult2>0</SubtractionResult2>
+      <SubtractionResult3>0</SubtractionResult3>
+      <SubtractionResult4>0</SubtractionResult4>
+      
+      <MultiplicationResult1>0</MultiplicationResult1>
+      <MultiplicationResult2>0</MultiplicationResult2>
+      <MultiplicationResult3>0</MultiplicationResult3>
+      <MultiplicationResult4>0</MultiplicationResult4>
+      
+      <DivisionResult1>0</DivisionResult1>
+      <DivisionResult2>0</DivisionResult2>
+      <DivisionResult3>0</DivisionResult3>
+      <DivisionResult4>0</DivisionResult4>
+      
+      <MixedResult1>0</MixedResult1>
+      <MixedResult2>0</MixedResult2>
+      <MixedResult3>0</MixedResult3>
+      <MixedResult4>0</MixedResult4>
+      <MixedResult5>0</MixedResult5>
+      
+      <RealResult1>0</RealResult1>
+      <RealResult2>0</RealResult2>
+      <RealResult3>0</RealResult3>
+      <RealResult4>0</RealResult4>
+      
+      <RealCalcIntoIntResult>0</RealCalcIntoIntResult>
+      <IntCalcIntoRealResult>0</IntCalcIntoRealResult>
+    </Arithmetic>
+  </data>
+</configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/ruleproject/rules/confml/commsdatcreator.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,1935 @@
+<configuration name="Default CommsDat settings" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
+  <feature name="CommsDat generation" ref="KCRUidCommsDatCreator">
+    <desc>Used to configure whether CommsDat generation from these settings is enabled.</desc>
+  <setting name="CommsDat generation enabled" ref="KCommsDatCreatorInputFileName" type="string">
+      <desc>This is the master switch that determines whether CommsDat is created in the first boot 
+    	of the device based on Configuration Tool output. Set this to Yes if you are creating variant 
+    	and need to configure anything under Default CommsDat settings.</desc>
+    <option name="No" value="" />
+    <option name="Yes" value="VariantData_commsdat.xml" />
+    </setting>
+  <setting name="CommsDatCreator startup status flag" readOnly="true" ref="KCommsDatCreatorStartupStatus" type="int">
+      <desc>Read-only flag that indicates the CommsDatCreator start-up status in runtime.</desc>
+    </setting>
+  </feature>
+<feature name="Global settings" ref="Global">
+    <desc>
+  	Global networking related settings not tied to individual connection methods.
+  	</desc>
+  <setting name="Attachmode" ref="Attachmode" type="selection">
+      <desc>
+      GPRS attach mode (attach when needed/when available).
+      </desc>
+    <option name="When available" value="whenavailable" />
+    <option name="When needed" value="whenneeded" />
+    </setting>
+  <setting name="Default access point" ref="DefaultAP" type="string">
+      <desc>
+    	Default GPRS access point. Used when the phone is used as a modem for a PC.
+    	The corresponding UI setting is Connection-Packet data-Access point.
+    	</desc>
+    </setting>
+  <setting name="Default icon for DNs" ref="DefaultDnIcon" type="selection">
+      <desc>
+      Default icon for destination networks.
+      </desc>
+    <option name="internet" value="0" />
+    <option name="wap" value="1" />
+    <option name="mms" value="2" />
+    <option name="intranet" value="3" />
+    <option name="operator" value="4" />
+    <option name="icon1" value="5" />
+    <option name="icon2" value="6" />
+    <option name="icon3" value="7" />
+    <option name="icon4" value="8" />
+    <option name="icon5" value="9" />
+    <option name="icon6" value="10" />
+    <option name="default" value="11" />
+    </setting>
+  <setting name="LAN bearer default priority" ref="PriorityLan" type="string">
+      <desc>
+    	Default priority for LAN bearer type.
+    	</desc>
+    </setting>
+  <setting name="WLAN bearer default priority" ref="PriorityWlan" type="string">
+      <desc>
+    	Default priority for WLAN bearer type.
+    	</desc>
+    </setting>
+  <setting name="PAN bearer default priority" ref="PriorityPan" type="string">
+      <desc>
+    	Default priority for PAN bearer type.
+    	</desc>
+    </setting>
+  <setting name="Outgoing GPRS bearer default priority" ref="PriorityGprsOut" type="string">
+      <desc>
+    	Default priority for outgoing GPRS bearer type.
+    	</desc>
+    </setting>
+  <setting name="Incoming GPRS bearer default priority" ref="PriorityGprsIn" type="string">
+      <desc>
+    	Default priority for incoming GPRS bearer type.
+    	</desc>
+    </setting>
+  <setting name="CDMA2000 bearer default priority" ref="PriorityCdma2k" type="string">
+      <desc>
+    	Default priority for CDMA 2000 bearer type.
+    	</desc>
+    </setting>
+  <setting name="DialOut ISP bearer default priority" ref="PriorityDialOut" type="string">
+      <desc>
+    	Default priority for outgoing dial bearer type.
+    	</desc>
+    </setting>
+  <setting name="DialIn ISP bearer default priority" ref="PriorityDialIn" type="string">
+      <desc>
+    	Default priority for incoming dial bearer type.
+    	</desc>
+    </setting>
+  <setting name="VPN bearer default priority" ref="PriorityVpn" type="string">
+      <desc>
+    	Default priority for VPN bearer type.
+    	</desc>
+    </setting>
+  <setting name="MIP bearer default priority" ref="PriorityMip" type="string">
+      <desc>
+    	Default priority for MIP bearer type.
+    	</desc>
+    </setting>
+  <setting name="LAN bearer default UI priority" ref="UIPriorityLan" type="string">
+      <desc>
+    	Default UI priority of LAN connection.
+    	</desc>
+    </setting>
+  <setting name="WLAN bearer default UI priority" ref="UIPriorityWlan" type="string">
+      <desc>
+    	Default UI priority for WLAN bearer type.
+    	</desc>
+    </setting>
+  <setting name="PAN bearer default UI priority" ref="UIPriorityPan" type="string">
+      <desc>
+    	Default UI priority for PAN bearer type.
+    	</desc>
+    </setting>
+  <setting name="Outgoing GPRS bearer default UI priority" ref="UIPriorityGprsOut" type="string">
+      <desc>
+    	Default UI priority for outgoing GPRS bearer type.
+    	</desc>
+    </setting>
+  <setting name="Incoming GPRS bearer default UI priority" ref="UIPriorityGprsIn" type="string">
+      <desc>
+    	Default UI priority for incoming GPRS bearer type.
+    	</desc>
+    </setting>
+  <setting name="CDMA2000 bearer default UI priority" ref="UIPriorityCdma2k" type="string">
+      <desc>
+    	Default UI priority for CDMA 2000 bearer type.
+    	</desc>
+    </setting>
+  <setting name="DialOut ISP bearer default UI priority" ref="UIPriorityDialOut" type="string">
+      <desc>
+    	Default UI priority for outgoing dial bearer type.
+    	</desc>
+    </setting>
+  <setting name="DialIn ISP bearer default UI priority" ref="UIPriorityDialIn" type="string">
+      <desc>
+    	Default UI priority for incoming dial bearer type.
+    	</desc>
+    </setting>
+  <setting name="VPN bearer default UI priority" ref="UIPriorityVpn" type="string">
+      <desc>
+    	Default UI priority for VPN bearer type.
+    	</desc>
+    </setting>
+  <setting name="MIP bearer default UI priority" ref="UIPriorityMip" type="string">
+      <desc>
+    	Default UI priority for MIP bearer type.
+    	</desc>
+    </setting>
+  <setting name="Default connection type" ref="DefaultConnectionType" type="selection">
+      <desc>
+      Specifies how the applications' default connection is specified.
+      </desc>
+    <option name="Ask once" value="Ask once" />
+    <option name="Always ask" value="Always ask" />
+    <option name="Destination" value="Destination" />
+    <option name="Connection method" value="Connection method" />
+    </setting>
+  <setting name="Default connection name" ref="DefaultConnectionName" type="string">
+      <desc>
+    	The name of the default connection (connection method or destination network). 
+    	Default connection type parameter needs to be set accordingly.
+    	</desc>
+    </setting>
+  <setting name="GPRS last socket activity timeout" ref="GprsLastSocketActivityTimeout" type="int">
+      <desc>
+    	For GPRS the time (in seconds) to stay online when all socket activity has ceased. -1 for unlimited time.
+    	Leave empty to use the product default value.
+    	</desc>
+    </setting>
+  <setting name="GPRS last session closed timeout" ref="GprsLastSessionClosedTimeout" type="int">
+      <desc>
+    	For GPRS the time (in seconds) to stay online when session has closed. -1 for unlimited time.
+    	Leave empty to use the product default value.
+    	</desc>
+    </setting>
+  <setting name="GPRS last socket closed timeout" ref="GprsLastSocketClosedTimeout" type="int">
+      <desc>
+    	For GPRS the time (in seconds) to stay online when socket has closed. -1 for unlimited time.
+    	Leave empty to use the product default value.
+    	</desc>
+    </setting>
+  <setting name="CSD last socket activity timeout" ref="CsdLastSocketActivityTimeout" type="int">
+      <desc>
+    	For CSD the time (in seconds) to stay online when all socket activity has ceased. -1 for unlimited time.
+    	Leave empty to use the product default value.
+    	</desc>
+    </setting>
+  <setting name="CSD last session closed timeout" ref="CsdLastSessionClosedTimeout" type="int">
+      <desc>
+    	For CSD the time (in seconds) to stay online when all socket activity has ceased. -1 for unlimited time.
+    	Leave empty to use the product default value.
+    	</desc>
+    </setting>
+  <setting name="CSD last socket closed timeout" ref="CsdLastSocketClosedTimeout" type="int">
+      <desc>
+    	For CSD the time (in seconds) to stay online when all socket activity has ceased. -1 for unlimited time.
+    	Leave empty to use the product default value.
+    	</desc>
+    </setting>
+  <setting name="WLAN last socket activity timeout" ref="WlanLastSocketActivityTimeout" type="int">
+      <desc>
+    	For WLAN the time (in seconds) to stay online when all socket activity has ceased. -1 for unlimited time.
+    	Leave empty to use the product default value.
+    	</desc>
+    </setting>
+  <setting name="WLAN last session closed timeout" ref="WlanLastSessionClosedTimeout" type="int">
+      <desc>
+    	For WLAN the time (in seconds) to stay online when all socket activity has ceased. -1 for unlimited time.
+    	Leave empty to use the product default value.
+    	</desc>
+    </setting>
+  <setting name="WLAN last socket closed timeout" ref="WlanLastSocketClosedTimeout" type="int">
+      <desc>
+    	For WLAN the time (in seconds) to stay online when all socket activity has ceased. -1 for unlimited time.
+    	Leave empty to use the product default value.
+    	</desc>
+    </setting>
+  <setting name="WLAN background scan interval" ref="WlanBGScanInterval" type="selection">
+      <desc>
+      How often WLAN networks are scanned when idle.
+      </desc>
+    <option name="Never" value="0" />
+    <option name="Every minute" value="60" />
+    <option name="Every 2 minutes" value="120" />
+    <option name="Every 5 minutes" value="300" />
+    <option name="Every 10 minutes" value="600" />
+    </setting>
+  <setting name="WLAN use default settings" ref="WlanUseDefSettings" type="selection">
+      <desc>Defines whether default values are being used for the advanced WLAN settings (recommended). </desc>
+    <option name="No" value="0" />
+    <option name="Yes" value="1" />
+    </setting>
+  <setting name="WLAN long retry limit" ref="WlanLongRetry" type="int">
+      <desc>Defines how many times packets bigger than RTS Threshold are been resent.</desc>
+    </setting>
+  <setting name="WLAN short retry limit" ref="WlanShortRetry" type="int">
+      <desc>Defines how many times packets smaller than RTS Threshold are been resent.</desc>
+    </setting>
+  <setting name="WLAN RTS threshold" ref="WlanRTS" type="int">
+      <desc>Minimum size of a packet for which CTS/RTS handshake has been used.</desc>
+    </setting>
+  <setting name="WLAN TX power level" ref="WlanTxPowerLevel" type="selection">
+      <desc>Transmission power level in use. In mWs. 4, 10 or 100 mW.</desc>
+    <option name="100 mW" value="100" />
+    <option name="10 mW" value="10" />
+    <option name="4 mW" value="4" />
+    </setting>
+  <setting name="WLAN allow radio measurements" ref="WlanRadioMeasurements" type="selection">
+      <desc>Defines whether the CCX radio measurements are allowed.</desc>
+    <option name="No" value="0" />
+    <option name="Yes" value="1" />
+    </setting>
+  <setting name="WLAN power save" ref="WlanPowerMode" type="selection">
+      <desc>Defines whether power saving methods are active. Disabling WLAN
+      power save might increase interoperability but will dramatically shorten battery life.</desc>
+    <option name="On" value="1" />
+    <option name="Off" value="0" />
+    </setting>
+  </feature>
+<feature name="GPRS Access Points" ref="APs">
+    <desc>GPRS connection method (CM) definitions</desc>
+  <setting maxOccurs="99" minOccurs="0" name="GPRS" ref="AP" type="sequence">
+      <setting name="Connection Name" ref="ConnectionName" type="string">
+        <desc>The CM name that is visible to the user.</desc>
+      </setting>
+    <setting name="Connection ID" ref="ConnectionId" type="int">
+        <desc>The CommsDat record id can be manually specified here. If left empty it is allocated automatically.
+      	Note: It needs to be verified carefully that the IDs are globally unique if allocated manually! 
+      	So a good idea is to either specify all the IDs manually or none at all.</desc>
+      </setting>
+    <setting name="Protected" ref="Protected" type="selection">
+        <desc>Defines whether connection method is protected (= cannot be edited by the user).</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="Hidden" ref="Hidden" type="selection">
+        <desc>Defines whether connection method is hidden.</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="Hidden Agent" ref="HiddenAgent" type="selection">
+        <desc>Connection method is hidden in CConnDlg or not (used to divide MMS and non-MMS CMs).</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="Highlighted" ref="Highlighted" type="selection">
+        <desc>Connection method is highlighted or not.</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="Seamlessness" ref="Seamlessness" type="selection">
+        <desc>Defines whether an IAP can be roamed to.</desc>
+      <option name="Confirm First" value="ConfirmFirst" />
+      <option name="Show Progress" value="ShowProgress" />
+      </setting>
+    <setting name="Network type" ref="NetworkType" type="selection">
+        <desc>Addressing that the network uses.</desc>
+      <option name="IPv4" value="IPv4" />
+      <option name="IPv6" value="IPv6" />
+      </setting>
+    <setting name="GPRS Access Point Name" ref="GPRS_AP_Name" type="string">
+        <desc>The access point name for this GPRS connection</desc>
+      </setting>
+    <setting name="User Name" ref="UserName" type="string">
+        <desc>User name</desc>
+      </setting>
+    <setting name="Prompt Password" ref="PromptPassword" type="selection">
+        <desc>Prompt password at connection time.</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="Password" ref="Password" type="string">
+        <desc>Password.</desc>
+      </setting>
+    <setting name="Password authentication type" ref="PasswordAuthenticationType" type="selection">
+        <desc>Password authentication method.</desc>
+      <option name="Normal" value="Normal" />
+      <option name="Secure" value="Secure" />
+      </setting>
+    <setting name="WAP Gateway IP" ref="WAPGatewayIP" type="string">
+        <desc>WAP gateway IP address.</desc>
+      </setting>
+    <setting name="Starting Page" ref="StartingPage" type="string">
+        <desc>Start page of the connection method. In URL format.</desc>
+      </setting>
+    <setting name="WTLS Security" ref="WTLS_Security" type="selection">
+        <desc>Attempts a secure WTLS connection to the gateway.</desc>
+      <option name="On" value="On" />
+      <option name="Off" value="Off" />
+      </setting>
+    <setting name="Connection type" ref="WAP_ConnectionType" type="selection">
+        <desc>Indicates whether a connection-oriented or connectionless API should be used.</desc>
+      <option name="Continuous" value="Continuous" />
+      <option name="Temporary" value="Temporary" />
+      </setting>
+    <setting name="IPv4 Phone IP address" ref="PhoneIP" type="string">
+        <desc>IP address of the interface. 
+        Typically allocated automatically so this can be left empty.</desc>
+      </setting>
+    <setting name="IPv4 Primary Name Server" ref="PrimaryNameServer" type="string">
+        <desc>Address of the primary DNS server that resolves host names. 
+        Typically allocated automatically so this can be left empty.</desc>
+      </setting>
+    <setting name="IPv4 Secondary Name Server" ref="SecondaryNameServer" type="string">
+        <desc>Address of the secondary DNS server to connect if the primary DNS server is not available.
+        Typically allocated automatically so this can be left empty.</desc>
+      </setting>
+    <setting name="IPv6 Primary Name Server" ref="PrimaryIP6NameServer" type="string">
+        <desc>Address of the primary DNS server that resolves host names.
+        Typically allocated automatically so this can be left empty.</desc>
+      </setting>
+    <setting name="IPv6 Secondary Name Server" ref="SecondaryIP6NameServer" type="string">
+        <desc>Address of the secondary DNS server to connect if the primary DNS server is not available.
+        Typically allocated automatically so this can be left empty.</desc>
+      </setting>
+    <setting name="Proxy Server Address" ref="ProxyServerAddress" type="string">
+        <desc>Address of the HTTP/HTTPS proxy server.</desc>
+      </setting>
+    <setting name="Proxy Port Number" ref="ProxyPortNumber" type="string">
+        <desc>Port number of the HTTP/HTTPS proxy server.</desc>
+      </setting>
+    <setting name="Proxy protocol Name" ref="ProxyProtocolName" type="string">
+        <desc>Name of the protocol for which this proxy can be used. 
+        Typically http or https.</desc>
+      </setting>
+    <setting name="GPRS Use EDGE" ref="GprsUseEdge" type="selection">
+        <desc>Allow EDGE usage.</desc>
+      <option name="Yes" value="Yes" />
+      <option name="No" value="No" />
+      </setting>
+    <setting name="ISP Type" ref="IspType" type="selection">
+        <desc>Specifies the service provider type. Used when filtering connection methods for certain purpose.</desc>
+      <option name="Internet" value="0" />
+      <option name="WAP" value="1" />
+      <option name="Both" value="2" />
+      </setting>
+    </setting>
+  </feature>
+<feature name="WLAN Access Points" ref="WLAN_APs">
+    <desc>WLAN connection method (CM) definitions</desc>
+  <setting maxOccurs="99" minOccurs="0" name="WLAN" ref="WLAN_AP" type="sequence">
+      <setting name="Connection Name" ref="ConnectionName" type="string">
+        <desc>The CM name that is visible to the user.</desc>
+      </setting>
+    <setting name="Connection ID" ref="ConnectionId" type="int">
+        <desc>The CommsDat record id can be manually specified here. If left empty it is allocated automatically.
+      	Note: It needs to be verified carefully that the IDs are globally unique if allocated manually! 
+      	So a good idea is to either specify all the IDs manually or none at all.</desc>
+      </setting>
+    <setting name="Protected" ref="Protected" type="selection">
+        <desc>Defines whether connection method is protected (= cannot be edited by the user).</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="Hidden" ref="Hidden" type="selection">
+        <desc>Defines whether connection method is hidden.</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="Hidden Agent" ref="HiddenAgent" type="selection">
+        <desc>Connection method is hidden in CConnDlg or not (used to divide MMS and non-MMS CMs).</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="Highlighted" ref="Highlighted" type="selection">
+        <desc>Connection method is highlighted or not.</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="Seamlessness" ref="Seamlessness" type="selection">
+        <desc>Defines whether an IAP can be roamed to.</desc>
+      <option name="Confirm First" value="ConfirmFirst" />
+      <option name="Show Progress" value="ShowProgress" />
+      </setting>
+    <setting name="Network Name" ref="NetworkName" type="string">
+        <desc>Service set identifier (SSID) of the primary WLAN network.</desc>
+      </setting>
+    <setting name="Starting Page" ref="StartingPage" type="string">
+        <desc>Start page of the connection method. In URL format.</desc>
+      </setting>
+    <setting name="Network Mode" ref="NetworkMode" type="string">
+        <desc>Determines the network infrastructure. 
+        If there is a WLAN access point in the network then this should be Infrastructure.</desc>
+      <option name="Infrastructure" value="Infrastructure" />
+      <option name="Ad-hoc" value="Ad-hoc" />
+      </setting>
+    <setting name="Security Mode" ref="SecurityMode" type="selection">
+        <desc>Security mode of the WLAN network.</desc>
+      <option name="Open" value="Open" />
+      <option name="WEP" value="WEP" />
+      <option name="802.1x" value="802.1x" />
+      <option name="WPA" value="WPA" />
+      <option name="WPA2" value="WPA2" />
+      </setting>
+    <setting name="IPv4 Primary Name Server" ref="PrimaryNameServer" type="string">
+        <desc>Address of the primary DNS server that resolves host names.
+        Typically allocated automatically in which case this should be empty.</desc>
+      </setting>
+    <setting name="IPv4 Secondary Name Server" ref="SecondaryNameServer" type="string">
+        <desc>Address of the secondary DNS server to connect if the primary DNS server is not available.
+        Typically allocated automatically in which case this should be empty.</desc>
+      </setting>
+    <setting name="IPv6 Primary Name Server" ref="PrimaryIP6NameServer" type="string">
+        <desc>Address of the primary DNS server that resolves host names.
+        Typically allocated automatically in which case this should be empty.</desc>
+      </setting>
+    <setting name="IPv6 Secondary Name Server" ref="SecondaryIP6NameServer" type="string">
+        <desc>Address of the secondary DNS server to connect if the primary DNS server is not available.
+        Typically allocated automatically in which case this should be empty.</desc>
+      </setting>
+    <setting name="WLAN IP Gateway Address" ref="WlanIpGatewayAddress" type="string">
+        <desc>The gateway IP address. 
+      Typically allocated automatically in which case this should be empty.</desc>
+      </setting>
+    <setting name="Wlan IP Net Mask" ref="WlanIpNetMask" type="string">
+        <desc>Network mask. Typically allocated automatically in which case this should be empty.</desc>
+      </setting>
+    <setting name="Proxy Server Address" ref="ProxyServerAddress" type="string">
+        <desc>Address of the HTTP/HTTPS proxy server.</desc>
+      </setting>
+    <setting name="Proxy Port Number" ref="ProxyPortNumber" type="string">
+        <desc>Port number of the HTTP/HTTPS proxy server.</desc>
+      </setting>
+    <setting name="Proxy protocol Name" ref="ProxyProtocolName" type="string">
+        <desc>Name of the protocol for which this proxy can be used. 
+        Typically http or https.</desc>
+      </setting>
+    <setting name="WLAN Scan SSID" ref="WLANScanSSID" type="selection">
+        <desc>Defines whether the SSID should be actively scanned. 
+        This is needed if the SSID is hidden (not broadcasted by the AP) </desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="WLAN Channel ID" ref="WlanChannelId" type="string">
+        <desc>
+      	802.11 Channel ID (1-14). Used only when connecting/setting up adhoc network.
+      	</desc>
+      </setting>
+    <setting name="IPv4 Phone IP address" ref="PhoneIP" type="string">
+        <desc>IP address of the interface.
+        Typically allocated automatically so this can be left empty.</desc>
+      </setting>
+    <setting name="WEP Key In Use" ref="WEPKeyInUse" type="selection">
+        <desc>Index of default WEP key. Used only when security mode is WEP.</desc>
+      <option name="key1" value="key1" />
+      <option name="key2" value="key2" />
+      <option name="key3" value="key3" />
+      <option name="key4" value="key4" />
+      </setting>
+    <setting name="WEP Auth Type" ref="WEPAuthType" type="selection">
+        <desc>WEP authentication mode. Only used when security mode is WEP.</desc>
+      <option name="Shared" value="Shared" />
+      <option name="Open" value="Open" />
+      </setting>
+    <setting name="WEP Key1 Length" ref="WEPKey1Length" type="selection">
+        <desc>WEP key length in bits.</desc>
+      <option name="64" value="64" />
+      <option name="128" value="128" />
+      <option name="256" value="256" />
+      </setting>
+    <setting name="WEP Key1 Format" ref="WEPKey1Format" type="selection">
+        <desc>WEP key format.</desc>
+      <option name="ASCII" value="ASCII" />
+      <option name="Hexadecimal" value="Hexadecimal" />
+      </setting>
+    <setting name="WEP Key1 Data" ref="WEPKey1Data" type="string">
+        <desc>WEP key data (in format specified by corresponding WEP key format field).</desc>
+      </setting>
+    <setting name="WEP Key2 Length" ref="WEPKey2Length" type="selection">
+        <desc>WEP key length in bits.</desc>
+      <option name="64" value="64" />
+      <option name="128" value="128" />
+      <option name="256" value="256" />
+      </setting>
+    <setting name="WEP Key2 Format" ref="WEPKey2Format" type="selection">
+        <desc>WEP key format.</desc>
+      <option name="ASCII" value="ASCII" />
+      <option name="Hexadecimal" value="Hexadecimal" />
+      </setting>
+    <setting name="WEP Key2 Data" ref="WEPKey2Data" type="string">
+        <desc>WEP key data (in format specified by corresponding WEP key format field).</desc>
+      </setting>
+    <setting name="WEP Key3 Length" ref="WEPKey3Length" type="selection">
+        <desc>WEP key length in bits.</desc>
+      <option name="64" value="64" />
+      <option name="128" value="128" />
+      <option name="256" value="256" />
+      </setting>
+    <setting name="WEP Key3 Format" ref="WEPKey3Format" type="selection">
+        <desc>WEP key format.</desc>
+      <option name="ASCII" value="ASCII" />
+      <option name="Hexadecimal" value="Hexadecimal" />
+      </setting>
+    <setting name="WEP Key3 Data" ref="WEPKey3Data" type="string">
+        <desc>WEP key data (in format specified by corresponding WEP key format field).</desc>
+      </setting>
+    <setting name="WEP Key4 Length" ref="WEPKey4Length" type="selection">
+        <desc>WEP key length in bits.</desc>
+      <option name="64" value="64" />
+      <option name="128" value="128" />
+      <option name="256" value="256" />
+      </setting>
+    <setting name="WEP Key4 Format" ref="WEPKey4Format" type="selection">
+        <desc>WEP key format.</desc>
+      <option name="ASCII" value="ASCII" />
+      <option name="Hexadecimal" value="Hexadecimal" />
+      </setting>
+    <setting name="WEP Key4 Data" ref="WEPKey4Data" type="string">
+        <desc>WEP key data (in format specified by corresponding WEP key format field).</desc>
+      </setting>
+    <setting name="WPA Pre-shared Key" ref="WPAPresharedKey" type="string">
+        <desc>WPA/WPA2 pre-shared key in plain text. ASCII character set values between 32-126 must be used. Minimum length is 8 characters and maximum 63.
+        You need to also define the WPA pre-shared key length field accordingly</desc>
+      </setting>
+    <setting name="WPA Use of Pre-shared Key" ref="WPAUseOfPresharedKey" type="selection">
+        <desc>Specifies that when the security mode is WPA or WPA2 if the PSK mode is enabled. 
+        If this is off then EAP mode is used and the list of EAPs needs to be defined.</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="WPA Pre-shared key length" ref="WPAKeyLength" type="int">
+        <desc>The length of the specified pre-shared key (in WPA pre-shared key field)</desc>
+      </setting>
+    <setting name="WPA List Of EAPs" ref="WPAListOfEAPs" type="string">
+        <desc>
+      	A list of Extensible Authentication Protocols (EAPs) in use. The format is +xxx,+xxx,+xxx where xxx indicates the enabled EAP method ID as
+      	specified in the IANA registry: http://www.iana.org/assignments/eap-numbers. For example to enable EAP-SIM the string needs to be "+018". 
+      	The list is in priority order, highest priority first.      	
+      	</desc>
+      </setting>
+    <setting name="EAP-GTC user name" ref="EapGtcUsername" type="string">
+        <desc>The username used with EAP-GTC.</desc>
+      </setting>
+    <setting name="EAP-GTC session validity time" ref="EapGtcSessionValidityTime" type="int">
+        <desc>Specifies how long single session is kept in memory (so no new password queries or similar appear).</desc>
+      </setting>
+    <setting name="EAP-GTC tunneling method" ref="EapGtcEncapsulation" type="selection">
+        <desc>Defines which EAP tunneling method is used with EAP-GTC.</desc>
+      <option name="EAP-PEAP" value="25" />
+      <option name="EAP-TTLS" value="21" />
+      <option name="EAP-FAST" value="43" />
+      </setting>
+    <setting name="EAP-TLS user name" ref="EapTlsUsername" type="string">
+        <desc>The username used with EAP-TLS.</desc>
+      </setting>
+    <setting name="EAP-TLS realm" ref="EapTlsRealm" type="string">
+        <desc>The realm used for device identification to the server.</desc>
+      </setting>
+    <setting name="EAP-TLS verify server realm" ref="EapTlsVerifyServerRealm" type="selection">
+        <desc>Specifies whether the server's realm is compared with own realm. 
+      	This provides extra security but it depends on the network infrastructure and set-up whether this will work.</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="EAP-TLS require client authentication" ref="EapTlsRequireClientAuth" type="selection">
+        <desc>Specifies whether TLS requires that the server authenticates it (the client).</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="EAP-TLS session validity time" ref="EapTlsSessionValidityTime" type="int">
+        <desc>Specifies how long single session is kept in memory (so no new password queries or similar appear)</desc>
+      </setting>
+    <setting name="EAP-TLS cipher suites" ref="EapTlsCipherSuites" type="string">
+        <desc>The list of allowed cipher suites. In the format +xxx,+xxx,+xxx... where xxx is the cipher suite identifier.
+      	004: TLS_RSA_WITH_RC4_128_MD5, 005: TLS_RSA_WITH_RC4_128_SHA, 010: TLS_RSA_WITH_3DES_EDE_CBC_SHA,
+				019:	TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, 022: TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, 047: TLS_RSA_WITH_AES_128_CBC_SHA
+				050:	TLS_DHE_DSS_WITH_AES_128_CBC_SHA, 051:	TLS_DHE_RSA_WITH_AES_128_CBC_SHA, 052: TLS_DH_anon_WITH_AES_128_CBC_SHA 
+				For example +004 enables only RSA with RC4 and MD5.
+				</desc>
+      </setting>
+    <setting name="EAP-TLS user certificate subject key id" ref="EapTlsUserCertSubjectKeyId" type="string">
+        <desc>The subject key id value of the user certificate. 
+        Currently this field is the only one that can be used to identify the certificate.</desc>
+      </setting>
+    <setting name="EAP-TLS user certificate issuer" ref="EapTlsUserCertIssuerName" type="string">
+        <desc>The issuer of the user certificate. Ignored by the implementation currently!</desc>
+      </setting>
+    <setting name="EAP-TLS user certificate serial number" ref="EapTlsUserCertSerialNumber" type="string">
+        <desc>The serial number of the user certificate. Ignored by the implementation currently!</desc>
+      </setting>
+    <setting name="EAP-TLS CA certificate subject key id" ref="EapTlsCaCertSubjectKeyId" type="string">
+        <desc>The subject key id value of the CA certificate.
+        Currently this field is the only one that can be used to identify the certificate.</desc>
+      </setting>
+    <setting name="EAP-TLS CA certificate issuer" ref="EapTlsCaCertIssuerName" type="string">
+        <desc>The issuer of the CA certificate. Ignored by the implementation currently!</desc>
+      </setting>
+    <setting name="EAP-TLS CA certificate serial number" ref="EapTlsCaCertSerialNumber" type="string">
+        <desc>The serial number of the CA certificate. Ignored by the implementation currently!</desc>
+      </setting>
+    <setting name="EAP-TLS tunneling method" ref="EapTlsEncapsulation" type="selection">
+        <desc>Defines which EAP tunneling method is used with EAP-TLS.</desc>
+      <option name="None" value="" />
+      <option name="EAP-PEAP" value="25" />
+      <option name="EAP-TTLS" value="21" />
+      <option name="EAP-FAST" value="43" />
+      </setting>
+    <setting name="EAP-LEAP user name" ref="EapLeapUsername" type="string">
+        <desc>The username used with EAP-LEAP.</desc>
+      </setting>
+    <setting name="EAP-LEAP password" ref="EapLeapPassword" type="string">
+        <desc>The password used with EAP-LEAP.</desc>
+      </setting>
+    <setting name="EAP-LEAP session validity time" ref="EapLeapSessionValidityTime" type="int">
+        <desc>Specifies how long single session is kept in memory (so no new password queries or similar appear).</desc>
+      </setting>
+    <setting name="EAP-SIM user name" ref="EapSimUsername" type="string">
+        <desc>The username used with EAP-SIM.</desc>
+      </setting>
+    <setting name="EAP-SIM realm" ref="EapSimRealm" type="string">
+        <desc>The realm used for device identification to the server.</desc>
+      </setting>
+    <setting name="EAP-SIM pseudonyms allowed" ref="EapSimUsePseudonyms" type="selection">
+        <desc>Specifies whether IMSI is sent always when authentication or is pseudonym usage allowed.</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="EAP-SIM session validity time" ref="EapSimSessionValidityTime" type="int">
+        <desc>Specifies how long single session is kept in memory (so no new password queries or similar appear)</desc>
+      </setting>
+    <setting name="EAP-SIM tunneling method" ref="EapSimEncapsulation" type="selection">
+        <desc>Defines which EAP tunneling method is used with EAP-SIM.</desc>
+      <option name="None" value="" />
+      <option name="EAP-PEAP" value="25" />
+      <option name="EAP-TTLS" value="21" />
+      <option name="EAP-FAST" value="43" />
+      </setting>
+    <setting name="EAP-TTLS user name" ref="EapTtlsUsername" type="string">
+        <desc>The username used with EAP-TTLS.</desc>
+      </setting>
+    <setting name="EAP-TTLS realm" ref="EapTtlsRealm" type="string">
+        <desc>The realm used for device identification to the server.</desc>
+      </setting>
+    <setting name="EAP-TTLS verify server realm" ref="EapTtlsVerifyServerRealm" type="selection">
+        <desc>Specifies whether the server's realm is compared with own realm. 
+      	This provides extra security but it depends on the network infrastructure and set-up whether this will work.</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="EAP-TTLS require client authentication" ref="EapTtlsRequireClientAuth" type="selection">
+        <desc>Specifies whether TTLS requires that the server authenticates it (the client).</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="EAP-TTLS session validity time" ref="EapTtlsSessionValidityTime" type="int">
+        <desc>Specifies how long single session is kept in memory (so no new password queries or similar appear).</desc>
+      </setting>
+    <setting name="EAP-TTLS cipher suites" ref="EapTtlsCipherSuites" type="string">
+        <desc>The list of allowed cipher suites. In the format +xxx,+xxx,+xxx... where xxx is the cipher suite identifier.
+      	004: TLS_RSA_WITH_RC4_128_MD5, 005: TLS_RSA_WITH_RC4_128_SHA, 010: TLS_RSA_WITH_3DES_EDE_CBC_SHA,
+				019:	TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, 022: TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, 047: TLS_RSA_WITH_AES_128_CBC_SHA
+				050:	TLS_DHE_DSS_WITH_AES_128_CBC_SHA, 051:	TLS_DHE_RSA_WITH_AES_128_CBC_SHA, 052: TLS_DH_anon_WITH_AES_128_CBC_SHA 
+				For example +004 enables only RSA with RC4 and MD5.
+				</desc>
+      </setting>
+    <setting name="EAP-TTLS tunneled methods" ref="EapTtlsEncapsulatedTypes" type="string">
+        <desc>A list of Extensible Authentication Protocols (EAPs) in tunneled by EAP-TTLS. The format is +xxx,+xxx,+xxx where xxx indicates the enabled EAP method ID as
+      	specified in the IANA registry: http://www.iana.org/assignments/eap-numbers. For example to enable EAP-SIM encapsulation the string needs to be "+018". 
+      	The list is in priority order, highest priority first. Note that the encapsulate type's encapsulation parameter needs to be configured accordingly. </desc>
+      </setting>
+    <setting name="EAP-TTLS user certificate subject key id" ref="EapTtlsUserCertSubjectKeyId" type="string">
+        <desc>The subject key id value of the user certificate.
+        Currently this field is the only one that can be used to identify the certificate.</desc>
+      </setting>
+    <setting name="EAP-TTLS user certificate issuer" ref="EapTtlsUserCertIssuerName" type="string">
+        <desc>The issuer of the user certificate. Ignored by the implementation currently!</desc>
+      </setting>
+    <setting name="EAP-TTLS user certificate serial number" ref="EapTtlsUserCertSerialNumber" type="string">
+        <desc>The serial number of the user certificate. Ignored by the implementation currently!</desc>
+      </setting>
+    <setting name="EAP-TTLS CA certificate subject key id" ref="EapTtlsCaCertSubjectKeyId" type="string">
+        <desc>The subject key id value of the CA certificate.
+        Currently this field is the only one that can be used to identify the certificate.</desc>
+      </setting>
+    <setting name="EAP-TTLS CA certificate issuer" ref="EapTtlsCaCertIssuerName" type="string">
+        <desc>The issuer of the CA certificate. Ignored by the implementation currently!</desc>
+      </setting>
+    <setting name="EAP-TTLS CA certificate serial number" ref="EapTtlsCaCertSerialNumber" type="string">
+        <desc>The serial number of the CA certificate. Ignored by the implementation currently!</desc>
+      </setting>
+    <setting name="EAP-AKA user name" ref="EapAkaUsername" type="string">
+        <desc>The username used with EAP-AKA.</desc>
+      </setting>
+    <setting name="EAP-AKA realm" ref="EapAkaRealm" type="string">
+        <desc>The realm used for device identification to the server.</desc>
+      </setting>
+    <setting name="EAP-AKA pseudonyms allowed" ref="EapAkaUsePseudonyms" type="selection">
+        <desc>Specifies whether IMSI is sent always when authentication or is pseudonym usage allowed.</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="EAP-AKA session validity time" ref="EapAkaSessionValidityTime" type="int">
+        <desc>Specifies how long single session is kept in memory (so no new password queries or similar appear).</desc>
+      </setting>
+    <setting name="EAP-AKA tunneling method" ref="EapAkaEncapsulation" type="selection">
+        <desc>Defines which EAP tunneling method is used with EAP-AKA.</desc>
+      <option name="None" value="" />
+      <option name="EAP-PEAP" value="25" />
+      <option name="EAP-TTLS" value="21" />
+      <option name="EAP-FAST" value="43" />
+      </setting>
+    <setting name="EAP-PEAP user name" ref="EapPeapUsername" type="string">
+        <desc>The username used with EAP-PEAP.</desc>
+      </setting>
+    <setting name="EAP-PEAP realm" ref="EapPeapRealm" type="string">
+        <desc>The realm used for device identification to the server.</desc>
+      </setting>
+    <setting name="EAP-PEAP verify server realm" ref="EapPeapVerifyServerRealm" type="selection">
+        <desc>Specifies whether the server's realm is compared with own realm. 
+      	This provides extra security but it depends on the network infrastructure and set-up whether this will work.</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="EAP-PEAP require client authentication" ref="EapPeapRequireClientAuth" type="selection">
+        <desc>Specifies whether PEAP requires that the server authenticates it (the client).</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="EAP-PEAP session validity time" ref="EapPeapSessionValidityTime" type="int">
+        <desc>Specifies how long single session is kept in memory (so no new password queries or similar appear)</desc>
+      </setting>
+    <setting name="EAP-PEAP cipher suites" ref="EapPeapCipherSuites" type="string">
+        <desc>The list of allowed cipher suites. In the format +xxx,+xxx,+xxx... where xxx is the cipher suite identifier.
+      	004: TLS_RSA_WITH_RC4_128_MD5, 005: TLS_RSA_WITH_RC4_128_SHA, 010: TLS_RSA_WITH_3DES_EDE_CBC_SHA,
+				019:	TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, 022: TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, 047: TLS_RSA_WITH_AES_128_CBC_SHA
+				050:	TLS_DHE_DSS_WITH_AES_128_CBC_SHA, 051:	TLS_DHE_RSA_WITH_AES_128_CBC_SHA, 052: TLS_DH_anon_WITH_AES_128_CBC_SHA 
+				For example +004 enables only RSA with RC4 and MD5.
+				</desc>
+      </setting>
+    <setting name="EAP-PEAP version 0 allowed" ref="EapPeapV0Allowed" type="selection">
+        <desc>Is PEAP version 0 allowed. If in doubt enable only this one.</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="EAP-PEAP version 1 allowed" ref="EapPeapV1Allowed" type="selection">
+        <desc>Is PEAP version 1 allowed.</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="EAP-PEAP version 2 allowed" ref="EapPeapV2Allowed" type="selection">
+        <desc>Is PEAP version 2 allowed.</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="EAP-PEAP tunneled methods" ref="EapPeapEncapsulatedTypes" type="string">
+        <desc>A list of Extensible Authentication Protocols (EAPs) in tunneled by EAP-PEAP. The format is +xxx,+xxx,+xxx where xxx indicates the enabled EAP method ID as
+      	specified in the IANA registry: http://www.iana.org/assignments/eap-numbers. For example to enable EAP-SIM encapsulation the string needs to be "+018". 
+      	The list is in priority order, highest priority first. Note that the encapsulate type's encapsulation parameter needs to be configured accordingly. </desc>
+      </setting>
+    <setting name="EAP-PEAP user certificate subject key id" ref="EapPeapUserCertSubjectKeyId" type="string">
+        <desc>The subject key id value of the user certificate.
+        Currently this field is the only one that can be used to identify the certificate.</desc>
+      </setting>
+    <setting name="EAP-PEAP user certificate issuer" ref="EapPeapUserCertIssuerName" type="string">
+        <desc>The issuer of the user certificate. Ignored by the implementation currently!</desc>
+      </setting>
+    <setting name="EAP-PEAP user certificate serial number" ref="EapPeapUserCertSerialNumber" type="string">
+        <desc>The serial number of the user certificate. Ignored by the implementation currently!</desc>
+      </setting>
+    <setting name="EAP-PEAP CA certificate subject key id" ref="EapPeapCaCertSubjectKeyId" type="string">
+        <desc>The subject key id value of the CA certificate.
+        Currently this field is the only one that can be used to identify the certificate.</desc>
+      </setting>
+    <setting name="EAP-PEAP CA certificate issuer" ref="EapPeapCaCertIssuerName" type="string">
+        <desc>The issuer of the CA certificate. Ignored by the implementation currently!</desc>
+      </setting>
+    <setting name="EAP-PEAP CA certificate serial number" ref="EapPeapCaCertSerialNumber" type="string">
+        <desc>The serial number of the CA certificate. Ignored by the implementation currently!</desc>
+      </setting>
+    <setting name="EAP-MSCHAPv2 user name" ref="EapMschapv2Username" type="string">
+        <desc>The username used with EAP-MSCHAPv2.</desc>
+      </setting>
+    <setting name="EAP-MSCHAPv2 password" ref="EapMschapv2Password" type="string">
+        <desc>The password used with EAP-MSCHAPv2.</desc>
+      </setting>
+    <setting name="EAP-MSCHAPv2 session validity time" ref="EapMschapv2SessionValidityTime" type="int">
+        <desc>Specifies how long single session is kept in memory (so no new password queries or similar appear)</desc>
+      </setting>
+    <setting name="EAP-MSCHAPv2 tunneling method" ref="EapMschapv2Encapsulation" type="selection">
+        <desc>Defines which EAP tunneling method is used with EAP-MSCHAPv2.</desc>
+      <option name="EAP-PEAP" value="25" />
+      <option name="EAP-TTLS" value="21" />
+      <option name="EAP-FAST" value="43" />
+      </setting>
+    <setting name="EAP-FAST user name" ref="EapFastUsername" type="string">
+        <desc>The username used with EAP-FAST.</desc>
+      </setting>
+    <setting name="EAP-FAST realm" ref="EapFastRealm" type="string">
+        <desc>The realm used for device identification to the server.</desc>
+      </setting>
+    <setting name="EAP-FAST verify server realm" ref="EapFastVerifyServerRealm" type="selection">
+        <desc>Specifies whether the server's realm is compared with own realm. 
+      	This provides extra security but it depends on the network infrastructure and set-up whether this will work.</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="EAP-FAST require client authentication" ref="EapFastRequireClientAuth" type="selection">
+        <desc>Specifies whether TTLS requires that the server authenticates it (the client).</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="EAP-FAST session validity time" ref="EapFastSessionValidityTime" type="int">
+        <desc>Specifies how long single session is kept in memory (so no new password queries or similar appear)</desc>
+      </setting>
+    <setting name="EAP-FAST cipher suites" ref="EapFastCipherSuites" type="string">
+        <desc>The list of allowed cipher suites. In the format +xxx,+xxx,+xxx... where xxx is the cipher suite identifier.
+      	004: TLS_RSA_WITH_RC4_128_MD5, 005: TLS_RSA_WITH_RC4_128_SHA, 010: TLS_RSA_WITH_3DES_EDE_CBC_SHA,
+				019:	TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, 022: TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, 047: TLS_RSA_WITH_AES_128_CBC_SHA
+				050:	TLS_DHE_DSS_WITH_AES_128_CBC_SHA, 051:	TLS_DHE_RSA_WITH_AES_128_CBC_SHA, 052: TLS_DH_anon_WITH_AES_128_CBC_SHA 
+				For example +004 enables only RSA with RC4 and MD5.
+				</desc>
+      </setting>
+    <setting name="EAP-FAST tunneled methods" ref="EapFastEncapsulatedTypes" type="string">
+        <desc>A list of Extensible Authentication Protocols (EAPs) in tunneled by EAP-FAST. The format is +xxx,+xxx,+xxx where xxx indicates the enabled EAP method ID as
+      	specified in the IANA registry: http://www.iana.org/assignments/eap-numbers. For example to enable EAP-SIM encapsulation the string needs to be "+018". 
+      	The list is in priority order, highest priority first. Note that the encapsulate type's encapsulation parameter needs to be configured accordingly. </desc>
+      </setting>
+    <setting name="EAP-FAST authenticated provisioning mode allowed" ref="EapFastAuthProvModeAllowed" type="selection">
+        <desc>EAP-FAST authenticated provisioning mode allowed</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="EAP-FAST unauthenticated provisioning mode allowed" ref="EapFastUnauthProvModeAllowed" type="selection">
+        <desc>EAP-FAST unauthenticated provisioning mode allowed</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="EAP-FAST warn ADHP no PAC" ref="EapFastWarnADHPNoPAC" type="selection">
+        <desc>EAP-FAST warn ADHP no PAC</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="EAP-FAST warn ADHP no matching PAC" ref="EapFastWarnADHPNoMatchingPAC" type="selection">
+        <desc>EAP-FAST warn ADHP no matching PAC</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="EAP-FAST warn not default server" ref="EapFastWarnNotDefaultServer" type="selection">
+        <desc>EAP-FAST warn not default server</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="EAP-FAST user certificate subject key id" ref="EapFastUserCertSubjectKeyId" type="string">
+        <desc>The subject key id value of the user certificate.
+        Currently this field is the only one that can be used to identify the certificate.</desc>
+      </setting>
+    <setting name="EAP-FAST user certificate issuer" ref="EapFastUserCertIssuerName" type="string">
+        <desc>The issuer of the user certificate. Ignored by the implementation currently!</desc>
+      </setting>
+    <setting name="EAP-FAST user certificate serial number" ref="EapFastUserCertSerialNumber" type="string">
+        <desc>The serial number of the user certificate. Ignored by the implementation currently!</desc>
+      </setting>
+    <setting name="EAP-FAST CA certificate subject key id" ref="EapFastCaCertSubjectKeyId" type="string">
+        <desc>The subject key id value of the CA certificate.
+        Currently this field is the only one that can be used to identify the certificate.</desc>
+      </setting>
+    <setting name="EAP-FAST CA certificate issuer" ref="EapFastCaCertIssuerName" type="string">
+        <desc>The issuer of the CA certificate. Ignored by the implementation currently!</desc>
+      </setting>
+    <setting name="EAP-FAST CA certificate serial number" ref="EapFastCaCertSerialNumber" type="string">
+        <desc>The serial number of the CA certificate. Ignored by the implementation currently!</desc>
+      </setting>
+    <setting name="MSCHAPv2 user name" ref="Mschapv2Username" type="string">
+        <desc>The username used with MSCHAPv2.</desc>
+      </setting>
+    <setting name="MSCHAPv2 password" ref="Mschapv2Password" type="string">
+        <desc>The password used with MSCHAPv2.</desc>
+      </setting>
+    <setting name="MSCHAPv2 session validity time" ref="Mschapv2SessionValidityTime" type="int">
+        <desc>Specifies how long single session is kept in memory (so no new password queries or similar appear).</desc>
+      </setting>
+    <setting name="MSCHAPv2 tunneling method" ref="Mschapv2Encapsulation" type="selection">
+        <desc>Defines which EAP tunneling method is used with MSCHAPv2. Needs to be EAP-TTLS.</desc>
+      <option name="EAP-TTLS" value="21" />
+      </setting>
+    </setting>
+  </feature>
+<feature name="CSD Access Points" ref="CSD_APs">
+    <desc>Circuit-Switched Data connection methods</desc>
+  <setting maxOccurs="99" minOccurs="0" name="CSD" ref="CSD_AP" type="sequence">
+      <setting name="Connection Name" ref="ConnectionName" type="string">
+        <desc>The CM name that is visible to the user.</desc>
+      </setting>
+    <setting name="Connection ID" ref="ConnectionId" type="int">
+        <desc>The CommsDat record id can be manually specified here. If left empty it is allocated automatically.
+      	Note: It needs to be verified carefully that the IDs are globally unique if allocated manually! 
+      	So a good idea is to either specify all the IDs manually or none at all.</desc>
+      </setting>
+    <setting name="Protected" ref="Protected" type="selection">
+        <desc>Defines whether connection method is protected (= cannot be edited by the user).</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="Hidden" ref="Hidden" type="selection">
+        <desc>Defines whether connection method is hidden.</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="Hidden Agent" ref="HiddenAgent" type="selection">
+        <desc>Connection method is hidden in CConnDlg or not (used to divide MMS and non-MMS CMs).</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="Highlighted" ref="Highlighted" type="selection">
+        <desc>Connection method is highlighted or not.</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="Seamlessness" ref="Seamlessness" type="selection">
+        <desc>Defines whether an IAP can be roamed to.</desc>
+      <option name="Confirm First" value="ConfirmFirst" />
+      <option name="Show Progress" value="ShowProgress" />
+      </setting>
+    <setting name="User Name" ref="UserName" type="string">
+        <desc>Username for the connection.</desc>
+      </setting>
+    <setting name="Prompt Password" ref="PromptPassword" type="selection">
+        <desc>Prompt password on connection set-up time.</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="Password" ref="Password" type="string">
+        <desc>Password.</desc>
+      </setting>
+    <setting name="Password Authentication type" ref="PasswordAuthenticationType" type="selection">
+        <desc>Password authentication type.</desc>
+      <option name="Normal" value="Normal" />
+      <option name="Secure" value="Secure" />
+      </setting>
+    <setting name="WAP Gateway IP" ref="WAPGatewayIP" type="string">
+        <desc>WAP gateway IP.</desc>
+      </setting>
+    <setting name="Starting Page" ref="StartingPage" type="string">
+        <desc>Starting page.</desc>
+      </setting>
+    <setting name="WTLS Security" ref="WTLS_Security" type="selection">
+        <desc>WTLS security.</desc>
+      <option name="On" value="On" />
+      <option name="Off" value="Off" />
+      </setting>
+    <setting name="Connection type" ref="WAP_ConnectionType" type="selection">
+        <desc>Connection type.</desc>
+      <option name="Continuous" value="Continuous" />
+      <option name="Temporary" value="Temporary" />
+      </setting>
+    <setting name="IPv4 Phone IP address" ref="PhoneIP" type="string">
+        <desc>IP address of the interface. 
+        Typically allocated automatically so this can be left empty.</desc>
+      </setting>
+    <setting name="IPv4 Primary Name Server" ref="PrimaryNameServer" type="string">
+        <desc>Address of the primary DNS server that resolves host names. 
+        Typically allocated automatically so this can be left empty.</desc>
+      </setting>
+    <setting name="IPv4 Secondary Name Server" ref="SecondaryNameServer" type="string">
+        <desc>Address of the secondary DNS server to connect if the primary DNS server is not available.
+        Typically allocated automatically so this can be left empty.</desc>
+      </setting>
+    <setting name="IPv6 Primary Name Server" ref="PrimaryIP6NameServer" type="string">
+        <desc>Address of the primary DNS server that resolves host names.
+        Typically allocated automatically so this can be left empty.</desc>
+      </setting>
+    <setting name="IPv6 Secondary Name Server" ref="SecondaryIP6NameServer" type="string">
+        <desc>Address of the secondary DNS server to connect if the primary DNS server is not available.
+        Typically allocated automatically so this can be left empty.</desc>
+      </setting>
+    <setting name="Proxy Server Address" ref="ProxyServerAddress" type="string">
+        <desc>Address of the HTTP/HTTPS proxy server.</desc>
+      </setting>
+    <setting name="Proxy Port Number" ref="ProxyPortNumber" type="string">
+        <desc>Port number of the HTTP/HTTPS proxy server.</desc>
+      </setting>
+    <setting name="Proxy protocol Name" ref="ProxyProtocolName" type="string">
+        <desc>Name of the protocol for which this proxy can be used. 
+        Typically http or https.</desc>
+      </setting>
+    <setting name="Default Tel Number (Mandatory)" ref="DefaultTelNumber" type="string">
+        <desc>Default telephone number.</desc>
+      </setting>
+    <setting name="Bearer Speed" ref="BearerSpeed" type="selection">
+        <desc>Bearer speed</desc>
+      <option name="Autodetect" value="Autodetect" />
+      <option name="9600" value="9600" />
+      <option name="14400" value="14400" />
+      <option name="19200" value="19200" />
+      <option name="28800" value="28800" />
+      <option name="38400" value="38400" />
+      <option name="43200" value="43200" />
+      <option name="56000" value="56000" />
+      </setting>
+    <setting name="Bearer Call Type Isdn" ref="BearerCallTypeIsdn" type="selection">
+        <desc>Bearer Call Type Isdn</desc>
+      <option name="Analogue" value="Analogue" />
+      <option name="Isdn v110" value="Isdn v110" />
+      <option name="Isdn v120" value="Isdn v120" />
+      </setting>
+    <setting name="Call back Enabled" ref="CallbackEnabled" type="selection">
+        <desc>Is callback enabled.</desc>
+      <option name="Yes" value="Yes" />
+      <option name="No" value="No" />
+      </setting>
+    <setting name="Call back type" ref="CallbackType" type="selection">
+        <desc>Callback type.</desc>
+      <option name="Server Number" value="Server Number" />
+      <option name="Other Number" value="Other Number" />
+      </setting>
+    <setting name="Call back number" ref="CallbackInfo" type="string">
+        <desc>Callback number.</desc>
+      </setting>
+    <setting name="Enable PPP Compression" ref="EnableSWCompression" type="selection">
+        <desc>Enable compression</desc>
+      <option name="Yes" value="Yes" />
+      <option name="No" value="No" />
+      </setting>
+    <setting name="Use Login Script" ref="UseLoginScript" type="selection">
+        <desc>Use login script</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="Login Script" ref="LoginScript" type="string">
+        <desc>Login script</desc>
+      </setting>
+    <setting name="Modem init string" ref="InitString" type="string">
+        <desc>Modem init string</desc>
+      </setting>
+    </setting>
+  </feature>
+<feature name="HSCD Access Points" ref="HSCSD_APs">
+    <desc>High-speed Circuit-Switched Data connection methods</desc>
+  <setting maxOccurs="99" minOccurs="0" name="HSCSD" ref="HSCSD_AP" type="sequence">
+      <setting name="Connection Name" ref="ConnectionName" type="string">
+        <desc>The CM name that is visible to the user.</desc>
+      </setting>
+    <setting name="Connection ID" ref="ConnectionId" type="int">
+        <desc>The CommsDat record id can be manually specified here. If left empty it is allocated automatically.
+      	Note: It needs to be verified carefully that the IDs are globally unique if allocated manually! 
+      	So a good idea is to either specify all the IDs manually or none at all.</desc>
+      </setting>
+    <setting name="Protected" ref="Protected" type="selection">
+        <desc>Defines whether connection method is protected (= cannot be edited by the user).</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="Hidden" ref="Hidden" type="selection">
+        <desc>Defines whether connection method is hidden.</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="Hidden Agent" ref="HiddenAgent" type="selection">
+        <desc>Connection method is hidden in CConnDlg or not (used to divide MMS and non-MMS CMs).</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="Highlighted" ref="Highlighted" type="selection">
+        <desc>Connection method is highlighted or not.</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="Seamlessness" ref="Seamlessness" type="selection">
+        <desc>Defines whether an IAP can be roamed to.</desc>
+      <option name="Confirm First" value="ConfirmFirst" />
+      <option name="Show Progress" value="ShowProgress" />
+      </setting>
+    <setting name="User Name" ref="UserName" type="string">
+        <desc>User name</desc>
+      </setting>
+    <setting name="Prompt Password" ref="PromptPassword" type="selection">
+        <desc>Prompt password at connection time.</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="Password" ref="Password" type="string">
+        <desc>Password.</desc>
+      </setting>
+    <setting name="Password authentication type" ref="PasswordAuthenticationType" type="selection">
+        <desc>Password authentication method.</desc>
+      <option name="Normal" value="Normal" />
+      <option name="Secure" value="Secure" />
+      </setting>
+    <setting name="WAP Gateway IP" ref="WAPGatewayIP" type="string">
+        <desc>WAP gateway IP address.</desc>
+      </setting>
+    <setting name="Starting Page" ref="StartingPage" type="string">
+        <desc>Start page of the connection method.</desc>
+      </setting>
+    <setting name="WTLS Security" ref="WTLS_Security" type="selection">
+        <desc>Attempts a secure WTLS connection to the gateway.</desc>
+      <option name="On" value="On" />
+      <option name="Off" value="Off" />
+      </setting>
+    <setting name="Connection type" ref="WAP_ConnectionType" type="selection">
+        <desc>Indicates whether a connection-oriented or connectionless API should be used.</desc>
+      <option name="Continuous" value="Continuous" />
+      <option name="Temporary" value="Temporary" />
+      </setting>
+    <setting name="IPv4 Phone IP address" ref="PhoneIP" type="string">
+        <desc>IP address of the interface. 
+        Typically allocated automatically so this can be left empty.</desc>
+      </setting>
+    <setting name="IPv4 Primary Name Server" ref="PrimaryNameServer" type="string">
+        <desc>Address of the primary DNS server that resolves host names. 
+        Typically allocated automatically so this can be left empty.</desc>
+      </setting>
+    <setting name="IPv4 Secondary Name Server" ref="SecondaryNameServer" type="string">
+        <desc>Address of the secondary DNS server to connect if the primary DNS server is not available.
+        Typically allocated automatically so this can be left empty.</desc>
+      </setting>
+    <setting name="IPv6 Primary Name Server" ref="PrimaryIP6NameServer" type="string">
+        <desc>Address of the primary DNS server that resolves host names.
+        Typically allocated automatically so this can be left empty.</desc>
+      </setting>
+    <setting name="IPv6 Secondary Name Server" ref="SecondaryIP6NameServer" type="string">
+        <desc>Address of the secondary DNS server to connect if the primary DNS server is not available.
+        Typically allocated automatically so this can be left empty.</desc>
+      </setting>
+    <setting name="Proxy Server Address" ref="ProxyServerAddress" type="string">
+        <desc>Address of the HTTP/HTTPS proxy server.</desc>
+      </setting>
+    <setting name="Proxy Port Number" ref="ProxyPortNumber" type="string">
+        <desc>Port number of the HTTP/HTTPS proxy server.</desc>
+      </setting>
+    <setting name="Proxy protocol Name" ref="ProxyProtocolName" type="string">
+        <desc>Name of the protocol for which this proxy can be used. 
+        Typically http or https.</desc>
+      </setting>
+    <setting name="Default Tel Number (Mandatory)" ref="DefaultTelNumber" type="string">
+        <desc>Default telephone number.</desc>
+      </setting>
+    <setting name="Bearer Speed" ref="BearerSpeed" type="selection">
+        <desc>Bearer speed</desc>
+      <option name="Autodetect" value="Autodetect" />
+      <option name="9600" value="9600" />
+      <option name="14400" value="14400" />
+      <option name="19200" value="19200" />
+      <option name="28800" value="28800" />
+      <option name="38400" value="38400" />
+      <option name="43200" value="43200" />
+      <option name="56000" value="56000" />
+      </setting>
+    <setting name="Bearer Call Type Isdn" ref="BearerCallTypeIsdn" type="selection">
+        <desc>Bearer Call Type Isdn</desc>
+      <option name="Analogue" value="Analogue" />
+      <option name="Isdn v110" value="Isdn v110" />
+      <option name="Isdn v120" value="Isdn v120" />
+      </setting>
+    <setting name="Call back Enabled" ref="CallbackEnabled" type="selection">
+        <desc>Is callback enabled.</desc>
+      <option name="Yes" value="Yes" />
+      <option name="No" value="No" />
+      </setting>
+    <setting name="Call back type" ref="CallbackType" type="selection">
+        <desc>Callback type.</desc>
+      <option name="Server Number" value="Server Number" />
+      <option name="Other Number" value="Other Number" />
+      </setting>
+    <setting name="Call back number" ref="CallbackInfo" type="string">
+        <desc>Callback number.</desc>
+      </setting>
+    <setting name="Enable PPP Compression" ref="EnableSWCompression" type="selection">
+        <desc>Enable compression</desc>
+      <option name="Yes" value="Yes" />
+      <option name="No" value="No" />
+      </setting>
+    <setting name="Use Login Script" ref="UseLoginScript" type="selection">
+        <desc>Use login script</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="Login Script" ref="LoginScript" type="string">
+        <desc>Login script</desc>
+      </setting>
+    <setting name="Modem init string" ref="InitString" type="string">
+        <desc>Modem init string</desc>
+      </setting>
+    </setting>
+  </feature>
+<feature name="LAN Access Points" ref="LAN_APs">
+    <desc>LAN connection methods</desc>
+  <setting maxOccurs="99" minOccurs="0" name="LAN" ref="LAN_AP" type="sequence">
+      <setting name="Connection Name" ref="ConnectionName" type="string">
+        <desc>The CM name that is visible to the user.</desc>
+      </setting>
+    <setting name="Connection ID" ref="ConnectionId" type="int">
+        <desc>The CommsDat record id can be manually specified here. If left empty it is allocated automatically.
+      	Note: It needs to be verified carefully that the IDs are globally unique if allocated manually! 
+      	So a good idea is to either specify all the IDs manually or none at all.</desc>
+      </setting>
+    <setting name="Protected" ref="Protected" type="selection">
+        <desc>Defines whether connection method is protected (= cannot be edited by the user).</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="Hidden" ref="Hidden" type="selection">
+        <desc>Defines whether connection method is hidden.</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="Hidden Agent" ref="HiddenAgent" type="selection">
+        <desc>Connection method is hidden in CConnDlg or not (used to divide MMS and non-MMS CMs).</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="Highlighted" ref="Highlighted" type="selection">
+        <desc>Connection method is highlighted or not.</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="Seamlessness" ref="Seamlessness" type="selection">
+        <desc>Defines whether an IAP can be roamed to.</desc>
+      <option name="Confirm First" value="ConfirmFirst" />
+      <option name="Show Progress" value="ShowProgress" />
+      </setting>
+    <setting name="WAP Gateway IP" ref="WAPGatewayIP" type="string">
+        <desc>WAP gateway IP address.</desc>
+      </setting>
+    <setting name="Starting Page" ref="StartingPage" type="string">
+        <desc>Start page of the connection method.</desc>
+      </setting>
+    <setting name="WTLS Security" ref="WTLS_Security" type="selection">
+        <desc>Attempts a secure WTLS connection to the gateway.</desc>
+      <option name="On" value="On" />
+      <option name="Off" value="Off" />
+      </setting>
+    <setting name="Connection type" ref="WAP_ConnectionType" type="selection">
+        <desc>Indicates whether a connection-oriented or connectionless API should be used.</desc>
+      <option name="Continuous" value="Continuous" />
+      <option name="Temporary" value="Temporary" />
+      </setting>
+    <setting name="Proxy Server Address" ref="ProxyServerAddress" type="string">
+        <desc>Address of the HTTP/HTTPS proxy server.</desc>
+      </setting>
+    <setting name="Proxy Port Number" ref="ProxyPortNumber" type="string">
+        <desc>Port number of the HTTP/HTTPS proxy server.</desc>
+      </setting>
+    <setting name="Proxy protocol Name" ref="ProxyProtocolName" type="string">
+        <desc>Name of the protocol for which this proxy can be used. 
+        Typically http or https.</desc>
+      </setting>
+    <setting name="LAN If Networks" ref="LanIfNetworks" type="string">
+        <desc>LAN interface networks.</desc>
+      </setting>
+    <setting name="LAN IP Netmask" ref="LanIpNetmask" type="string">
+        <desc>LAN interface netmask.</desc>
+      </setting>
+    <setting name="LAN IP Gateway" ref="LanIpGateway" type="string">
+        <desc>LAN IP Gateway.</desc>
+      </setting>
+    <setting name="IPv4 Phone IP address" ref="PhoneIP" type="string">
+        <desc>IP address of the interface. 
+        Typically allocated automatically so this can be left empty.</desc>
+      </setting>
+    <setting name="IPv4 Primary Name Server" ref="PrimaryNameServer" type="string">
+        <desc>Address of the primary DNS server that resolves host names. 
+        Typically allocated automatically so this can be left empty.</desc>
+      </setting>
+    <setting name="IPv4 Secondary Name Server" ref="SecondaryNameServer" type="string">
+        <desc>Address of the secondary DNS server to connect if the primary DNS server is not available.
+        Typically allocated automatically so this can be left empty.</desc>
+      </setting>
+    <setting name="IPv6 Primary Name Server" ref="PrimaryIP6NameServer" type="string">
+        <desc>Address of the primary DNS server that resolves host names.
+        Typically allocated automatically so this can be left empty.</desc>
+      </setting>
+    <setting name="IPv6 Secondary Name Server" ref="SecondaryIP6NameServer" type="string">
+        <desc>Address of the secondary DNS server to connect if the primary DNS server is not available.
+        Typically allocated automatically so this can be left empty.</desc>
+      </setting>
+    </setting>
+  </feature>
+<feature name="VPN Access Points" ref="VPN_APs">
+    <desc>Virtual Private Network connection methods</desc>
+  <setting maxOccurs="99" minOccurs="0" name="VPN" ref="VPN_AP" type="sequence">
+      <setting name="Connection Name" ref="ConnectionName" type="string">
+        <desc>The CM name that is visible to the user.</desc>
+      </setting>
+    <setting name="Connection ID" ref="ConnectionId" type="int">
+        <desc>The CommsDat record id can be manually specified here. If left empty it is allocated automatically.
+      	Note: It needs to be verified carefully that the IDs are globally unique if allocated manually! 
+      	So a good idea is to either specify all the IDs manually or none at all.</desc>
+      </setting>
+    <setting name="Protected" ref="Protected" type="selection">
+        <desc>Defines whether connection method is protected (= cannot be edited by the user).</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="Hidden" ref="Hidden" type="selection">
+        <desc>Defines whether connection method is hidden.</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="Hidden Agent" ref="HiddenAgent" type="selection">
+        <desc>Connection method is hidden in CConnDlg or not (used to divide MMS and non-MMS CMs).</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="Highlighted" ref="Highlighted" type="selection">
+        <desc>Connection method is highlighted or not.</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="Seamlessness" ref="Seamlessness" type="selection">
+        <desc>Defines whether an IAP can be roamed to.</desc>
+      <option name="Confirm First" value="ConfirmFirst" />
+      <option name="Show Progress" value="ShowProgress" />
+      </setting>
+    <setting name="Proxy Server Address" ref="ProxyServerAddress" type="string">
+        <desc>Address of the HTTP/HTTPS proxy server.</desc>
+      </setting>
+    <setting name="Proxy Port Number" ref="ProxyPortNumber" type="string">
+        <desc>Port number of the HTTP/HTTPS proxy server.</desc>
+      </setting>
+    <setting name="Proxy protocol Name" ref="ProxyProtocolName" type="string">
+        <desc>Name of the protocol for which this proxy can be used. 
+        Typically http or https.</desc>
+      </setting>
+    <setting name="Underlying IAP Name" ref="IAP_Name" type="string">
+        <desc>The network connection provider IAP name.</desc>
+      </setting>
+    <setting name="Service Policy" ref="ServicePolicy" type="string">
+        <desc>Service policy.</desc>
+      </setting>
+    </setting>
+  </feature>
+<feature name="Destination Networks" ref="DNs">
+    <desc>Destination network (SNAP) definitions.</desc>
+  <setting maxOccurs="99" minOccurs="0" name="DN" ref="DN" type="sequence">
+      <setting name="Name" ref="Name" type="string">
+        <desc>The name that is visible to the user</desc>
+      </setting>
+    <setting name="Destination Network ID" ref="DNId" type="int">
+        <desc>The CommsDat record id can be manually specified here. If left empty it is allocated automatically.
+      	Note: It needs to be verified carefully that the IDs are globally unique if allocated manually! 
+      	So a good idea is to either specify all the IDs manually or none at all.</desc>
+      </setting>
+    <setting name="Metadata" ref="Metadata" type="selection">
+        <desc>Metadata that specifies a few default destination networks that applications can use</desc>
+      <option name="User Defined" value="UserDefined" />
+      <option name="Internet" value="Internet" />
+      <option name="Operator" value="Operator" />
+      <option name="MMS" value="MMS" />
+      <option name="Intranet" value="Intranet" />
+      </setting>
+    <setting name="Protection Level" ref="Protection" type="selection">
+        <desc>DN protection level. Destination contents mean the connection methods inside the destination and their priorities. </desc>
+      <option name="No protection" value="0" />
+      <option name="Destination and contents" value="1" />
+      <option name="Destination" value="2" />
+      </setting>
+    <setting name="Hidden" ref="Hidden" type="selection">
+        <desc>Is DN hidden or not.</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="Hidden Agent" ref="HiddenAgent" type="selection">
+        <desc>Is DN hidden in CConnDlg or not</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="Highlighted" ref="Highlighted" type="selection">
+        <desc>Is DN highlighted or not.</desc>
+      <option name="No" value="No" />
+      <option name="Yes" value="Yes" />
+      </setting>
+    <setting name="Icon" ref="Icon" type="selection">
+        <desc>Icon to be assigned to DN.</desc>
+      <option name="internet" value="0" />
+      <option name="wap" value="1" />
+      <option name="mms" value="2" />
+      <option name="intranet" value="3" />
+      <option name="operator" value="4" />
+      <option name="icon1" value="5" />
+      <option name="icon2" value="6" />
+      <option name="icon3" value="7" />
+      <option name="icon4" value="8" />
+      <option name="icon5" value="9" />
+      <option name="icon6" value="10" />
+      <option name="default" value="11" />
+      </setting>
+    <setting name="EmbeddedDN" ref="EmbeddedDN" type="string">
+        <desc>
+	    	Name of an embedded DN that is bound to DN.
+	    	</desc>
+      </setting>
+    <setting name="IAP Name 1" ref="IAP" type="string">
+        <desc>
+	    	Name of the Connection Method that is bound to DN.
+	    	</desc>
+      </setting>
+    <setting name="IAP Name 2" ref="IAP2" type="string">
+        <desc>
+	    	Name of the Connection Method that is bound to DN.
+	    	</desc>
+      </setting>
+    <setting name="IAP Name 3" ref="IAP3" type="string">
+        <desc>
+	    	Name of the Connection Method that is bound to DN.
+	    	</desc>
+      </setting>
+    <setting name="IAP Name 4" ref="IAP4" type="string">
+        <desc>
+	    	Name of the Connection Method that is bound to DN.
+	    	</desc>
+      </setting>
+    <setting name="IAP Name 5" ref="IAP5" type="string">
+        <desc>
+	    	Name of the Connection Method that is bound to DN.
+	    	</desc>
+      </setting>
+    <setting name="IAP Name 6" ref="IAP6" type="string">
+        <desc>
+	    	Name of the Connection Method that is bound to DN.
+	    	</desc>
+      </setting>
+    <setting name="IAP Name 7" ref="IAP7" type="string">
+        <desc>
+	    	Name of the Connection Method that is bound to DN.
+	    	</desc>
+      </setting>
+    <setting name="IAP Name 8" ref="IAP8" type="string">
+        <desc>
+	    	Name of the Connection Method that is bound to DN.
+	    	</desc>
+      </setting>
+    <setting name="IAP Name 9" ref="IAP9" type="string">
+        <desc>
+	    	Name of the Connection Method that is bound to DN.
+	    	</desc>
+      </setting>
+    <setting name="IAP Name 10" ref="IAP10" type="string">
+        <desc>
+	    	Name of the Connection Method that is bound to DN.
+	    	</desc>
+      </setting>
+    </setting>
+  </feature>
+<data>
+    <CSD_APs>
+      <CSD_AP template="true">
+        <Protected>No</Protected>
+      <Hidden>No</Hidden>
+      <HiddenAgent>No</HiddenAgent>
+      <Highlighted>No</Highlighted>
+      <Seamlessness>ConfirmFirst</Seamlessness>
+      <PasswordAuthenticationType>Normal</PasswordAuthenticationType>
+      <WTLS_Security>On</WTLS_Security>
+      <WAP_ConnectionType>Continuous</WAP_ConnectionType>
+      <BearerSpeed>Autodetect</BearerSpeed>
+      <BearerCallTypeIsdn>Analogue</BearerCallTypeIsdn>
+      <CallbackEnabled>Yes</CallbackEnabled>
+      <CallbackType>Server Number</CallbackType>
+      <EnableSWCompression>No</EnableSWCompression>
+      <UseLoginScript>No</UseLoginScript>
+      <ConnectionName />
+      <ConnectionId />
+      <UserName />
+      <PromptPassword />
+      <Password />
+      <WAPGatewayIP />
+      <StartingPage />
+      <PhoneIP />
+      <PrimaryNameServer />
+      <SecondaryNameServer />
+      <PrimaryIP6NameServer />
+      <SecondaryIP6NameServer />
+      <ProxyServerAddress />
+      <ProxyPortNumber />
+      <ProxyProtocolName />
+      <DefaultTelNumber />
+      <CallbackInfo />
+      <LoginScript />
+      <InitString />
+      </CSD_AP>
+    </CSD_APs>
+  <DNs>
+      <DN template="true">
+        <Metadata>User Defined</Metadata>
+      <Protection>0</Protection>
+      <Hidden>No</Hidden>
+      <HiddenAgent>No</HiddenAgent>
+      <Highlighted>No</Highlighted>
+      <Icon>11</Icon>
+      <Name />
+      <DNId />
+      <EmbeddedDN />
+      <IAP />
+      <IAP2 />
+      <IAP3 />
+      <IAP4 />
+      <IAP5 />
+      <IAP6 />
+      <IAP7 />
+      <IAP8 />
+      <IAP9 />
+      <IAP10 />
+      </DN>
+    <DN>
+        <Name>Internet</Name>
+      <DNId>1</DNId>
+      <Metadata>Internet</Metadata>
+      <Protection>2</Protection>
+      <Hidden>No</Hidden>
+      <HiddenAgent>No</HiddenAgent>
+      <Highlighted>Yes</Highlighted>
+      <Icon>0</Icon>
+      <EmbeddedDN />
+      <IAP />
+      <IAP2 />
+      <IAP3 />
+      <IAP4 />
+      <IAP5 />
+      <IAP6 />
+      <IAP7 />
+      <IAP8 />
+      <IAP9 />
+      <IAP10 />
+      </DN>
+    <DN>
+        <Name>MMS</Name>
+      <DNId>2</DNId>
+      <Metadata>MMS</Metadata>
+      <Protection>2</Protection>
+      <Hidden>No</Hidden>
+      <HiddenAgent>Yes</HiddenAgent>
+      <Highlighted>No</Highlighted>
+      <Icon>2</Icon>
+      <EmbeddedDN />
+      <IAP />
+      <IAP2 />
+      <IAP3 />
+      <IAP4 />
+      <IAP5 />
+      <IAP6 />
+      <IAP7 />
+      <IAP8 />
+      <IAP9 />
+      <IAP10 />
+      </DN>
+    <DN>
+        <Name>Operator</Name>
+      <DNId>3</DNId>
+      <Metadata>Operator</Metadata>
+      <Protection>2</Protection>
+      <Hidden>No</Hidden>
+      <HiddenAgent>No</HiddenAgent>
+      <Highlighted>No</Highlighted>
+      <Icon>4</Icon>
+      <EmbeddedDN />
+      <IAP />
+      <IAP2 />
+      <IAP3 />
+      <IAP4 />
+      <IAP5 />
+      <IAP6 />
+      <IAP7 />
+      <IAP8 />
+      <IAP9 />
+      <IAP10 />
+      </DN>
+    </DNs>
+  <Global>
+      <Attachmode>whenavailable</Attachmode>
+    <DefaultDnIcon>11</DefaultDnIcon>
+    <DefaultConnectionType>Ask once</DefaultConnectionType>
+    <DefaultConnectionName />
+    <DefaultAP />
+    <WlanUseDefSettings>1</WlanUseDefSettings>
+    <WlanBGScanInterval>0</WlanBGScanInterval>
+    <WlanTxPowerLevel>100</WlanTxPowerLevel>
+    <WlanRadioMeasurements>1</WlanRadioMeasurements>
+    <WlanPowerMode>1</WlanPowerMode>
+    <PriorityLan>0</PriorityLan>
+    <PriorityWlan>1</PriorityWlan>
+    <PriorityPan>2</PriorityPan>
+    <PriorityGprsOut>3</PriorityGprsOut>
+    <PriorityGprsIn>4</PriorityGprsIn>
+    <PriorityCdma2k>5</PriorityCdma2k>
+    <PriorityDialOut>6</PriorityDialOut>
+    <PriorityDialIn>7</PriorityDialIn>
+    <PriorityVpn>253</PriorityVpn>
+    <PriorityMip>254</PriorityMip>
+    <UIPriorityLan>9</UIPriorityLan>
+    <UIPriorityWlan>0</UIPriorityWlan>
+    <UIPriorityPan>8</UIPriorityPan>
+    <UIPriorityGprsOut>1</UIPriorityGprsOut>
+    <UIPriorityGprsIn>2</UIPriorityGprsIn>
+    <UIPriorityCdma2k>3</UIPriorityCdma2k>
+    <UIPriorityDialOut>4</UIPriorityDialOut>
+    <UIPriorityDialIn>5</UIPriorityDialIn>
+    <UIPriorityVpn>6</UIPriorityVpn>
+    <UIPriorityMip>7</UIPriorityMip>
+    <WlanLongRetry>4</WlanLongRetry>
+    <WlanShortRetry>7</WlanShortRetry>
+    <WlanRTS>2347</WlanRTS>
+    <CsdLastSocketActivityTimeout>300</CsdLastSocketActivityTimeout>
+    <CsdLastSessionClosedTimeout>1</CsdLastSessionClosedTimeout>
+    <CsdLastSocketClosedTimeout>300</CsdLastSocketClosedTimeout>
+    <WlanLastSocketActivityTimeout>-1</WlanLastSocketActivityTimeout>
+    <WlanLastSessionClosedTimeout>1</WlanLastSessionClosedTimeout>
+    <WlanLastSocketClosedTimeout>-1</WlanLastSocketClosedTimeout>
+    <GprsLastSocketActivityTimeout>-1</GprsLastSocketActivityTimeout>
+    <GprsLastSessionClosedTimeout>1</GprsLastSessionClosedTimeout>
+    <GprsLastSocketClosedTimeout>-1</GprsLastSocketClosedTimeout>
+    </Global>
+  <APs>
+      <AP template="true">
+        <Protected>No</Protected>
+      <Hidden>No</Hidden>
+      <HiddenAgent>No</HiddenAgent>
+      <Highlighted>No</Highlighted>
+      <Seamlessness>ConfirmFirst</Seamlessness>
+      <NetworkType>IPv4</NetworkType>
+      <PromptPassword>No</PromptPassword>
+      <PasswordAuthenticationType>Normal</PasswordAuthenticationType>
+      <WTLS_Security>On</WTLS_Security>
+      <WAP_ConnectionType>Continuous</WAP_ConnectionType>
+      <GprsUseEdge>Yes</GprsUseEdge>
+      <ConnectionName />
+      <ConnectionId />
+      <GPRS_AP_Name />
+      <UserName />
+      <Password />
+      <WAPGatewayIP />
+      <StartingPage />
+      <PhoneIP />
+      <PrimaryNameServer />
+      <SecondaryNameServer />
+      <PrimaryIP6NameServer />
+      <SecondaryIP6NameServer />
+      <ProxyServerAddress />
+      <ProxyPortNumber />
+      <ProxyProtocolName />
+      <IspType />
+      </AP>
+    <AP>
+        <Protected>No</Protected>
+      <Hidden>No</Hidden>
+      <HiddenAgent>No</HiddenAgent>
+      <Highlighted>No</Highlighted>
+      <Seamlessness>ConfirmFirst</Seamlessness>
+      <NetworkType>IPv4</NetworkType>
+      <PromptPassword>No</PromptPassword>
+      <PasswordAuthenticationType>Normal</PasswordAuthenticationType>
+      <WTLS_Security>On</WTLS_Security>
+      <WAP_ConnectionType>Continuous</WAP_ConnectionType>
+      <GprsUseEdge>Yes</GprsUseEdge>
+      <ConnectionName />
+      <ConnectionId />
+      <GPRS_AP_Name />
+      <UserName />
+      <Password />
+      <WAPGatewayIP />
+      <StartingPage />
+      <PhoneIP />
+      <PrimaryNameServer />
+      <SecondaryNameServer />
+      <PrimaryIP6NameServer />
+      <SecondaryIP6NameServer />
+      <ProxyServerAddress />
+      <ProxyPortNumber />
+      <ProxyProtocolName />
+      <IspType />
+      </AP>
+    </APs>
+  <HSCSD_APs>
+      <HSCSD_AP template="true">
+        <Protected>No</Protected>
+      <Hidden>No</Hidden>
+      <HiddenAgent>No</HiddenAgent>
+      <Highlighted>No</Highlighted>
+      <Seamlessness>ConfirmFirst</Seamlessness>
+      <PromptPassword>No</PromptPassword>
+      <PasswordAuthenticationType>Normal</PasswordAuthenticationType>
+      <WTLS_Security>On</WTLS_Security>
+      <WAP_ConnectionType>Continuous</WAP_ConnectionType>
+      <BearerSpeed>Autodetect</BearerSpeed>
+      <BearerCallTypeIsdn>Analogue</BearerCallTypeIsdn>
+      <CallbackEnabled>Yes</CallbackEnabled>
+      <CallbackType>Server Number</CallbackType>
+      <EnableSWCompression>No</EnableSWCompression>
+      <UseLoginScript>No</UseLoginScript>
+      <ConnectionName />
+      <ConnectionId />
+      <UserName />
+      <Password />
+      <WAPGatewayIP />
+      <StartingPage />
+      <PhoneIP />
+      <PrimaryNameServer />
+      <SecondaryNameServer />
+      <PrimaryIP6NameServer />
+      <SecondaryIP6NameServer />
+      <ProxyServerAddress />
+      <ProxyPortNumber />
+      <ProxyProtocolName />
+      <DefaultTelNumber />
+      <CallbackInfo />
+      <LoginScript />
+      <InitString />
+      </HSCSD_AP>
+    </HSCSD_APs>
+  <LAN_APs>
+      <LAN_AP template="true">
+        <Protected>No</Protected>
+      <Hidden>No</Hidden>
+      <HiddenAgent>No</HiddenAgent>
+      <Highlighted>No</Highlighted>
+      <Seamlessness>Confirm first</Seamlessness>
+      <WTLS_Security>On</WTLS_Security>
+      <WAP_ConnectionType>Continuous</WAP_ConnectionType>
+      <ConnectionName />
+      <ConnectionId />
+      <WAPGatewayIP />
+      <StartingPage />
+      <ProxyServerAddress />
+      <ProxyPortNumber />
+      <ProxyProtocolName />
+      <LanIfNetworks />
+      <LanIpNetmask />
+      <LanIpGateway />
+      <PhoneIP />
+      <PrimaryNameServer />
+      <SecondaryNameServer />
+      <PrimaryIP6NameServer />
+      <SecondaryIP6NameServer />
+      </LAN_AP>
+    </LAN_APs>
+  <WLAN_APs>
+      <WLAN_AP template="true">
+        <Protected>No</Protected>
+      <Hidden>No</Hidden>
+      <HiddenAgent>No</HiddenAgent>
+      <Highlighted>No</Highlighted>
+      <Seamlessness>ConfirmFirst</Seamlessness>
+      <NetworkMode>Infrastructure</NetworkMode>
+      <SecurityMode>Open</SecurityMode>
+      <WLANScanSSID>No</WLANScanSSID>
+      <WEPKeyInUse>key1</WEPKeyInUse>
+      <WEPAuthType>Shared</WEPAuthType>
+      <WEPKey1Length>64</WEPKey1Length>
+      <WEPKey1Format>ASCII</WEPKey1Format>
+      <WEPKey2Length>64</WEPKey2Length>
+      <WEPKey2Format>ASCII</WEPKey2Format>
+      <WEPKey3Length>64</WEPKey3Length>
+      <WEPKey3Format>ASCII</WEPKey3Format>
+      <WEPKey4Length>64</WEPKey4Length>
+      <WEPKey4Format>ASCII</WEPKey4Format>
+      <WPAUseOfPresharedKey>No</WPAUseOfPresharedKey>
+      <WPAKeyLength>0</WPAKeyLength>
+      <ConnectionName />
+      <ConnectionId />
+      <NetworkName />
+      <StartingPage />
+      <PrimaryNameServer />
+      <SecondaryNameServer />
+      <PrimaryIP6NameServer />
+      <SecondaryIP6NameServer />
+      <WlanIpGatewayAddress />
+      <WlanIpNetMask />
+      <ProxyServerAddress />
+      <ProxyPortNumber />
+      <ProxyProtocolName />
+      <WlanChannelId />
+      <PhoneIP />
+      <WEPKey1Data />
+      <WEPKey2Data />
+      <WEPKey3Data />
+      <WEPKey4Data />
+      <WPAPresharedKey />
+      <WPAListOfEAPs />
+      <EapGtcUsername />
+      <EapGtcSessionValidityTime />
+      <EapGtcEncapsulation />
+      <EapTlsUsername />
+      <EapTlsRealm />
+      <EapTlsVerifyServerRealm />
+      <EapTlsRequireClientAuth />
+      <EapTlsSessionValidityTime />
+      <EapTlsCipherSuites />
+      <EapTlsUserCertSubjectKeyId />
+      <EapTlsUserCertIssuerName />
+      <EapTlsUserCertSerialNumber />
+      <EapTlsCaCertSubjectKeyId />
+      <EapTlsCaCertIssuerName />
+      <EapTlsCaCertSerialNumber />
+      <EapTlsEncapsulation />
+      <EapLeapUsername />
+      <EapLeapPassword />
+      <EapLeapSessionValidityTime />
+      <EapSimUsername />
+      <EapSimRealm />
+      <EapSimUsePseudonyms />
+      <EapSimSessionValidityTime />
+      <EapSimEncapsulation />
+      <EapTtlsUsername />
+      <EapTtlsRealm />
+      <EapTtlsVerifyServerRealm />
+      <EapTtlsRequireClientAuth />
+      <EapTtlsSessionValidityTime />
+      <EapTtlsCipherSuites />
+      <EapTtlsEncapsulatedTypes />
+      <EapTtlsUserCertSubjectKeyId />
+      <EapTtlsUserCertIssuerName />
+      <EapTtlsUserCertSerialNumber />
+      <EapTtlsCaCertSubjectKeyId />
+      <EapTtlsCaCertIssuerName />
+      <EapTtlsCaCertSerialNumber />
+      <EapAkaUsername />
+      <EapAkaRealm />
+      <EapAkaUsePseudonyms />
+      <EapAkaSessionValidityTime />
+      <EapAkaEncapsulation />
+      <EapPeapUsername />
+      <EapPeapRealm />
+      <EapPeapVerifyServerRealm />
+      <EapPeapRequireClientAuth />
+      <EapPeapSessionValidityTime />
+      <EapPeapCipherSuites />
+      <EapPeapV0Allowed />
+      <EapPeapV1Allowed />
+      <EapPeapV2Allowed />
+      <EapPeapEncapsulatedTypes />
+      <EapPeapUserCertSubjectKeyId />
+      <EapPeapUserCertIssuerName />
+      <EapPeapUserCertSerialNumber />
+      <EapPeapCaCertSubjectKeyId />
+      <EapPeapCaCertIssuerName />
+      <EapPeapCaCertSerialNumber />
+      <EapMschapv2Username />
+      <EapMschapv2Password />
+      <EapMschapv2SessionValidityTime />
+      <EapMschapv2Encapsulation />
+      <EapFastUsername />
+      <EapFastRealm />
+      <EapFastVerifyServerRealm />
+      <EapFastRequireClientAuth />
+      <EapFastSessionValidityTime />
+      <EapFastCipherSuites />
+      <EapFastEncapsulatedTypes />
+      <EapFastAuthProvModeAllowed />
+      <EapFastUnauthProvModeAllowed />
+      <EapFastWarnADHPNoPAC />
+      <EapFastWarnADHPNoMatchingPAC />
+      <EapFastWarnNotDefaultServer />
+      <EapFastUserCertSubjectKeyId />
+      <EapFastUserCertIssuerName />
+      <EapFastUserCertSerialNumber />
+      <EapFastCaCertSubjectKeyId />
+      <EapFastCaCertIssuerName />
+      <EapFastCaCertSerialNumber />
+      <Mschapv2Username />
+      <Mschapv2Password />
+      <Mschapv2SessionValidityTime />
+      <Mschapv2Encapsulation />
+      </WLAN_AP>
+    </WLAN_APs>
+  <VPN_APs>
+      <VPN_AP template="true">
+        <Protected>No</Protected>
+      <Hidden>No</Hidden>
+      <HiddenAgent>No</HiddenAgent>
+      <Highlighted>No</Highlighted>
+      <Seamlessness>ConfirmFirst</Seamlessness>
+      <ConnectionName />
+      <ConnectionId />
+      <ProxyServerAddress />
+      <ProxyPortNumber />
+      <ProxyProtocolName />
+      <IAP_Name />
+      <ServicePolicy />
+      </VPN_AP>
+    <VPN_AP>
+        <Protected>No</Protected>
+      <Hidden>No</Hidden>
+      <HiddenAgent>No</HiddenAgent>
+      <Highlighted>No</Highlighted>
+      <Seamlessness>ConfirmFirst</Seamlessness>
+      <ConnectionName />
+      <ConnectionId />
+      <ProxyServerAddress />
+      <ProxyPortNumber />
+      <ProxyProtocolName />
+      <IAP_Name />
+      <ServicePolicy />
+      </VPN_AP>
+    </VPN_APs>
+  <KCRUidCommsDatCreator>
+      <KCommsDatCreatorStartupStatus>0</KCommsDatCreatorStartupStatus>
+    </KCRUidCommsDatCreator>
+  </data>
+<rfs>
+    <KCRUidCommsDatCreator>
+      <KCommsDatCreatorStartupStatus>false</KCommsDatCreatorStartupStatus>
+    <KCommsDatCreatorInputFileName>false</KCommsDatCreatorInputFileName>
+    </KCRUidCommsDatCreator>
+  </rfs>
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/ruleproject/rules/confml/comparison_operators.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,62 @@
+<configuration name="Arithmetic operation test" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
+  <feature name="Test settings for comparison operators" ref="CompOperTest">
+    <setting name="Value zero" ref="Zero" type="int" />
+    <setting name="Value one" ref="One" type="int" />
+    <setting name="Value two" ref="Two" type="int" />
+    
+    <setting name="Literals result" ref="LiteralsResult1" type="boolean" />
+    <setting name="Literals result" ref="LiteralsResult2" type="boolean" />
+    <setting name="Literals result" ref="LiteralsResult3" type="boolean" />
+    <setting name="Literals result" ref="LiteralsResult4" type="boolean" />
+    <setting name="Literals result" ref="LiteralsResult5" type="boolean" />
+    <setting name="Literals result" ref="LiteralsResult6" type="boolean" />
+    <setting name="Literals result" ref="LiteralsResult7" type="boolean" />
+    <setting name="Literals result" ref="LiteralsResult8" type="boolean" />
+    <setting name="Literals result" ref="LiteralsResult9" type="boolean" />
+    <setting name="Literals result" ref="LiteralsResult10" type="boolean" />
+    
+    <setting name="Refs result" ref="RefsResult1" type="boolean" />
+    <setting name="Refs result" ref="RefsResult2" type="boolean" />
+    <setting name="Refs result" ref="RefsResult3" type="boolean" />
+    <setting name="Refs result" ref="RefsResult4" type="boolean" />
+    <setting name="Refs result" ref="RefsResult5" type="boolean" />
+    <setting name="Refs result" ref="RefsResult6" type="boolean" />
+    <setting name="Refs result" ref="RefsResult7" type="boolean" />
+    <setting name="Refs result" ref="RefsResult8" type="boolean" />
+    <setting name="Refs result" ref="RefsResult9" type="boolean" />
+    <setting name="Refs result" ref="RefsResult10" type="boolean" />
+
+
+  </feature>
+  
+  <data>
+    <CompOperTest>
+      <Zero>0</Zero>
+      <One>1</One>
+      <Two>2</Two>
+      
+      <LiteralsResult1>0</LiteralsResult1>
+      <LiteralsResult2>0</LiteralsResult2>
+      <LiteralsResult3>0</LiteralsResult3>
+      <LiteralsResult4>0</LiteralsResult4>
+      <LiteralsResult5>0</LiteralsResult5>
+      <LiteralsResult6>0</LiteralsResult6>
+      <LiteralsResult7>0</LiteralsResult7>
+      <LiteralsResult8>0</LiteralsResult8>
+      <LiteralsResult9>0</LiteralsResult9>
+      <LiteralsResult10>0</LiteralsResult10>
+      
+      <RefsResult1>0</RefsResult1>
+      <RefsResult2>0</RefsResult2>
+      <RefsResult3>0</RefsResult3>
+      <RefsResult4>0</RefsResult4>
+      <RefsResult5>0</RefsResult5>
+      <RefsResult6>0</RefsResult6>
+      <RefsResult7>0</RefsResult7>
+      <RefsResult8>0</RefsResult8>
+      <RefsResult9>0</RefsResult9>
+      <RefsResult10>0</RefsResult10>
+      
+    </CompOperTest>
+  </data>
+</configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/ruleproject/rules/confml/eval.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,83 @@
+<configuration name="Eval test data" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
+  <feature ref="EvalTest" name="Test settings for eval blocks">
+  
+    <setting ref="StringLenResult" name="String length result" type="int" />
+    <setting ref="EvalConstantResult" name="Result set from an eval global constant" type="int" />
+	<setting ref="EvalFileImport" name="Result set from an imported pyfile" type="int" />
+    <setting ref="UnchangedValue" name="Value that should remain unchanged" type="int" />
+    <setting ref="UnicodeResult1" name="Result set with an eval block using characters outside the ASCII range" type="string" />
+    <setting ref="UnicodeResult2" name="Result set with an eval block using characters outside the ASCII range" type="string" />
+    
+    <setting ref="Bitmask" name="Bitmask int setting" type="int" />
+    
+    <setting ref="Bit0Result" name="Bitmask bit 0 result" type="boolean"/>
+    <setting ref="Bit1Result" name="Bitmask bit 1 result" type="boolean"/>
+    <setting ref="Bit2Result" name="Bitmask bit 2 result" type="boolean"/>
+    <setting ref="Bit3Result" name="Bitmask bit 3 result" type="boolean"/>
+    
+    <setting ref="EvalBuiltinResult" name="String value set from eval using the built-in configuration member" type="string"/>
+    
+    <setting ref="StrippedSequence" name="Stripped sequence" type="sequence">
+      <setting ref="StringSubSetting" name="String sub-setting" type="string"/>
+      <setting ref="IntSubSetting" name="Int sub-setting" type="int"/>
+    </setting>
+    
+    <setting ref="FullSequence" name="Full sequence" type="sequence">
+      <setting ref="StringSubSetting" name="String sub-setting" type="string"/>
+      <setting ref="IntSubSetting" name="Int sub-setting" type="int"/>
+      <setting ref="RealSubSetting" name="Real sub-setting" type="real"/>
+      <setting ref="BooleanSubSetting" name="Boolean sub-setting" type="boolean"/>
+    </setting>
+  </feature>
+  
+  <data>
+    <EvalTest>
+      <StringLenResult>0</StringLenResult>
+      <EvalConstantResult>0</EvalConstantResult>
+      <EvalFileImport></EvalFileImport>
+      <UnchangedValue>0</UnchangedValue>
+      <UnicodeResult1></UnicodeResult1>
+      <UnicodeResult2></UnicodeResult2>
+      
+      <Bitmask>10</Bitmask>
+      <Bit0Result>false</Bit0Result>
+      <Bit1Result>false</Bit1Result>
+      <Bit2Result>false</Bit2Result>
+      <Bit3Result>false</Bit3Result>
+      
+      <EvalBuiltinResult></EvalBuiltinResult>
+      
+      <StrippedSequence template="true">
+        <StringSubSetting>Default</StringSubSetting>
+        <IntSubSetting>0</IntSubSetting>
+      </StrippedSequence>
+      <StrippedSequence>
+        <StringSubSetting>Stripped 1</StringSubSetting>
+        <IntSubSetting>1</IntSubSetting>
+      </StrippedSequence>
+      <StrippedSequence>
+        <StringSubSetting>Stripped 2</StringSubSetting>
+        <IntSubSetting>2</IntSubSetting>
+      </StrippedSequence>
+      
+      <FullSequence template="true">
+        <StringSubSetting>Default</StringSubSetting>
+        <IntSubSetting>0</IntSubSetting>
+        <RealSubSetting>0.5</RealSubSetting>
+        <IntSubSetting>false</IntSubSetting>
+      </FullSequence>
+      <FullSequence>
+        <StringSubSetting>Full 1</StringSubSetting>
+        <IntSubSetting>10</IntSubSetting>
+        <RealSubSetting>1.5</RealSubSetting>
+        <BooleanSubSetting>true</BooleanSubSetting>
+      </FullSequence>
+      <FullSequence>
+        <StringSubSetting>Full 2</StringSubSetting>
+        <IntSubSetting>20</IntSubSetting>
+        <RealSubSetting>2.5</RealSubSetting>
+        <BooleanSubSetting>false</BooleanSubSetting>
+      </FullSequence>
+    </EvalTest>
+  </data>
+</configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/ruleproject/rules/confml/filename_testdata.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,43 @@
+<configuration name="Filenamejoin test" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
+  <feature name="Filenamejoin rule test" ref="FilenamejoinTest">
+  
+    <setting name="Folder setting 1" ref="Folder1" type="folder">
+      <localPath/>
+    </setting>
+    <setting name="File setting 1" ref="File1" type="file">
+      <localPath/>
+    </setting>
+    <setting name="String setting 1" ref="String1" type="string"/>
+    
+    <setting name="Result 1" ref="Result1" type="string"/>
+    <setting name="Result 2" ref="Result2" type="string"/>
+    <setting name="Result 3" ref="Result3" type="string"/>
+    <setting name="Result 4" ref="Result4" type="string"/>
+    <setting name="Result 5" ref="Result5" type="string"/>
+    <setting name="Result 6" ref="Result6" type="string"/>
+    <setting name="Result 7" ref="Result7" type="string"/>
+    <setting name="Result 8" ref="Result8" type="string"/>
+    <setting name="Result 9" ref="Result9" type="string"/>
+	<setting name="Result 10" ref="Result10" type="string"/>
+	<setting name="Result 11" ref="Result11" type="string"/>
+  </feature>
+  <data>
+    <FilenamejoinTest>
+      <Folder1><localPath>some/folder1</localPath></Folder1>
+      <File1><localPath>sounds/file1.txt</localPath></File1>
+      <String1>Z:\\data\\sound.mp3</String1>
+      
+      <Result1>x</Result1>
+      <Result2>x</Result2>
+      <Result3>x</Result3>
+      <Result4>x</Result4>
+      <Result5>x</Result5>
+      <Result6>x</Result6>
+      <Result7>x</Result7>
+      <Result8>x</Result8>
+      <Result9>x</Result9>
+	  <Result10>x</Result10>
+      <Result11>x</Result11>
+    </FilenamejoinTest>
+  </data>
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/ruleproject/rules/confml/testdata.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration name="imaker interface" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
+  <feature name="iMaker Image creation" ref="imaker">
+    <setting name="IMAGE_TARGET" ref="imagetarget" type="selection">
+      <option name="core" value="0" />
+    <option name="rofs2" value="1" />
+    <option name="rofs3" value="2" />
+    <option name="rofs4" value="3" />
+    <option name="uda" value="4" />
+    <option name="rofs3_uda" value="4" />
+    </setting>
+  <setting name="iMaker api makefile" ref="makefilename" type="string" />
+  </feature>
+<feature name="iMaker API" ref="imakerapi">
+    <setting name="IMAGE_TYPE" ref="imagetype" type="selection">
+      <option name="rnd" value="0" />
+    <option name="subcon" value="1" />
+    <option name="prd" value="2" />
+    </setting>
+  <setting name="ROFS3_VERSION" ref="rofs3version" type="string" />
+  <setting name="PRODUCT_NAME" ref="productname" type="string" />
+  <setting name="OUTPUT_LOCATION" ref="outputLocation" type="string" />
+  <setting name="OUTPUT_LOCATIONY" ref="outputLocationY" type="string" />
+  </feature>
+<feature name="ar operations" ref="operations">
+    <setting name="MINUS" ref="minus" type="int" />
+  <setting name="MINUS1" ref="minus1" type="int" />
+  <setting name="MINUS2" ref="minus2" type="int" />
+  <setting name="MINUS3" ref="minus3" type="int" />
+  <setting name="MINUS4" ref="minus4" type="int" />
+  <setting name="MINUS5" ref="minus5" type="int" />
+  <setting name="MINUS6" ref="minus6" type="int" />
+  <setting name="MINUS7" ref="minus7" type="int" />
+  <setting name="MINUS8" ref="minus8" type="int" />
+  </feature>
+<feature name="String concatenation test" ref="StringConcatenationTest">
+    <setting name="Value 1" ref="Value1" type="string" />
+  <setting name="Value 2" ref="Value2" type="string" />
+  <setting name="Result 1" ref="Result1" type="string" />
+  <setting name="Result 2" ref="Result2" type="string" />
+  <setting name="Result 3" ref="Result3" type="string" />
+  <setting name="Result 4" ref="Result4" type="string" />
+  <setting name="Result 5" ref="Result5" type="string" />
+  <setting name="Result 6" ref="Result6" type="string" />
+  </feature>
+<feature name="Unicode test feature" ref="ударениÑ">
+    <setting name="Unicode test setting" ref="ελληνικά" type="string" />
+  </feature>
+<data>
+    <imaker>
+      <imagetarget>2</imagetarget>
+    <makefilename>image_conf_imakerapi.mk</makefilename>
+    </imaker>
+  <imakerapi>
+      <imagetype>0</imagetype>
+    <rofs3version>V .50.2009.04.0113 RND</rofs3version>
+    <productname>myProduct</productname>
+    <outputLocation>myProduct</outputLocation>
+    <outputLocationY />
+    </imakerapi>
+  <operations>
+      <minus>5</minus>
+    <minus1>25</minus1>
+    <minus2>7</minus2>
+    <minus3>5</minus3>
+    <minus4>10</minus4>
+    <minus5>2</minus5>
+    <minus6>5</minus6>
+    <minus7>10</minus7>
+    <minus8>8</minus8>
+    </operations>
+  <StringConcatenationTest>
+      <Value1>String 1</Value1>
+    <Value2>String 2</Value2>
+    <Result1>x</Result1>
+    <Result2>x</Result2>
+    <Result3>x</Result3>
+    <Result4>x</Result4>
+    <Result5>x</Result5>
+    <Result6>x</Result6>
+    </StringConcatenationTest>
+    
+    <ударениÑ>
+      <ελληνικά>カタカナ</ελληνικά>
+    </ударениÑ>
+  </data>
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/ruleproject/rules/implml/arithmetic.ruleml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ruleml xmlns="http://www.s60.com/xml/ruleml/1">
+  <!-- Value1 = 5, Value2 = 20 -->
+  <rule>True configures Arithmetic.AdditionResult1 = 2 + 6</rule>
+  <rule>True configures Arithmetic.AdditionResult2 = Arithmetic.Value1 + 6</rule>
+  <rule>True configures Arithmetic.AdditionResult3 = 2 + Arithmetic.Value2</rule>
+  <rule>True configures Arithmetic.AdditionResult4 = Arithmetic.Value1 + Arithmetic.Value2</rule>
+  
+  <rule>True configures Arithmetic.SubtractionResult1 = 2 - 6</rule>
+  <rule>True configures Arithmetic.SubtractionResult2 = Arithmetic.Value1 - 6</rule>
+  <rule>True configures Arithmetic.SubtractionResult3 = 2 - Arithmetic.Value2</rule>
+  <rule>True configures Arithmetic.SubtractionResult4 = Arithmetic.Value1 - Arithmetic.Value2</rule>
+  
+  <rule>True configures Arithmetic.MultiplicationResult1 = 2 * 6</rule>
+  <rule>True configures Arithmetic.MultiplicationResult2 = Arithmetic.Value1 * 6</rule>
+  <rule>True configures Arithmetic.MultiplicationResult3 = 2 * Arithmetic.Value2</rule>
+  <rule>True configures Arithmetic.MultiplicationResult4 = Arithmetic.Value1 * Arithmetic.Value2</rule>
+  
+  <rule>True configures Arithmetic.DivisionResult1 = 6 / 2</rule>
+  <rule>True configures Arithmetic.DivisionResult2 = Arithmetic.Value2 / 4</rule>
+  <rule>True configures Arithmetic.DivisionResult3 = 10 / Arithmetic.Value1</rule>
+  <rule>True configures Arithmetic.DivisionResult4 = Arithmetic.Value2 / Arithmetic.Value1</rule>
+  
+  <rule>True configures Arithmetic.MixedResult1 = (6 / 2 + 3 * 9) - 7</rule> 
+  <rule>True configures Arithmetic.MixedResult2 = (6 / 2 + Arithmetic.Value1 * 9) - 7</rule> 
+  <rule>True configures Arithmetic.MixedResult3 = (Arithmetic.Value2 / 2 + Arithmetic.Value1 * 9) - 7</rule> 
+  <rule>True configures Arithmetic.MixedResult4 = (Arithmetic.Value2 / Arithmetic.Value1 + Arithmetic.Value1 * Arithmetic.Value1) - Arithmetic.Value2</rule> 
+  <rule>True configures Arithmetic.MixedResult5 = 4 + 6 / 2 - 3 * 9 + 10 / 5 - 8</rule>
+  
+  <rule>True configures Arithmetic.RealResult1 = 5.0 / 2.0</rule>
+  <rule>True configures Arithmetic.RealResult2 = Arithmetic.RealValue1 / 2</rule>
+  <rule>True configures Arithmetic.RealResult3 = 0.25 * Arithmetic.RealValue2</rule>
+  <rule>True configures Arithmetic.RealResult4 = Arithmetic.RealValue1 / 2.0 * Arithmetic.RealValue2</rule>
+  
+  <rule>True configures Arithmetic.RealCalcIntoIntResult = 0.25 * Arithmetic.RealValue1</rule>
+  <rule>True configures Arithmetic.IntCalcIntoRealResult = 3 * Arithmetic.Value1</rule>
+</ruleml>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/ruleproject/rules/implml/commsdat.ruleml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ruleml xmlns="http://www.s60.com/xml/ruleml/1">
+  <rule>(APs.AP != []) or (VPN_APs.VPN_AP != []) configures KCRUidCommsDatCreator.KCommsDatCreatorInputFileName = 'test.xml'</rule>
+</ruleml>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/ruleproject/rules/implml/comparison_operators.ruleml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ruleml xmlns="http://www.s60.com/xml/ruleml/1">
+  <rule>0 == 0 configures CompOperTest.LiteralsResult1 = true</rule>
+  <rule>0 != 1 configures CompOperTest.LiteralsResult2 = true</rule>
+  <rule>1 &lt; 2 configures CompOperTest.LiteralsResult3 = true</rule>
+  <rule>2 > 1 configures CompOperTest.LiteralsResult4 = true</rule>
+  <rule>1 &lt;= 1 configures CompOperTest.LiteralsResult5 = true</rule>
+  <rule>1 &lt;= 2 configures CompOperTest.LiteralsResult6 = true</rule>
+  <rule>1 >= 1 configures CompOperTest.LiteralsResult7 = true</rule>
+  <rule>2 >= 1 configures CompOperTest.LiteralsResult8 = true</rule>
+
+  <rule>CompOperTest.Zero == CompOperTest.Zero configures CompOperTest.RefsResult1 = true</rule>
+  <rule>CompOperTest.Zero != CompOperTest.One configures CompOperTest.RefsResult2 = true</rule>
+  <rule>CompOperTest.One &lt; CompOperTest.Two configures CompOperTest.RefsResult3 = true</rule>
+  <rule>CompOperTest.Two > CompOperTest.One configures CompOperTest.RefsResult4 = true</rule>
+  <rule>CompOperTest.One &lt;= CompOperTest.One configures CompOperTest.RefsResult5 = true</rule>
+  <rule>CompOperTest.One &lt;= CompOperTest.Two configures CompOperTest.RefsResult6 = true</rule>
+  <rule>CompOperTest.One >= CompOperTest.One configures CompOperTest.RefsResult7 = true</rule>
+  <rule>CompOperTest.Two >= CompOperTest.One configures CompOperTest.RefsResult8 = true</rule>
+</ruleml>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/ruleproject/rules/implml/container_with_rules.ruleml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<container xmlns="http://www.symbianfoundation.org/xml/implml/1">
+    <container>
+        <phase name="pre"/>
+        <rules:ruleml xmlns:rules="http://www.s60.com/xml/ruleml/1">
+          <rules:rule>imaker.imagetarget configures imakerapi.outputLocation = imaker.imagetarget</rules:rule>
+          <rules:rule>True configures StringConcatenationTest.Result1 = "Test " + "test"</rules:rule>
+          <rules:rule>True configures StringConcatenationTest.Result2 = StringConcatenationTest.Value1 + " Literal 2"</rules:rule>
+        </rules:ruleml>
+    </container>
+    <container>
+        <phase name="normal"/>
+        <rules:ruleml xmlns:rules="http://www.s60.com/xml/ruleml/1">
+          <rules:rule>True configures StringConcatenationTest.Result3 = "Literal 1 " + StringConcatenationTest.Value2</rules:rule>
+          <rules:rule>True configures StringConcatenationTest.Result4 = StringConcatenationTest.Value1 + StringConcatenationTest.Value2</rules:rule>
+          <rules:rule>True configures StringConcatenationTest.Result5 = StringConcatenationTest.Value1 + " &amp; " + StringConcatenationTest.Value2</rules:rule>
+          <rules:rule>True configures StringConcatenationTest.Result6 = StringConcatenationTest.Value1 + u" € カタカナ"</rules:rule>      
+        </rules:ruleml>
+    </container>
+</container>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/ruleproject/rules/implml/eval.ruleml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ruleml xmlns="http://www.s60.com/xml/ruleml/2">
+  <rule>True configures EvalTest.StringLenResult = {% len("faklskjh") %}</rule>
+  <rule>True configures EvalTest.EvalConstantResult = {% SOME_VALUE %}</rule>
+  <rule>True configures EvalTest.EvalFileImport = {% do_something(SOME_VALUE) %}</rule>
+  
+  <rule>{% ${EvalTest.Bitmask} &amp; 0x1 %} configures EvalTest.Bit0Result = True</rule>
+  <rule>{% ${EvalTest.Bitmask} &amp; 0x2 %} configures EvalTest.Bit1Result = True</rule>
+  <rule>True configures EvalTest.Bit2Result = {% 
+    bool(${EvalTest.Bitmask} &amp; 0x4) 
+    %}
+    </rule>
+  
+  <rule>True configures EvalTest.Bit3Result = {% bool(${EvalTest.Bitmask} &amp; 0x8) %}</rule>
+  
+  <rule>
+    True configures EvalTest.FullSequence = {% append_stripped_seq_to_full_seq(
+        @{EvalTest.StrippedSequence},
+        @{EvalTest.FullSequence})
+    %}
+  </rule>
+  
+  <!-- The eval block here should not be executed -->
+  <rule>False configures {% @{EvalTest.UnchangedValue}.set_value(54321) %}</rule>
+  
+  <rule>True configures EvalTest.UnicodeResult1 = {% u'100€' %}</rule>
+  <rule>True configures EvalTest.UnicodeResult2 = {% @{ударениÑ.ελληνικά}.get_value() %}</rule>
+  
+  <rule>True configures EvalTest.EvalBuiltinResult = {% ruleml.configuration.get_name() %}</rule>
+  
+  <eval_globals>SOME_VALUE = 12345</eval_globals>
+  
+<eval_globals>
+def append_stripped_seq_to_full_seq(stripped_seq, full_seq):
+    stripped_values = stripped_seq.get_value()
+    full_values = full_seq.get_value()
+    for sv in stripped_values:
+        full_values.append([sv[0], sv[1], '0.1', 'false'])
+    return full_values
+</eval_globals>
+<eval_globals file="scripts/test_eval.py"/>
+</ruleml>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/ruleproject/rules/implml/filename_rules.ruleml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ruleml xmlns="http://www.s60.com/xml/ruleml/1">
+  <rule>True configures FilenamejoinTest.Result1 = FilenamejoinTest.String1 filenamejoin FilenamejoinTest.File1.localPath</rule>
+  <rule>True configures FilenamejoinTest.Result2 = "some/content/dir/somefile.csv" filenamejoin FilenamejoinTest.File1.localPath</rule>
+  <rule>True configures FilenamejoinTest.Result3 = "some/content/dir/" filenamejoin FilenamejoinTest.File1.localPath</rule>
+  <rule>True configures FilenamejoinTest.Result4 = "some\\content\\dir\\somefile.csv" filenamejoin FilenamejoinTest.File1.localPath</rule>
+  <rule>True configures FilenamejoinTest.Result5 = "some\\content\\dir\\" filenamejoin FilenamejoinTest.File1.localPath</rule>
+  <rule>True configures FilenamejoinTest.Result6 = "Z:\\\\some\\\\content\\\\dir\\\\somefile.csv" filenamejoin FilenamejoinTest.File1.localPath</rule>
+  <rule>True configures FilenamejoinTest.Result7 = "Z:\\\\some\\\\content\\\\dir\\\\" filenamejoin FilenamejoinTest.File1.localPath</rule>
+  <rule>True configures FilenamejoinTest.Result8 = "somedir" filenamejoin FilenamejoinTest.File1.localPath</rule>
+  <rule>True configures FilenamejoinTest.Result9 = "somedir" filenamejoin "somefile.txt"</rule>
+  <rule>True configures FilenamejoinTest.Result10 = "somedir" filenamejoin "somefile.txt" + ';' + r'Z:\\some\\dir\\' filenamejoin FilenamejoinTest.File1.localPath</rule>
+  <rule>True and FilenamejoinTest.String1==r'Z:\\data\\sound.mp3' and True configures FilenamejoinTest.Result11 = "some" + "dir" filenamejoin "somefile.txt"</rule>
+</ruleml>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/ruleproject/rules/implml/rules.ruleml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ruleml xmlns="http://www.s60.com/xml/ruleml/2">
+  <rule>{% ${imaker.imagetarget} %} configures imakerapi.outputLocation = imaker.imagetarget</rule>
+  <rule>mms.imagesize == 'large' configures pd.ref1 = True and pd.ref2 = True</rule>
+  <rule>mms.imagesize == 'small' configures pd.ref1 = False and pd.ref2 = True</rule>
+  <rule>mms.imagesize == 'extrasmall' configures pd.ref1 = False and pd.ref2 = False</rule>
+  <rule>mms.imagesize == 'extralarge' configures pd.ref1 = True and pd.ref2 = False</rule>
+  <rule>imakerapi.outputLocationY == None configures imakerapi.outputLocationY = 'hello'</rule>
+  <rule>operations.minus == 5 configures operations.minus = operations.minus1 - operations.minus2</rule>
+  <rule>operations.minus1 == 25 configures operations.minus1 = operations.minus3 * operations.minus2</rule>
+  <rule>operations.minus4 == 10 configures operations.minus4 = operations.minus4 / operations.minus5</rule>
+  <rule>operations.minus6 == 5 configures operations.minus6 = operations.minus7 + operations.minus8</rule>
+  
+  <rule>True configures StringConcatenationTest.Result1 = "Test " + "test"</rule>
+  <rule>True configures StringConcatenationTest.Result2 = StringConcatenationTest.Value1 + " Literal 2"</rule>
+  <rule>True configures StringConcatenationTest.Result3 = "Literal 1 " + StringConcatenationTest.Value2</rule>
+  <rule>True configures StringConcatenationTest.Result4 = StringConcatenationTest.Value1 + StringConcatenationTest.Value2</rule>
+  <rule>True configures StringConcatenationTest.Result5 = StringConcatenationTest.Value1 + " &amp; " + StringConcatenationTest.Value2</rule>
+  <rule>True configures StringConcatenationTest.Result6 = StringConcatenationTest.Value1 + u" € カタカナ"</rule>
+  
+  <rule>True configures ударениÑ.ελληνικά = ударениÑ.ελληνικά + u" € カタカナ"</rule>
+  
+  <rule>{% @{Foo.Bar}.value %} configures ${Foo.Baz} = 'gaa'</rule>
+</ruleml>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/ruleproject/rules/implml/scripts/test_eval.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,18 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+def do_something(param):
+    return param + 1
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/ruleproject/rules/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,7 @@
+<configuration name="ruleml_test_config" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
+  <xi:include href="confml/testdata.confml" />
+<xi:include href="confml/filename_testdata.confml" />
+<xi:include href="confml/arithmetic.confml" />
+<xi:include href="confml/comparison_operators.confml" />
+<xi:include href="confml/eval.confml" />
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/runtests.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,19 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+if __name__ == '__main__':
+    import nose
+    nose.core.run(argv=['collector','--include=unittest', '--verbosity=3'])
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/unittest_eval.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,106 @@
+# *-* coding: utf-8 *-*
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+import unittest
+import os, shutil
+import sys
+import re
+
+from legacyruleplugin import ruleml, relations
+from cone.public import api, exceptions
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+class MockObject(object):
+    pass
+
+class MockFeature(object):
+    def __init__(self, ref, feature_values):
+        self.ref = ref
+        self.feature_values = feature_values
+    
+    def get_value(self):
+        return self.feature_values[self.ref]
+    
+    def set_value(self, value):
+        self.feature_values[self.ref] = value
+
+class MockConfigurationContext(object):
+    def __init__(self, feature_values):
+        self.configuration = MockObject()
+        default_view = MockObject()
+        default_view.get_feature = lambda ref: MockFeature(ref, feature_values)
+        self.configuration.get_default_view = lambda: default_view
+        self.ref_eval_callback = None
+
+class MockExpression(object):
+    def __init__(self, expression):
+        self.expression = repr(expression)
+
+class TestEvalExpression(unittest.TestCase):
+    def test_extract_refs(self):
+        ee = relations.EvalExpression(
+            None, MockExpression("'%05d 0x%08X %d' % (${Feature1.Setting1}.get_value(), ${Feature1.Setting2}.get_value(), ${Feature2.Setting1}.get_value())"))
+        self.assertEquals(sorted(ee.extract_refs()), sorted(["Feature1.Setting1", "Feature1.Setting2", "Feature2.Setting1"]))
+        
+        ee = relations.EvalExpression(None, MockExpression("'%05d 0x%08X %d' % (1, 2, 3)"))
+        self.assertEquals(ee.extract_refs(), [])
+        
+        ee = relations.EvalExpression(None, MockExpression(u"${ударениÑ.ελληνικά}"))
+        self.assertEquals(ee.extract_refs(), [u'ударениÑ.ελληνικά'])
+    
+    def test_execute(self):
+        feature_values = {
+            "Feature1.Setting1":  16,
+            "Feature1.Setting2":  32,
+            "Feature2.Setting1":  64,
+            u'ударениÑ.ελληνικά': 100,
+        }
+        context = MockConfigurationContext(feature_values)
+        
+        ee = relations.EvalExpression(None,
+            MockExpression("'%05d 0x%08X %d' % (@{Feature1.Setting1}.get_value(), @{Feature1.Setting2}.get_value(), @{Feature2.Setting1}.get_value())"))
+        self.assertEquals(ee.eval(context), "00016 0x00000020 64")
+        
+        ee = relations.EvalExpression(None, MockExpression("'%05d 0x%08X %d' % (1, 2, 3)"))
+        self.assertEquals(ee.eval(context), "00001 0x00000002 3")
+        
+        ee = relations.EvalExpression(None, MockExpression(u"'%d' % @{ударениÑ.ελληνικά}.get_value()"))
+        self.assertEquals(ee.eval(context), "100")
+
+class TestReplaceEvalBlocks(unittest.TestCase):
+    def test_replace_eval_blocks(self):
+        replace = ruleml.RuleImplReader2._replace_eval_blocks
+        
+        orig = """some.setting configures x = y"""
+        self.assertEquals(replace(orig), orig)
+        
+        orig = """some.setting configures x = {% do_something(@{Fea.Set}) %}"""
+        self.assertEquals(replace(orig), """some.setting configures x = __eval__ 'do_something(@{Fea.Set})'""")
+        
+        orig = """{% 'test' %}"""
+        self.assertEquals(replace(orig), '''__eval__ "'test'"''')
+        orig = """{%'test'%}"""
+        self.assertEquals(replace(orig), '''__eval__ "'test'"''')
+        
+        orig = """{% len(@{Fea.Set}.get_value()) %} == 3 configures x = {% do_something('test') %}"""
+        self.assertEquals(replace(orig), '''__eval__ 'len(@{Fea.Set}.get_value())' == 3 configures x = __eval__ "do_something('test')"''')
+        
+        orig = u"True configures X.Y = {% len(@{ударениÑ.ελληνικά}.get_value()) %}"
+        self.assertEquals(replace(orig), u"True configures X.Y = __eval__ %r" % u"len(@{ударениÑ.ελληνικά}.get_value())")
+        
+if __name__ == "__main__":
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/unittest_parseruleml.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,95 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+import unittest
+import os, shutil
+import sys
+try:
+    from cElementTree import ElementTree
+except ImportError:
+    try:    
+        from elementtree import ElementTree
+    except ImportError:
+        try:
+            from xml.etree import cElementTree as ElementTree
+        except ImportError:
+            from xml.etree import ElementTree
+
+from legacyruleplugin import ruleml, relations
+from cone.public import api, exceptions, utils, plugin
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+ruleml_string = \
+'''<?xml version="1.0" encoding="UTF-8"?>
+<ruleml xmlns="http://www.s60.com/xml/ruleml/2">
+  <rule>imaker.imagetarget configures imakerapi.outputLocation = imaker.imagetarget</rule>
+  <rule>imaker.imagename configures imakerapi.outputLocation = imaker.imagename</rule>
+</ruleml>
+'''
+
+class TestParseRuleimpl(unittest.TestCase):    
+    def setUp(self):    relations.register()
+    def tearDown(self): relations.unregister()
+    
+    def test_parse_rules(self):
+        etree = ElementTree.fromstring(ruleml_string)
+        reader = ruleml.RuleImplReader2(None, None)
+        rules = reader.parse_rules("",etree)
+        self.assertTrue(isinstance(rules[0],relations.ConfigureRelation))
+        self.assertTrue(isinstance(rules[1],relations.ConfigureRelation))
+        self.assertTrue(rules[0].has_ref('imaker.imagetarget'))
+        self.assertFalse(rules[0].has_ref('imakerapi.imagename'))
+        self.assertTrue(rules[0].has_ref('imakerapi.outputLocation'))
+
+
+class TestRulemlFromFile(unittest.TestCase):
+    def setUp(self):    pass
+    def tearDown(self): relations.unregister()
+    
+    def test_create_from_file(self):
+        project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'ruleproject/rules')))
+        config = project.get_configuration('root.confml')
+        ruleimpl = plugin.ImplFactory.get_impls_from_file('implml/rules.ruleml', config)[0]
+        relation_container = ruleimpl.get_relation_container()
+        self.assertTrue(isinstance(relation_container, plugin.RelationContainer))
+        self.assertEquals(relation_container.get_relation_count(), 18)
+
+    def test_create_from_file_with_common_container(self):
+        project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'ruleproject/rules')))
+        config = project.get_configuration('root.confml')
+        ruleimpl = plugin.ImplFactory.get_impls_from_file('implml/container_with_rules.ruleml', config)[0]
+        relation_container = ruleimpl.get_relation_container()
+        self.assertTrue(isinstance(relation_container, plugin.RelationContainer))
+        self.assertEquals(relation_container.get_relation_count(), 7)
+
+    def test_create_from_file_filename(self):
+        project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'ruleproject/rules')))
+        config = project.get_configuration('root.confml')
+        ruleimpl = plugin.ImplFactory.get_impls_from_file('implml/filename_rules.ruleml', config)[0]
+        relation_container = ruleimpl.get_relation_container()
+        self.assertTrue(isinstance(relation_container, plugin.RelationContainer))
+        self.assertEquals(relation_container.get_relation_count(), 11)
+
+    def test_parse_eval(self):
+        project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'ruleproject/rules')))
+        config = project.get_configuration('root.confml')
+        ruleimpl = plugin.ImplFactory.get_impls_from_file('implml/eval.ruleml', config)[0]
+        relation_container = ruleimpl.get_relation_container()
+        self.assertTrue(isinstance(relation_container, plugin.RelationContainer))
+        self.assertEquals(relation_container.get_relation_count(), 12)
+
+if __name__ == '__main__':
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/unittest_rule_empty_plugin.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,71 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+import unittest
+import os, shutil
+import sys
+import logging
+
+from cone.public import exceptions,plugin,api,container
+from cone.storage import filestorage
+from legacyruleplugin import ruleml
+
+# Hardcoded value of testdata folder that must be under the current working dir
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+testdata  = os.path.join(ROOT_PATH,'rule')
+
+class TestRuleEmptyPlugin(unittest.TestCase):    
+    def setUp(self):
+        pass
+      
+    def tearDown(self):
+        pass
+        
+        
+    def test_rule_with_empty_value1(self):
+        return
+        project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'ruleproject/rules'), "a" ))
+        config = project.get_configuration('root.confml')
+        implcontainer = plugin.get_impl_set(config)
+        implcontainer.generate()
+        lastconfig = config.get_last_configuration()
+        self.assertEquals(lastconfig.get_path(),ruleml.RuleImpl.AUTOCONFIGURATION_CONFML)
+        self.assertEquals(lastconfig.get_data('imakerapi.outputLocation').get_ref(),'outputLocation')
+        self.assertEquals(lastconfig.get_data('imakerapi.outputLocation').get_value(),'2')
+        self.assertEquals(lastconfig.get_data('imakerapi.outputLocationY').get_value(),'hello')
+        self.assertEquals(lastconfig.get_data('operations.minus').get_value(),'18')
+        self.assertEquals(lastconfig.get_data('operations.minus1').get_value(),'35')
+        self.assertEquals(lastconfig.get_data('operations.minus4').get_value(),'5')
+        project.close()
+    
+        
+    def test_rule_with_empty_value2(self):
+        return
+        project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'rule/config_project/platforms/customsw'), "a" ))
+        config = project.get_configuration('root.confml')
+        implcontainer = plugin.get_impl_set(config)
+        implcontainer.generate()
+        lastconfig = config.get_last_configuration()
+        self.assertEquals(lastconfig.get_data('operations.minus').get_value(),'18')
+        self.assertEquals(lastconfig.get_data('operations.minus1').get_value(),'35')
+        self.assertEquals(lastconfig.get_data('operations.minus4').get_value(),'5')
+        self.assertEquals(lastconfig.get_data('operations.minus6').get_value(),'19')
+        self.assertEquals(lastconfig.get_data('operations.string1').get_value(),'HelloWorld')
+        project.close()
+        
+        
+if __name__ == '__main__':
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/unittest_rule_plugin.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,93 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+import unittest
+import os, shutil
+import sys
+import logging
+
+from cone.public import exceptions,plugin,api,container
+from cone.storage import filestorage
+from legacyruleplugin import ruleml
+
+# Hardcoded value of testdata folder that must be under the current working dir
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+testdata  = os.path.join(ROOT_PATH,'ruleproject')
+
+class TestRulePlugin(unittest.TestCase):    
+    def setUp(self):
+        pass
+      
+    def tearDown(self):
+        pass
+
+class TestRulePluginOnFileStorage(unittest.TestCase):    
+    def test_get_impl_container(self):
+        project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'ruleproject/rules')))
+        config = project.get_configuration('root.confml')
+        implcontainer = plugin.get_impl_set(config, 'ruleml$')
+        impl = implcontainer.get_implementations_by_file('implml/rules.ruleml')[0]
+        
+        EXPECTED_REFS = sorted([
+            'imaker.imagetarget',
+            'mms.imagesize',
+            'imakerapi.outputLocationY',
+            'operations.minus',
+            'operations.minus1',
+            'operations.minus4',
+            'operations.minus6',
+            'Foo.Bar'])
+        self.assertEquals(EXPECTED_REFS, sorted(impl.get_child_refs()))
+        self.assertEquals([], impl.list_output_files())
+
+    def test_impl_container_execute_pre_rules(self):
+        project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'ruleproject/rules'), "a" ))
+        config = project.get_configuration('root.confml')
+        
+        implcontainer = plugin.get_impl_set(config, 'ruleml$')
+        ruleimpl = implcontainer.get_implementations_by_file('implml/container_with_rules.ruleml')[0]
+        context = plugin.GenerationContext(configuration=config)
+        context.phase = "pre"
+        ruleimpl.generate(context)
+        
+        lastconfig = config.get_last_configuration()
+        self.assertEquals(lastconfig.get_path(), plugin.AUTOCONFIG_CONFML)
+        self.assertEquals(lastconfig.list_all_datas(),['imakerapi', 
+                                                       'imakerapi.outputLocation', 
+                                                       'StringConcatenationTest', 
+                                                       'StringConcatenationTest.Result1', 
+                                                       'StringConcatenationTest.Result2'])
+        
+        self.assertEquals(lastconfig.get_data('imakerapi.outputLocation').get_ref(),'outputLocation')
+        self.assertEquals(lastconfig.get_data('imakerapi.outputLocation').get_value(),'2')
+        project.close()
+
+    def test_impl_container_execute_rules(self):
+        project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'ruleproject/rules'), "a" ))
+        config = project.get_configuration('root.confml')
+        context = plugin.GenerationContext(configuration=config)
+        implcontainer = plugin.get_impl_set(config, 'ruleml$')
+        implcontainer.generate(context)
+        
+        lastconfig = config.get_last_configuration()
+        self.assertEquals(lastconfig.get_path(), plugin.AUTOCONFIG_CONFML)
+        self.assertEquals(lastconfig.get_data('imakerapi.outputLocation').get_ref(),'outputLocation')
+        self.assertEquals(lastconfig.get_data('imakerapi.outputLocation').get_value(),'2')
+        project.close()
+        
+        
+if __name__ == '__main__':
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/unittest_rule_plugin_errors.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,109 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+import unittest
+import os, shutil
+import sys
+import logging
+
+from cone.public import exceptions,plugin,api,container
+from cone.storage import filestorage
+from legacyruleplugin import ruleml
+from testautomation.base_testcase import BaseTestCase
+
+# Hardcoded value of testdata folder that must be under the current working dir
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+testdata  = os.path.join(ROOT_PATH,'errorruleproject')
+
+class TestErrorReporting(BaseTestCase):
+    def setUp(self):
+        pass
+      
+    def tearDown(self):
+        pass
+    
+    def _prepare_workdir(self, workdir):
+        workdir = os.path.join(ROOT_PATH, workdir)
+        self.recreate_dir(workdir)
+        return workdir
+
+    def _prepare_log(self, log_file, level=logging.DEBUG, formatter="%(levelname)s - %(name)s - %(message)s", logger='cone'):
+        FULL_PATH = os.path.join(ROOT_PATH, "temp", log_file)
+        self.remove_if_exists(FULL_PATH)
+        self.create_dir_for_file_path(FULL_PATH)
+        
+        handler = logging.FileHandler(FULL_PATH)
+        handler.setLevel(level)
+        frm = logging.Formatter(formatter)
+        handler.setFormatter(frm)
+        logger = logging.getLogger(logger)
+        logger.addHandler(handler)
+        
+        return [FULL_PATH, handler, logger]
+    
+    def _execute_rules(self, project_location):
+        project = api.Project(api.Storage.open(os.path.join(ROOT_PATH, project_location)))
+        config = project.get_configuration('root.confml')
+        context = plugin.GenerationContext(configuration=config)
+        implcontainer = plugin.get_impl_set(config, r'\.ruleml$')
+        implcontainer.get_relation_container().execute(context)
+        lastconfig = config.get_last_configuration()
+        project.close()
+    
+    def test_terminal_expression_repr(self):
+        log_file, handler, logger = self._prepare_log('test1.log')
+        self._execute_rules('errorruleproject/test1')
+        logger.removeHandler(handler)
+        
+        self.assert_file_does_not_contain(log_file, "<cone.public.rules.TerminalExpression object at")
+
+    def test_invalid_python_code_eval(self):
+        log_file, handler, logger = self._prepare_log('test2.log')
+        self._execute_rules('errorruleproject/test2')
+        logger.removeHandler(handler)
+        self.assert_file_contains(log_file, "INFO - cone.ruleml - Set EvalTest2.StringResult = None from ConfigureRelation(ref='implml/invalid_python_eval.ruleml', lineno=3)")
+        self.assert_file_contains(log_file, "WARNING - cone.ruleml - Invalid syntax in eval: -> this is invalid python code")
+        self.assert_file_contains(log_file, "ERROR - cone.ruleml_relation_container(implml/invalid_python_eval.ruleml:3) - '-> this is invalid python code'")
+
+    def test_invalid_python_code_eval_globals(self):
+        log_file, handler, logger = self._prepare_log('test3.log')
+        self._execute_rules('errorruleproject/test3')
+        logger.removeHandler(handler)
+        self.assert_file_contains(log_file, "WARNING - cone.ruleml(implml/invalid_python_eval.ruleml) - Cannot import eval file: implml/scripts/test_eval.py. Exception: invalid syntax (<string>, line 17)")
+        
+    def test_invalid_file_reference_in_eval_globals_file_attribute(self):
+        log_file, handler, logger = self._prepare_log('test4.log')
+        self._execute_rules('errorruleproject/test4')
+        logger.removeHandler(handler)
+        self.assert_file_contains(log_file, "WARNING - cone.ruleml(implml/invalid_python_eval.ruleml) - Cannot import eval file: implml/scripts/not_valid_filename.py. Exception: implml/scripts/not_valid_filename.py, [Errno 2] No such file or directory:")
+        self.assert_file_contains(log_file, '/implml/scripts/not_valid_filename.py')
+    
+    def test_runtime_error_when_running_an_eval_block_inside_rule(self):
+        log_file, handler, logger = self._prepare_log('test5.log')
+        self._execute_rules('errorruleproject/test5')
+        logger.removeHandler(handler)
+
+        self.assert_file_contains(log_file, "Execution failed for eval: 7/0 <type 'exceptions.ZeroDivisionError'>: integer division or modulo by zero")
+
+    def test_references_non_existent_settings(self):
+        log_file, handler, logger = self._prepare_log('test6.log')
+        self._execute_rules('errorruleproject/test6')
+        logger.removeHandler(handler)
+        #self.assert_file_contains(log_file, "Execution failed for eval: 7/0 <type 'exceptions.ZeroDivisionError'>: integer division or modulo by zero")
+
+    
+if __name__ == '__main__':
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/tests/unittest_rules.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,178 @@
+# *-* coding: utf-8 *-*
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+import unittest
+import os, shutil
+import sys
+# import legacyruleplugin_testinit
+
+from legacyruleplugin import ruleml
+from cone.public import api, plugin
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+class TestRuleExecutes(unittest.TestCase):
+    
+    def setUp(self):
+        self.project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'ruleproject/rules')))
+        self.config = self.project.get_configuration('root.confml')
+    
+    def tearDown(self):
+        self.project.close()
+    
+    def _execute_rules(self, impl_filter):
+        implcontainer = plugin.get_impl_set(self.config, impl_filter)
+        context = plugin.GenerationContext(configuration=self.config)
+        implcontainer.generate(context)
+        return context.generation_output
+    
+    def test_arithmetic_operations(self):
+        self._execute_rules(r'^implml/arithmetic\.ruleml$')
+        
+        # Values used in the ConfML (the calculations are duplicated here to make
+        # the tests more readable)
+        value1 = 5
+        value2 = 20
+        config = self.config
+        self.assert_setting_equals(config, 'Arithmetic.AdditionResult1', 2 + 6)
+        self.assert_setting_equals(config, 'Arithmetic.AdditionResult2', value1 + 6)
+        self.assert_setting_equals(config, 'Arithmetic.AdditionResult3', 2 + value2)
+        self.assert_setting_equals(config, 'Arithmetic.AdditionResult4', value1 + value2)
+        
+        self.assert_setting_equals(config, 'Arithmetic.SubtractionResult1', 2 - 6)
+        self.assert_setting_equals(config, 'Arithmetic.SubtractionResult2', value1 - 6)
+        self.assert_setting_equals(config, 'Arithmetic.SubtractionResult3', 2 - value2)
+        self.assert_setting_equals(config, 'Arithmetic.SubtractionResult4', value1 - value2)
+        
+        self.assert_setting_equals(config, 'Arithmetic.MultiplicationResult1', 2 * 6)
+        self.assert_setting_equals(config, 'Arithmetic.MultiplicationResult2', value1 * 6)
+        self.assert_setting_equals(config, 'Arithmetic.MultiplicationResult3', 2 * value2)
+        self.assert_setting_equals(config, 'Arithmetic.MultiplicationResult4', value1 * value2)
+        
+        self.assert_setting_equals(config, 'Arithmetic.DivisionResult1', 6 / 2)
+        self.assert_setting_equals(config, 'Arithmetic.DivisionResult2', value2 / 4)
+        self.assert_setting_equals(config, 'Arithmetic.DivisionResult3', 10 / value1)
+        self.assert_setting_equals(config, 'Arithmetic.DivisionResult4', value2 / value1)
+        
+        self.assert_setting_equals(config, 'Arithmetic.MixedResult1', (6 / 2 + 3 * 9) - 7)
+        self.assert_setting_equals(config, 'Arithmetic.MixedResult2', (6 / 2 + value1 * 9) - 7)
+        self.assert_setting_equals(config, 'Arithmetic.MixedResult3', (value2 / 2 + value1 * 9) - 7)
+        self.assert_setting_equals(config, 'Arithmetic.MixedResult4', (value2 / value1 + value1 * value1) - value2)
+        self.assert_setting_equals(config, 'Arithmetic.MixedResult5', 4 + 6 / 2 - 3 * 9 + 10 / 5 - 8)
+        
+        rvalue1 = float(value1)
+        rvalue2 = float(value2)
+        self.assert_setting_equals(config, 'Arithmetic.RealResult1', 5.0 / 2.0)
+        self.assert_setting_equals(config, 'Arithmetic.RealResult2', rvalue1 / 2.0)
+        self.assert_setting_equals(config, 'Arithmetic.RealResult3', 0.25 * rvalue2)
+        self.assert_setting_equals(config, 'Arithmetic.RealResult4', rvalue1 / 2.0 * rvalue2)
+#
+        self.assert_setting_equals(config, 'Arithmetic.RealCalcIntoIntResult', int(0.25 * rvalue1))
+        self.assert_setting_equals(config, 'Arithmetic.IntCalcIntoRealResult', float(3 * value1))
+    
+    def test_string_concatenation(self):
+        self._execute_rules(r'^implml/rules\.ruleml$')
+        
+        config = self.config
+        self.assert_setting_equals(config, 'StringConcatenationTest.Result1', 'Test test')
+        self.assert_setting_equals(config, 'StringConcatenationTest.Result2', 'String 1 Literal 2')
+        self.assert_setting_equals(config, 'StringConcatenationTest.Result3', 'Literal 1 String 2')
+        self.assert_setting_equals(config, 'StringConcatenationTest.Result4', 'String 1String 2')
+        self.assert_setting_equals(config, 'StringConcatenationTest.Result5', 'String 1 & String 2')
+        self.assert_setting_equals(config, 'StringConcatenationTest.Result6', u'String 1 € カタカナ')
+        
+        self.assert_setting_equals(config, u'ударениÑ.ελληνικά', u'カタカナ € カタカナ')
+        
+    
+    def test_filenamejoin(self):
+        self._execute_rules(r'^implml/filename_rules\.ruleml$')
+        
+        config = self.config
+        self.assert_setting_equals(config, 'FilenamejoinTest.Result1', r'Z:\\data\\file1.txt')
+        self.assert_setting_equals(config, 'FilenamejoinTest.Result2', r'some/content/dir/file1.txt')
+        self.assert_setting_equals(config, 'FilenamejoinTest.Result3', r'some/content/dir/file1.txt')
+        self.assert_setting_equals(config, 'FilenamejoinTest.Result4', r'some\content\dir\file1.txt')
+        self.assert_setting_equals(config, 'FilenamejoinTest.Result5', r'some\content\dir\file1.txt')
+        self.assert_setting_equals(config, 'FilenamejoinTest.Result6', r'Z:\\some\\content\\dir\\file1.txt')
+        self.assert_setting_equals(config, 'FilenamejoinTest.Result7', r'Z:\\some\\content\\dir\\file1.txt')
+        self.assert_setting_equals(config, 'FilenamejoinTest.Result8', r'somedir/file1.txt')
+        self.assert_setting_equals(config, 'FilenamejoinTest.Result9', r'somedir/somefile.txt')
+        self.assert_setting_equals(config, 'FilenamejoinTest.Result10', r'somedir/somefile.txt;Z:\\some\\dir\\file1.txt')
+        self.assert_setting_equals(config, 'FilenamejoinTest.Result11', r'somedir/somefile.txt')
+    
+    def test_comparison_operators(self):
+        self._execute_rules(r'^implml/comparison_operators\.ruleml$')
+        
+        for i in xrange(1, 8):
+            ref = 'CompOperTest.LiteralsResult%d' % i
+            self.assert_setting_equals(self.config, ref, True, "Setting %s is not True" % ref)
+        
+        for i in xrange(1, 8):
+            ref = 'CompOperTest.RefsResult%d' % i
+            self.assert_setting_equals(self.config, ref, True, "Setting %s is not True" % ref)
+    
+    def test_eval(self):
+        config = self.config
+        
+        self.assert_setting_equals(config, 'EvalTest.FullSequence',
+            [['Full 1', 10, 1.5, True],
+             ['Full 2', 20, 2.5, False]])
+        
+        self._execute_rules(r'^implml/eval\.ruleml$')
+        
+        self.assert_setting_equals(config, 'EvalTest.StringLenResult', 8)
+        self.assert_setting_equals(config, 'EvalTest.EvalConstantResult', 12345)
+        self.assert_setting_equals(config, 'EvalTest.EvalFileImport', 12346)
+        self.assert_setting_equals(config, 'EvalTest.UnchangedValue', 0)
+        self.assert_setting_equals(config, 'EvalTest.UnicodeResult1', u'100€')
+        self.assert_setting_equals(config, 'EvalTest.UnicodeResult2', u'カタカナ')
+        self.assert_setting_equals(config, 'EvalTest.Bit0Result', False)
+        self.assert_setting_equals(config, 'EvalTest.Bit1Result', True)
+        self.assert_setting_equals(config, 'EvalTest.Bit2Result', False)
+        self.assert_setting_equals(config, 'EvalTest.Bit3Result', True)
+        self.assert_setting_equals(config, 'EvalTest.FullSequence',
+            [['Full 1', 10, 1.5, True],
+             ['Full 2', 20, 2.5, False],
+             ['Stripped 1', 1, 0.1, False],
+             ['Stripped 2', 2, 0.1, False]])
+        self.assert_setting_equals(config, 'EvalTest.EvalBuiltinResult', 'ruleml_test_config')
+    
+    def assert_setting_equals(self, config, setting, expected_value, msg=None):
+        if msg == None:
+            self.assertEquals(config.get_default_view().get_feature(setting).get_value(), expected_value)
+        else:
+            self.assertEquals(config.get_default_view().get_feature(setting).get_value(), expected_value, msg)
+    
+    def test_rule_execution_results(self):
+        results = self._execute_rules(r'^implml/rules\.ruleml$')
+        
+        outputs = [(output.name, output.implementation.get_refs()) for output in results if output.type == 'ref']  
+        self.assertEquals(outputs, [(u'imakerapi.outputLocation', [u'imaker.imagetarget']), 
+                                   (u'imakerapi.outputLocationY', [u'imakerapi.outputLocationY']), 
+                                   (u'operations.minus', [u'operations.minus']), 
+                                   (u'operations.minus1', [u'operations.minus1']), 
+                                   (u'operations.minus4', [u'operations.minus4']), 
+                                   (u'operations.minus6', [u'operations.minus6']), 
+                                   (u'StringConcatenationTest.Result1', []), 
+                                   (u'StringConcatenationTest.Result2', []), 
+                                   (u'StringConcatenationTest.Result3', []), 
+                                   (u'StringConcatenationTest.Result4', []), 
+                                   (u'StringConcatenationTest.Result5', []), 
+                                   (u'StringConcatenationTest.Result6', []), 
+                                   (u'\u0443\u0434\u0430\u0440\u0435\u043d\u0438\u044f.\u03b5\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac', [])]) 
+            
+if __name__ == '__main__':
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/xsd/ruleml.xsd	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema 
+	xmlns:xs="http://www.w3.org/2001/XMLSchema"
+	targetNamespace="http://www.s60.com/xml/ruleml/1"
+	xmlns:ruleml="http://www.s60.com/xml/ruleml/1"
+	elementFormDefault="qualified">
+
+    <xs:element name="ruleml">
+        <xs:annotation>
+            <xs:documentation>
+                RuleML v1 implementation for specifying rules to execute.
+            </xs:documentation>
+        </xs:annotation>
+        <xs:complexType>
+            <xs:choice minOccurs="0" maxOccurs="unbounded">
+                <xs:element name="rule" type="xs:string">
+                    <xs:annotation>
+                        <xs:documentation>
+                            <![CDATA[
+                            <p>The rule element specifies a single rule to execute.</p><br/>
+                            
+                            <p>
+                            For example:<br/>
+                            <b>&lt;rule>MyFeature.MySetting1 == 'test' configures MyFeature.MySetting2 = '1'&lt;/rule></b><br/>
+                            This would cause the value '1' to be assigned to the setting 'MyFeature.MySetting2'
+                            if the value of the setting 'MyFeature.MySetting1' is 'test'.
+                            </p>
+                            ]]>
+                        </xs:documentation>
+                    </xs:annotation>
+                </xs:element>
+            </xs:choice>
+        </xs:complexType>
+    </xs:element>
+</xs:schema>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/legacyruleplugin/xsd/ruleml2.xsd	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema 
+	xmlns:xs="http://www.w3.org/2001/XMLSchema"
+	targetNamespace="http://www.s60.com/xml/ruleml/2"
+	xmlns:ruleml="http://www.s60.com/xml/ruleml/2"
+	elementFormDefault="qualified">
+
+    <xs:element name="ruleml">
+        <xs:annotation>
+            <xs:documentation>
+                RuleML v2 implementation for specifying rules to execute.
+            </xs:documentation>
+        </xs:annotation>
+        <xs:complexType>
+            <xs:choice minOccurs="0" maxOccurs="unbounded">
+                <xs:element name="rule" type="xs:string">
+                    <xs:annotation>
+                        <xs:documentation>
+                            <![CDATA[
+                            <p>The rule element specifies a single rule to execute.</p><br/>
+                            
+                            <p>
+                            For example:<br/>
+                            <b>&lt;rule>MyFeature.MySetting1 == 'test' configures MyFeature.MySetting2 = '1'&lt;/rule></b><br/>
+                            This would cause the value '1' to be assigned to the setting 'MyFeature.MySetting2'
+                            if the value of the setting 'MyFeature.MySetting1' is 'test'.
+                            </p><br/>
+                            
+                            <p>
+                            Arbitrary Python code can also be executed in the rule by enclosing the eval block
+                            with {% %}. For example:<br/>
+                            <b>&lt;rule>True configures MyFeature.MySetting = {% get_some_value() %}&lt;/rule></b><br/>
+                            This would cause the value got from evaluating the Python function call
+                            get_some_value() to be assigned to the setting 'MyFeature.MySetting'.
+                            </p><br/>
+                            
+                            <p>
+                            Any settings referenced inside an eval block must be enclosed with ${ }
+                            to differentiate them from the Python code. For example:<br/>
+                              <b>&lt;rule>True configures MyFeature.MySetting = {% get_some_value(${MyFeature.MySetting1}) %}&lt;/rule></b><br/>
+                            This would cause the value of the setting 'MyFeature.MySetting1' to be passed as a
+                            parameter to the function call.
+                            The actual feature object handled by ConE can be accessed by enclosing the setting
+                            reference with @{ }.
+                            </p><br/>                            
+                            
+                            <p>
+                            Any functions or variables (like get_some_value() in the above examples) need
+                            to be defined using eval_globals elements inside the ruleml element.
+                            </p>
+                            ]]>
+                        </xs:documentation>
+                    </xs:annotation>
+                </xs:element>
+                <xs:element name="eval_globals" type="ruleml:evalGlobalsType">
+                    <xs:annotation>
+                        <xs:documentation>
+                            An eval_globals block can be used to add Python variables
+                            or functions to the evaluation context of the rules contained
+                            within the current ruleml implementation. The Python code can be contained
+                            either directly inside the XML element or inside a file pointed by the
+                            'file' attribute.
+                        </xs:documentation>
+                    </xs:annotation>
+                </xs:element>
+            </xs:choice>
+        </xs:complexType>
+    </xs:element>
+    
+    <xs:complexType name="evalGlobalsType">
+        <xs:simpleContent>
+            <xs:extension base="xs:string">
+                <xs:attribute name="file" type="xs:string" use="optional">
+                    <xs:annotation>
+                        <xs:documentation>
+                            Path to the file containing the Python code of the eval_globals element.
+                            Should be a path relative to the current implementation file.
+                            Specifying the 'file' attribute causes the text content of the eval_globals
+                            element to be ignored.
+                        </xs:documentation>
+                    </xs:annotation>
+                </xs:attribute>
+            </xs:extension>
+        </xs:simpleContent>
+    </xs:complexType>
+</xs:schema>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/setup.cfg	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,2 @@
+[egg_info]
+tag_svn_revision = 1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeLegacyRulePlugin/setup.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,40 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+import os, os.path
+from setuptools import setup, find_packages
+from legacyruleplugin import __version__
+
+setup(
+    name = "conelegacyruleplugin",
+    version = __version__,
+    packages = find_packages(exclude=["*.tests"]),
+    package_data = {'legacyruleplugin': ['xsd/*.xsd']},
+    test_suite = "legacyruleplugin.tests.collect_suite",
+
+    # metadata for upload to PyPI
+    author = "Teemu Rytkonen",
+    author_email = "teemu.rytkonen@nokia.com",
+    description = "Configuration Engine rule plugin",
+    license = "Eclipse Public License v1.0",
+    keywords = "cone",
+    url = "http://developer.symbian.org/wiki/index.php/Software_Configuration_Middleware",   # project home page, if any
+    zip_safe = True,
+    
+    # entrypoint info
+    entry_points={'cone.plugins.implmlreaders': ['ruleml_1 = legacyruleplugin.ruleml:RuleImplReader1',
+                                                 'ruleml_2 = legacyruleplugin.ruleml:RuleImplReader2']}
+)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/__init__.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,16 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
--- a/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/__init__.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/__init__.py	Tue Aug 10 14:29:28 2010 +0300
@@ -16,15 +16,3 @@
 
 __version__ = 0.1
 
-
-import pkg_resources 
-import sys,os
-
-try:
-  pkg_resources.require("Cone")
-except pkg_resources.DistributionNotFound:
-  ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
-  sys.path.append(ROOT_PATH)
-  sys.path.append(os.path.join(ROOT_PATH,'..'))
-  sys.path.append(os.path.join(ROOT_PATH,'../..'))
-  sys.path.append(os.path.join(ROOT_PATH,'../../..'))
\ No newline at end of file
--- a/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/accesspoint_id_counter.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/accesspoint_id_counter.py	Tue Aug 10 14:29:28 2010 +0300
@@ -21,59 +21,55 @@
 
 logger = logging.getLogger('cone.ruleplugin.evals.accesspoint_id_counter')
 
-def get_apindex_by_apname(aps, dns, apname):
+def get_apindex_by_apname(wlan_aps, aps, dns, apname):
     """
     Returns AccessPoint index by given AccessPoint name
     """
-    cnt = _get_ApDnContainer_(aps, dns)
+    cnt = _get_ApDnContainer_(wlan_aps, aps, dns)
     return cnt.get_apindex_by_apname(apname)
 
-def get_apid_by_apname(aps, dns, apname, wlan_support=True):
+def get_apid_by_apname(wlan_aps, aps, dns, apname):
     """
     Returns AccessPoint id by given AccessPoint name
     """
-    cnt = _get_ApDnContainer_(aps, dns, wlan_support)
+    cnt = _get_ApDnContainer_(wlan_aps, aps, dns)
     return cnt.get_apid_by_apname(apname)
 
-def get_dnid_by_dnname(aps, dns, dnname, wlan_support=True):
+def get_dnid_by_dnname(aps, dns, dnname):
     """
     Return DestinationNetwork id by given DestinationNetworks name
     """
-    cnt = _get_ApDnContainer_(aps, dns, wlan_support)
+    cnt = _get_ApDnContainer_(wlan_aps, aps, dns)
     return cnt.get_dnid_by_dnname(dnname)
 
-def get_apid_by_dnname_and_apname(aps, dns, dnname, apname, wlan_support=True):
+def get_apid_by_dnname_and_apname(wlan_aps, aps, dns, dnname, apname):
     """
     Returns AccessPoint id by given DestinationNetwork name and AccessPoint name.
     """
-    cnt = _get_ApDnContainer_(aps, dns, wlan_support)
+    cnt = _get_ApDnContainer_(wlan_aps, aps, dns)
     return cnt.get_apid_by_dnname_and_apname(dnname, apname)
 
-def get_all_in_array(aps, dns, wlan_support=True):
+def get_all_in_array(wlan_aps, aps, dns):
     """
     Returns array containing all data:
         [DN name],[DN id], [IAPS names], [IAPS ids], [IAPS indexes] 
     """
-    cnt = _get_ApDnContainer_(aps, dns, wlan_support)
+    cnt = _get_ApDnContainer_(wlan_aps, aps, dns)
     return cnt.get_all_in_array()
 
-def _get_ApDnContainer_(aps, dns, wlan_support=True):
+def _get_ApDnContainer_(wlan_aps, aps, dns):
     """
     Returns populated ApDnContainer
     """
     cnt = ApDnContainer()
     
     _read_dns_(dns, cnt)
+    _read_wlan_aps_(wlan_aps, cnt)
     _read_aps_(aps, cnt)
     
     cnt._calc_dn_ids_()
-    
-    if wlan_support:
-        cnt._calc_ap_ids_(2)
-    else:
-        cnt._calc_ap_ids_(1)
-    
-    cnt._calc_ap_indexes_(1)
+    cnt._calc_ap_ids_()
+    cnt._calc_ap_indexes_()
     
     return cnt
 
@@ -127,6 +123,12 @@
         cnt.add_dn(mydn)
     return cnt
 
+def _read_all_aps_(wlan_aps, aps, cnt):
+    """
+    Reads WLAN_APs and APs to internal objects to ApDnContainer
+    """
+    
+
 def _read_aps_(aps, cnt):
     """
     Reads APs to internal objects to ApDnContainer.
@@ -159,7 +161,39 @@
         cnt.add_ap(myap)
     return cnt
 
-def _get_next_free_id_(bases, start_index=1):
+def _read_wlan_aps_(wlan_aps, cnt):
+    """
+    Reads APs to internal objects to ApDnContainer.
+    """
+    ap_names = None
+    ap_ids1 = None
+    
+    for ap in wlan_aps.WLAN_AP:
+        if ap.ref == 'ConnectionName':
+            ap_names = ap.value
+        if ap.ref == 'ConnectionId':
+            ap_ids1 = ap.value
+    
+    ap_ids2 = [None]*len(ap_names)
+    if ap_ids1 == None:
+        ap_ids1 = []
+    
+    
+    for i in range(len(ap_ids1)):
+        ap_ids2[i] = ap_ids1[i]
+        
+    
+    logger.info('Parsed WLAN_AP names: %s' % ap_names)
+    logger.info('Parsed WLAN_AP ids: %s' % ap_ids2)
+    
+    for i in range(len(ap_names)):
+        myap = Ap()
+        myap.set_id(ap_ids2[i])
+        myap.set_name(ap_names[i])
+        cnt.add_ap(myap)
+    return cnt
+
+def _get_next_free_id_(bases, start_index=0):
     """
     Returns next id as a string that is not in use.
     """
@@ -206,7 +240,6 @@
 
     def _calc_ap_indexes_(self, ind=1):
         index = ind
-        
         for dn in self.dns:
             for iap in dn.get_iaps():
                 if iap != None:
@@ -215,16 +248,11 @@
                             ap.set_index(str(index))
                             index += 1
 
-    def _calc_ap_ids_(self, start_index=1):
-        """
-        Calculates unique index for every AccessPoint, if Easy_WLAN is given it always have index 1.
+    def _calc_ap_ids_(self, start_index=0):
         """
-        
-        for ap in self.aps:
-            if ap.name == 'Easy WLAN':
-                ap.set_id('1')
-                logger.info('Easy_WLAN AP found. Setting 1 to AP id.')
-                
+        Calculates unique index for every AccessPoint.
+        """
+                        
         for ap in self.aps:
             if ap.get_id() == None or ap.get_id() == '':
                 ap.set_id(_get_next_free_id_(self.aps, int(start_index)))
@@ -237,6 +265,7 @@
         for ap in self.aps:
             if ap.name == apname:
                 return ap.get_id()
+        logger.warning('ApId not found by ApName: %s' % apname)
         return None
     
     def get_apindex_by_apname(self, apname):
@@ -247,6 +276,7 @@
         for ap in self.aps:
             if ap.get_name() == apname:
                 return ap.get_index()
+        logger.warning('ApIndex not found by ApName: %s' % apname)
         return None
     
     
@@ -257,6 +287,7 @@
         for dn in self.dns:
             if dn.name == dnname:
                 return dn.id
+        logger.warning('DnId not found by DnName: %s' % dnname)
         return None
     
     def get_apid_by_dnname_and_apname(self, dnname, apname):
@@ -269,6 +300,7 @@
                 for iap in range(len(iaps)):
                     if iaps[iap] != None and iaps[iap] == apname:
                         return self.get_apid_by_apname(apname)
+        logger.warning('ApId not found by DnName: %s ApName: %s' % dnname, apname)
         return None
     
     def get_all_in_array(self):
--- a/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/layer_utils.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/layer_utils.py	Tue Aug 10 14:29:28 2010 +0300
@@ -1,9 +1,9 @@
 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
 # All rights reserved.
 # This component and the accompanying materials are made available
-# under the terms of "Eclipse Public License v1.0"
+# under the terms of the License "Symbian Foundation License v1.0"
 # which accompanies this distribution, and is available
-# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+# at the URL "http://www.symbianfoundation.org/legal/sfl-v10.html".
 #
 # Initial Contributors:
 # Nokia Corporation - initial contribution.
@@ -17,12 +17,52 @@
 Ruleml eval extension to check is passed ref changed on given layer(range).
 '''
 
-from cone.public import api
+from cone.public import api, plugin
 
 import logging
+import re
 
 logger = logging.getLogger('cone.ruleplugin.evals.layer_utils')
 
+
+def layers_used(config, layers_or_regex, impl_tags):
+    """
+    Return True if matching layers are used by any implementation with given tag.
+    @param config: The configuration.
+    @param layers_or_regex: List of layer objects to check against, or regular
+        expression (string) for resolving the list of layers.
+    @param impl_tags: Implementation tags to use.
+    """
+    # Resolve layer list
+    if isinstance(layers_or_regex, basestring):
+        layers = []
+        for lay in config.list_configurations():
+            if re.search(layers_or_regex, lay):
+                layers.append(config.get_configuration(lay))
+    else:
+        layers = layers_or_regex
+    
+    impls = plugin.filtered_impl_set(config).filter_implementations(tags=impl_tags)
+    context = plugin.GenerationContext(tags=impl_tags,
+                                       configuration=config)
+    for impl in impls:
+        if impl.uses_layers(layers, context) == True:
+            return True
+    return False
+
+
+def get_all_layers(feat):
+    """
+    Returns all layers.
+    """
+    
+    root_conf = feat.get_root_configuration()
+    result = []
+    
+    for i in range(0, len(root_conf.list_configurations())):
+        result.append(root_conf.get_configuration_by_index(i))
+    return result
+
 def give_changed_layers(feat):
     """
     Returns a list of booleans where True means that feature is changed in that layer. Index is
@@ -33,22 +73,9 @@
     
     root_conf = feat.get_root_configuration()
     nro_of_layers = len(root_conf.list_configurations())
-    result = [False] * nro_of_layers
-    
+    result = []
     for i in range(0, nro_of_layers):
-        conf = root_conf.get_configuration_by_index(i)
-        logger.debug("Traversing data from configuration: %s" % conf.get_path())
-        datas = conf._traverse(type=api.Data, filters=[lambda d: d.fqr==feat.fqr])
-        for data in datas:
-            try:
-                if data.get_value() != None:
-                    logger.debug("Feature '%s' is changed in layer %s with data '%s'" % (feat.fqr, i, data.get_value()))
-                    result[i] = True
-            except Exception, e:
-                logger.debug("Failed to check Feature '%s' data in layer %s:", (e,i))
-        if result[i] == False:
-            logger.debug("Feature '%s' is not changed in layer: %s" % (feat.fqr, i))
-    logger.debug("Feature '%s' is changed in layers: %s" % (feat.fqr, result))
+        result.append(_changed_on_layer(feat, root_conf.get_configuration_by_index(i)))
     return result
 
 def changed_on_last_layer(feat):
@@ -58,18 +85,7 @@
     
     root_conf = feat.get_root_configuration()
     conf = root_conf.get_configuration_by_index(-2)#autoconfig layer is ignored 
-    
-    def check(node):
-        if isinstance(node, api.Data) and node.fqr == feat.fqr:
-            return True
-        for obj in node._objects():
-            if check(obj):
-                return True
-    
-    if check(conf):
-        return True
-    else:
-        return False
+    return _changed_on_layer(feat, conf)
 
 def changed_on_autoconfig_layer(feat):
     """
@@ -77,19 +93,8 @@
     """
     
     root_conf = feat.get_root_configuration()
-    conf = root_conf.get_configuration_by_index(-1) 
-    
-    def check(node):
-        if isinstance(node, api.Data) and node.fqr == feat.fqr:
-            return True
-        for obj in node._objects():
-            if check(obj):
-                return True
-    
-    if check(conf):
-        return True
-    else:
-        return False
+    conf = root_conf.get_configuration_by_index(-1)
+    return _changed_on_layer(feat, conf)
 
 def changed_on_layer(feat, layer):
     """
@@ -97,23 +102,72 @@
     """
     try:
         return give_changed_layers(feat)[layer]
-    except IndexError, e:
+    except IndexError:
         logger.warning("Given layer is not found: %s" % (layer))
         return False
 
+def _changed_on_layer(feature, layer_obj):
+    """
+    Return whether the given feature is changed on the given layer.
+    """
+    # Check recursively if the layer contains any data objects with
+    # the same FQR as the feature
+    def check(node):
+        if isinstance(node, api.Data) and node.fqr == feature.fqr:
+            return True
+        for obj in node._objects():
+            if check(obj):
+                return True
+        return False
+    
+    return check(layer_obj)
+
 def changed_on_layers(feat, findex, tindex):
     """
     Returns True if feature is changed in layer of given range.
     """
-    layers = give_changed_layers(feat)
+    root_conf = feat.get_root_configuration()
+    nro_of_layers = len(root_conf.list_configurations())
     
-    if findex == tindex:
-        return changed_on_layer(feat, findex)
+    # Convert negative indices to positive
+    def neg_index_to_pos(index):
+        if index < 0:   return nro_of_layers + index
+        else:           return index
+    begin = neg_index_to_pos(findex)
+    end = neg_index_to_pos(tindex)
     
-    for i in range(findex, tindex):
-        if i > len(layers):
+    if end == begin:
+        return changed_on_layer(feat, begin)
+    
+    # Check the layers inside the range
+    if end > begin: index_range = xrange(begin, end)
+    else:           index_range = xrange(end, begin)
+    for i in index_range:
+        if i < 0 or i >= nro_of_layers:
             continue
-        if layers != None and layers[i] != None and layers[i]:
+        
+        layer = root_conf.get_configuration_by_index(i)
+        if _changed_on_layer(feat, layer):
             return True
     return False
 
+def changed_on_layers_regex(feat, regex):
+    """
+    Return whether the given feature is changed on any layer that matches
+    the given regular expression.
+    """
+    pattern = re.compile(regex)
+    root_conf = feat.get_root_configuration()
+    for config_path in root_conf.list_configurations():
+        if pattern.search(config_path):
+            layer = root_conf.get_configuration(config_path)
+            if _changed_on_layer(feat, layer):
+                return True
+    return False
+
+def changed_on_custvariant_layer(feat):
+    """
+    Return whether the given feature is changed on any of the custvariant layers
+    (layers that match the regex '/custvariant(_.*)?/').
+    """
+    return changed_on_layers_regex(feat, r'/custvariant(_.*)?/')
--- a/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/shortcuts_conversion.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/shortcuts_conversion.py	Tue Aug 10 14:29:28 2010 +0300
@@ -17,79 +17,79 @@
 import os
 
 def get_fixed_target_path(feature, setting):
-	type_ref = setting + '_type'
-	type = feature.get_feature(type_ref)
-	type_value = type.get_value()
-	ret = ""
-	if type_value == '1':
-		None
-	elif type_value == '2':
-		icon = feature.get_feature(setting + '_icon')
-		if icon != None:
-			ret = get_fixed_icon_target(icon)
-	else:
-		None
-		
-	return ret
+    type_ref = setting + '_type'
+    type = feature.get_feature(type_ref)
+    type_value = type.get_value()
+    ret = ""
+    if type_value == '1':
+        None
+    elif type_value == '2':
+        icon = feature.get_feature(setting + '_icon')
+        if icon != None:
+            ret = get_fixed_icon_target(icon)
+    else:
+        None
+        
+    return ret
 
 def get_fixed_icon_target(icon):
-	targetPath = icon.get_feature('targetPath').get_value()
-	localPath = icon.get_feature('localPath').get_value()
-	target = get_target_without_extension(targetPath)
-	extension = get_correct_extension(localPath)
-	fixed = ""
-	if extension != None:
-		if len(target) > 0 and len(extension) > 0:
-			fixed = target + extension
-	return fixed
+    targetPath = icon.get_feature('targetPath').get_value()
+    localPath = icon.get_feature('localPath').get_value()
+    target = get_target_without_extension(targetPath)
+    extension = get_correct_extension(localPath)
+    fixed = ""
+    if extension != None:
+        if len(target) > 0 and len(extension) > 0:
+            fixed = target + extension
+    return fixed
 
 def get_target_without_extension(targetPath):
-	(target,_) = os.path.splitext(targetPath)
-	return target
+    (target,_) = os.path.splitext(targetPath)
+    return target
 
 def get_correct_extension(localPath):
-	
-	if localPath != None:
-		(_,extension) = os.path.splitext(localPath)
-		if extension == '.bmp':
-			return '.mbm'
-		elif extension == '.svg':
-			return '.mif'
-		else:
-			return extension
-	else:
-		return None
+    
+    if localPath != None:
+        (_,extension) = os.path.splitext(localPath)
+        if extension == '.bmp':
+            return '.mbm'
+        elif extension == '.svg':
+            return '.mif'
+        else:
+            return extension
+    else:
+        return None
 
 def get_shortcut_string(feature, setting):
-	type_ref = setting + '_type'
-	type_value = feature.get_feature(type_ref).get_value()
-	ret = ""
-	if type_value == '1':
-		app_ref = setting + '_app'
-		application = feature.get_feature(app_ref).get_value()
-		ret = application
-	elif type_value == '2':
-		url = feature.get_feature(setting+'_URL').get_value()
-		title = feature.get_feature(setting+'_title').get_value()
+    type_ref = setting + '_type'
+    type_value = feature.get_feature(type_ref).get_value()
+    ret = ""
+    if type_value == '1':
+        app_ref = setting + '_app'
+        application = feature.get_feature(app_ref).get_value()
+        ret = application
+    elif type_value == '2':
+        url = feature.get_feature(setting+'_URL').get_value()
+        title = feature.get_feature(setting+'_title').get_value()
 
-		if title == None:
-			title = ""
-		else:
-			title = 'customtitle=' + title
-		
-		icon = feature.get_feature(setting + '_icon')
-		image_path = icon.get_feature('targetPath').get_value()
-		
-		icon_str = ""
-		
-		if image_path != None and image_path != "":
-			icon_str = 'iconmifpath='
-			if image_path.endswith('.mif'): index = '16384'
-			else:                           index = '0'
-			icon_str = icon_str + image_path + ';' + index + '&'
-			
-		ret = url + '?custom?' + icon_str + title
-	return ret
+        if title == None:
+            title = ""
+        else:
+            title = 'customtitle=' + title
+        
+        icon = feature.get_feature(setting + '_icon')
+        image_path = icon.get_feature('targetPath').get_value()
+        
+        icon_str = ""
+        
+        if image_path != None and image_path != "":
+            icon_str = 'iconmifpath='
+            if image_path.endswith('.mif'): index = '16384'
+            else:                           index = '0'
+            icon_str = icon_str + image_path + ';' + index + '&'
+            
+        ret = url + '?custom?' + icon_str + title
+    return ret
 
 #print get_shortcut_string('1', '2', '3')
 #http://www.nokia2.com?custom?iconmifpath=Z:\\resource\\apps\\icon2.mbm;1&amp;customtitle=Nokia2
--- a/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/__init__.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/__init__.py	Tue Aug 10 14:29:28 2010 +0300
@@ -13,24 +13,4 @@
 #
 # Description: 
 #
-import sys, os, unittest
 
-# Path to the directory where this file is located
-ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
-
-# Import common plug-in initialization
-PLUGINS_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../../../../..'))
-assert os.path.split(PLUGINS_ROOT)[1] == 'plugins'
-if PLUGINS_ROOT not in sys.path: sys.path.append(PLUGINS_ROOT)
-import plugin_utils
-
-plugin_utils.plugin_test_init(ROOT_PATH, '../../..')
-
-def collect_suite():
-    return plugin_utils.collect_test_suite_from_dir(ROOT_PATH)
-
-def runtests():
-    unittest.TextTestRunner(verbosity=2).run(collect_suite())
-
-if __name__ == '__main__':
-    runtests()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/base/confml/test_feature.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/1" name="Test feature" version="1">
+  <feature ref="TestFeature" name="Test feature">
+    <setting ref="BaseLayerSetting" name="Base layer setting" type="int"/>
+    <setting ref="Layer1Setting" name="Layer 1 setting" type="int"/>
+    <setting ref="Layer2Setting" name="Layer 2 setting" type="int"/>
+    <setting ref="Layer3Setting" name="Layer 3 setting" type="int"/>
+    <setting ref="Layer6Setting" name="Layer 6 setting" type="int"/>
+    <setting ref="EnableLayer7Content" name="Enable layer 7 content" type="boolean"/>
+    <setting ref="Layer8Setting" name="Layer 8 setting" type="int"/>
+    <setting ref="EnableLayer8Impl" name="Enable layer 8 implementation" type="boolean"/>
+    <setting ref="EnableLayer9Content" name="Enable layer 9 content" type="boolean"/>
+    <setting ref="EnableLayer11Content" name="Enable layer 11 content" type="boolean"/>
+  </feature>
+  <feature ref="content" name="Content related copy configuration">
+	<setting ref="inputfile" name="Content output file" type="string"/>
+    <setting ref="extinputfile" name="Content output file" type="string"/>
+	<setting ref="outputfile" name="Content output file" type="string"/>
+  </feature>
+  <data>
+    <TestFeature>
+      <BaseLayerSetting>0</BaseLayerSetting>
+      <Layer1Setting>0</Layer1Setting>
+      <Layer2Setting>0</Layer2Setting>
+      <Layer3Setting>0</Layer3Setting>
+      <Layer5Setting>0</Layer5Setting>
+      <Layer6Setting>0</Layer6Setting>
+      <EnableLayer7Content>true</EnableLayer7Content>
+      <Layer8Setting>0</Layer8Setting>
+      <!-- No data at all for EnableLayer8Impl. This is intentional, because it
+           caused problems earlier, and this is to make sure that there will
+           no regression -->
+      <!--<EnableLayer8Impl>false</EnableLayer8Impl>-->
+      <EnableLayer9Content>false</EnableLayer9Content>
+      <EnableLayer11Content>false</EnableLayer11Content>
+    </TestFeature>
+    <content>
+      <extinputfile>0</extinputfile>
+	  <inputfile>0</inputfile>
+	  <outputfile>0</outputfile>
+    </content>
+
+  </data>
+</configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/base/content/layer7/foo.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,1 @@
+Foo
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/base/content/layer9/bar.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,1 @@
+Bar
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/base/content/layer9/foo.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,1 @@
+Foo
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/base/implml/base.templateml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<templateml xmlns="http://www.s60.com/xml/templateml/1">
+    <output file="base.txt" encoding="UTF-8">
+        <template>Value: {{ feat_tree.TestFeature.BaseLayerSetting._value }}</template>
+    </output>
+</templateml>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/base/implml/layer1.templateml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<templateml xmlns="http://www.s60.com/xml/templateml/1">
+    <tag name="target" value="uda"/>
+    <output file="layer1.txt" encoding="UTF-8">
+        <template>Value: {{ feat_tree.TestFeature.Layer1Setting._value }}</template>
+    </output>
+</templateml>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/base/implml/layer10.content	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<content xmlns="http://www.s60.com/xml/content/2">
+    <tag name="target" value="uda"/>
+    <content xmlns="http://www.s60.com/xml/content/2">
+	  <output dir="content/layer10_output" flatten="true">
+	    <input file="layer10/foo.txt" />
+	  </output>
+	</content>
+</content>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/base/implml/layer11.implml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<container xmlns="http://www.symbianfoundation.org/xml/implml/1">
+    
+    <!-- This is the same as layer9.implml, except that this uses RuleML v3 -->
+    
+    <tag name="target" value="uda" />
+    <tempVariable ref="TempLayer11InputFiles" type="string"/>
+    
+    <container>
+        <ruleml xmlns="http://www.s60.com/xml/ruleml/3">
+            <rule>${TestFeature.EnableLayer11Content} configures ${TempLayer11InputFiles} = {% "layer9/foo.txt, layer9/bar.txt" %}</rule>
+        </ruleml>
+    </container>
+    
+    <content xmlns="http://www.s60.com/xml/content/2">
+        <output dir="sis" flatten="true">
+            <input>
+                <include files="${TempLayer11InputFiles}" />
+            </input>
+        </output>
+    </content>
+    
+</container>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/base/implml/layer2.templateml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<templateml xmlns="http://www.s60.com/xml/templateml/1">
+    <tag name="target" value="rofs2"/>
+    <output file="layer2.txt" encoding="UTF-8">
+        <template>Value: {{ feat_tree.TestFeature.Layer2Setting._value }}</template>
+    </output>
+</templateml>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/base/implml/layer3.templateml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<templateml xmlns="http://www.s60.com/xml/templateml/1">
+    <output file="layer3.txt" encoding="UTF-8">
+        <template>Value: {{ feat_tree.TestFeature.Layer3Setting._value }}</template>
+    </output>
+</templateml>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/base/implml/layer4.content	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<content xmlns="http://www.s60.com/xml/content/1">
+    <tag name="target" value="uda"/>
+    <input file="${content.outputfile}"/>
+    <output file="${content.inputfile}" someother="sss"/>
+</content>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/base/implml/layer5.content	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<content xmlns="http://www.s60.com/xml/content/2">
+    <tag name="target" value="rofs3"/>
+    <output dir="content/12345678" file="abcdef.txt">
+    	<externalinput dir="${content.extinputfile}">
+    		<include files="test.txt"/>
+    	</externalinput>
+    </output>
+</content>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/base/implml/layer6.implml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<container  xmlns="http://www.symbianfoundation.org/xml/implml/1">
+    <container>
+        <tag name="target" value="rofs3"/>
+        <templateml xmlns="http://www.s60.com/xml/templateml/1">
+            <output file="layer6.txt" encoding="UTF-8">
+                <template>Value: {{ feat_tree.TestFeature.Layer6Setting._value }}</template>
+            </output>
+        </templateml>
+    </container>
+    
+    <container>
+        <tag name="target" value="uda"/>
+        <templateml xmlns="http://www.s60.com/xml/templateml/1">
+            <output file="layer6.txt" encoding="UTF-8">
+                <template>Value: {{ feat_tree.TestFeature.Layer6Setting._value }}</template>
+            </output>
+        </templateml>
+    </container>
+</container>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/base/implml/layer7.implml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<container  xmlns="http://www.symbianfoundation.org/xml/implml/1"
+			condition="${TestFeature.EnableLayer7Content}">
+	<!-- The ContentML implementation has get_refs() == None, but the setting
+         triggering the condition has been changed -->
+    <tag name="target" value="uda" />
+	<content xmlns="http://www.s60.com/xml/content/2">
+	  <output dir="foo" flatten="true">
+	    <input file="layer7/foo.txt" />
+	  </output>
+	</content>
+</container>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/base/implml/layer8.implml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<container xmlns="http://www.symbianfoundation.org/xml/implml/1"
+           condition="${TestFeature.EnableLayer8Impl}">
+    <!-- The ref used in this implementation has been changed, but it should not
+         trigger layer_used(), because the condition evaluates to False -->
+	<templateml xmlns="http://www.s60.com/xml/templateml/1">
+        <tag name="target" value="uda"/>
+        <output file="layer8.txt" encoding="UTF-8">
+            <template>Value: {{ feat_tree.TestFeature.Layer8Setting._value }}</template>
+        </output>
+    </templateml>
+</container>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/base/implml/layer9.implml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<container xmlns="http://www.symbianfoundation.org/xml/implml/1">
+    
+    <tag name="target" value="uda" />
+    <tempVariable ref="TempLayer9InputFiles" type="string"/>
+    
+    <container>
+        <ruleml xmlns="http://www.s60.com/xml/ruleml/2"> 
+            <rule>TestFeature.EnableLayer9Content configures TempLayer9InputFiles = {% "layer9/foo.txt, layer9/bar.txt" %}</rule>
+        </ruleml>
+    </container>
+    
+    <content xmlns="http://www.s60.com/xml/content/2">
+        <output dir="sis" flatten="true">
+            <input>
+                <include files="${TempLayer9InputFiles}" />
+            </input>
+        </output>
+    </content>
+    
+</container>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/base/implml/uses_layers_test.ruleml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ruleml xmlns="http://www.s60.com/xml/ruleml/3">
+    <!-- This RuleML is used when running the integration test, it is not used in unit tests -->
+    <phase name="post"/>
+	<rule>{% check_uses_layer() %} configures "foo" = "baar"
+    </rule>
+    <eval_globals>
+import os
+
+from ruleplugin.evals import layer_utils
+
+def check_uses_layer():
+    results = [('Layer', 'Tag', 'Expected', 'Actual', 'Outcome')]
+    
+    def check(layer_index, tag, expected):
+        layer = ruleml.configuration.get_configuration_by_index(layer_index)
+        result = layer_utils.layers_used(ruleml.configuration, [layer], {'target' : [tag]})
+        
+        if result == expected:  outcome = "OK"
+        else:                   outcome = "FAIL"
+        
+        results.append((layer.get_path(), tag, expected, result, outcome))
+    
+    # BASE
+    check(layer_index = 0, tag = 'uda',   expected = True)
+    check(layer_index = 0, tag = 'rofs3', expected = True)
+    check(layer_index = 0, tag = 'rofs2', expected = True)
+    
+    # LAYER 1
+    check(layer_index = 1, tag = 'uda',   expected = True)
+    check(layer_index = 1, tag = 'rofs3', expected = False)
+    check(layer_index = 1, tag = 'rofs2', expected = False)
+    
+    # LAYER 2
+    check(layer_index = 2, tag = 'uda',   expected = False)
+    check(layer_index = 2, tag = 'rofs3', expected = False)
+    check(layer_index = 2, tag = 'rofs2', expected = True)
+    
+    # LAYER 3
+    check(layer_index = 3, tag = 'uda',   expected = False)
+    check(layer_index = 3, tag = 'rofs3', expected = False)
+    check(layer_index = 3, tag = 'rofs2', expected = False)
+    
+    # LAYER 4
+    check(layer_index = 4, tag = 'uda',   expected = True)
+    check(layer_index = 4, tag = 'rofs3', expected = False)
+    check(layer_index = 4, tag = 'rofs2', expected = False)
+    
+    # LAYER 5
+    check(layer_index = 5, tag = 'uda',   expected = False)
+    check(layer_index = 5, tag = 'rofs3', expected = True)
+    check(layer_index = 5, tag = 'rofs2', expected = False)
+    
+    # LAYER 6
+    check(layer_index = 6, tag = 'uda',   expected = True)
+    check(layer_index = 6, tag = 'rofs3', expected = True)
+    check(layer_index = 6, tag = 'rofs2', expected = False)
+    
+    # LAYER 7
+    check(layer_index = 7, tag = 'uda',   expected = True)
+    check(layer_index = 7, tag = 'rofs3', expected = False)
+    check(layer_index = 7, tag = 'rofs2', expected = False)
+    
+    # LAYER 8
+    check(layer_index = 8, tag = 'uda',   expected = False)
+    check(layer_index = 8, tag = 'rofs3', expected = False)
+    check(layer_index = 8, tag = 'rofs2', expected = False)
+    
+    # LAYER 9
+    check(layer_index = 9, tag = 'uda',   expected = True)
+    check(layer_index = 9, tag = 'rofs3', expected = False)
+    check(layer_index = 9, tag = 'rofs2', expected = False)
+    
+    # LAYER 10
+    check(layer_index = 10, tag = 'uda',   expected = True)
+    check(layer_index = 10, tag = 'rofs3', expected = False)
+    check(layer_index = 10, tag = 'rofs2', expected = False)
+    
+    # LAYER 11
+    check(layer_index = 11, tag = 'uda',   expected = True)
+    check(layer_index = 11, tag = 'rofs3', expected = False)
+    check(layer_index = 11, tag = 'rofs2', expected = False)
+    
+    # Write the results to output
+    f = open(os.path.join(ruleml.context.output, 'uses_layers_test.txt'),'w')
+    try:
+        # Column widths
+        layer_cw      = max([len(str(r[0])) for r in results]) + 2
+        tag_cw        = max([len(str(r[1])) for r in results]) + 2
+        expected_cw   = max([len(str(r[2])) for r in results])
+        actual_cw     = max([len(str(r[3])) for r in results]) + 2
+        
+        format = "%%-%ss %%-%ss %%-%ss %%-%ss %%s\n" % (layer_cw, tag_cw, expected_cw, actual_cw)
+        for r in results:
+            f.write(format % r)
+    finally:
+        f.close()
+    
+</eval_globals>
+</ruleml>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/base/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2 http://www.w3.org/2001/XInclude http://www.s60.com/xml/confml/1#//include">
+<xi:include href="confml/test_feature.confml" />
+</confml:configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/layer1/confml/data.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/2" name="data">
+  <data>
+    <TestFeature>
+      <Layer1Setting>1</Layer1Setting>
+    </TestFeature>
+  </data>
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/layer1/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="ASCII"?>
+<configuration xmlns="http://www.s60.com/xml/confml/1" xmlns:xi="http://www.w3.org/2001/XInclude" name="Layer 1">
+  <xi:include href="confml/data.confml"/>
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/layer10/confml/data.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/2" name="data">
+  <data>
+  </data>
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/layer10/content/layer10/foo.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,1 @@
+Foo
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/layer10/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="ASCII"?>
+<configuration xmlns="http://www.s60.com/xml/confml/1" xmlns:xi="http://www.w3.org/2001/XInclude" name="Layer 10">
+  <xi:include href="confml/data.confml"/>
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/layer11/confml/data.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/2" name="data">
+  <data>
+    <TestFeature>
+      <EnableLayer11Content>true</EnableLayer11Content>
+    </TestFeature>
+  </data>
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/layer11/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="ASCII"?>
+<configuration xmlns="http://www.s60.com/xml/confml/1" xmlns:xi="http://www.w3.org/2001/XInclude" name="Layer 11">
+  <xi:include href="confml/data.confml"/>
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/layer2/confml/data.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/2" name="data">
+  <data>
+    <TestFeature>
+      <Layer2Setting>2</Layer2Setting>
+    </TestFeature>
+  </data>
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/layer2/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="ASCII"?>
+<configuration xmlns="http://www.s60.com/xml/confml/1" xmlns:xi="http://www.w3.org/2001/XInclude" name="Layer 2">
+  <xi:include href="confml/data.confml"/>
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/layer3/confml/data.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/2" name="data">
+  <data>
+    <TestFeature>
+      <Layer3Setting>2</Layer3Setting>
+    </TestFeature>
+  </data>
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/layer3/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="ASCII"?>
+<configuration xmlns="http://www.s60.com/xml/confml/1" xmlns:xi="http://www.w3.org/2001/XInclude" name="Layer 3">
+  <xi:include href="confml/data.confml"/>
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/layer4/confml/data.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/2" name="data">
+  <data>
+    <content>
+	  <inputfile>test_input.txt</inputfile>
+	  <outputfile>test_output.txt</outputfile>
+    </content>
+  </data>
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/layer4/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="ASCII"?>
+<configuration xmlns="http://www.s60.com/xml/confml/1" xmlns:xi="http://www.w3.org/2001/XInclude" name="Layer 3">
+  <xi:include href="confml/data.confml"/>
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/layer5/confml/data.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/2" name="data">
+  <data>
+    <content>
+	  <extinputfile>test_extinput.txt</extinputfile>
+    </content>
+  </data>
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/layer5/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="ASCII"?>
+<configuration xmlns="http://www.s60.com/xml/confml/1" xmlns:xi="http://www.w3.org/2001/XInclude" name="Layer 3">
+  <xi:include href="confml/data.confml"/>
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/layer6/confml/data.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/2" name="data">
+  <data>
+    <TestFeature>
+      <Layer6Setting>6</Layer6Setting>
+    </TestFeature>
+  </data>
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/layer6/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="ASCII"?>
+<configuration xmlns="http://www.s60.com/xml/confml/1" xmlns:xi="http://www.w3.org/2001/XInclude" name="Layer 6">
+  <xi:include href="confml/data.confml"/>
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/layer7/confml/data.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/2" name="data">
+  <data>
+    <TestFeature>
+      <EnableLayer7Content>true</EnableLayer7Content>
+    </TestFeature>
+  </data>
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/layer7/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="ASCII"?>
+<configuration xmlns="http://www.s60.com/xml/confml/1" xmlns:xi="http://www.w3.org/2001/XInclude" name="Layer 7">
+  <xi:include href="confml/data.confml"/>
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/layer8/confml/data.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/2" name="data">
+  <data>
+    <TestFeature>
+      <Layer8Setting>8</Layer8Setting>
+    </TestFeature>
+  </data>
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/layer8/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="ASCII"?>
+<configuration xmlns="http://www.s60.com/xml/confml/1" xmlns:xi="http://www.w3.org/2001/XInclude" name="Layer 8">
+  <xi:include href="confml/data.confml"/>
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/layer9/confml/data.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/2" name="data">
+  <data>
+    <TestFeature>
+      <EnableLayer9Content>true</EnableLayer9Content>
+    </TestFeature>
+  </data>
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/assets/layer9/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="ASCII"?>
+<configuration xmlns="http://www.s60.com/xml/confml/1" xmlns:xi="http://www.w3.org/2001/XInclude" name="Layer 9">
+  <xi:include href="confml/data.confml"/>
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="ASCII"?>
+<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2 http://www.w3.org/2001/XInclude http://www.s60.com/xml/confml/1#//include">
+  <xi:include href="assets/base/root.confml"/>
+  <xi:include href="assets/layer1/root.confml"/>
+  <xi:include href="assets/layer2/root.confml"/>
+  <xi:include href="assets/layer3/root.confml"/>
+  <xi:include href="assets/layer4/root.confml"/>
+  <xi:include href="assets/layer5/root.confml"/>
+  <xi:include href="assets/layer6/root.confml"/>
+  <xi:include href="assets/layer7/root.confml"/>
+  <xi:include href="assets/layer8/root.confml"/>
+  <xi:include href="assets/layer9/root.confml"/>
+  <xi:include href="assets/layer10/root.confml"/>
+  <xi:include href="assets/layer11/root.confml"/>
+</confml:configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layerproject/foo/bar/customer/custvariant_123_xyz/configurator/confml/test.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration name="testdata" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
+	<data>
+		<TestFeature>
+            <CustvariantConfigurator>false</CustvariantConfigurator>
+		</TestFeature>
+	</data>
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layerproject/foo/bar/customer/custvariant_123_xyz/configurator/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,3 @@
+<configuration name="testdata" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
+  <xi:include href="confml/test.confml" />
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layerproject/foo/bar/customer/custvariant_123_xyz/manual/confml/test.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration name="testdata" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
+	<data>
+		<TestFeature>
+			<CustvariantManual>false</CustvariantManual>
+		</TestFeature>
+	</data>
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layerproject/foo/bar/customer/custvariant_123_xyz/manual/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,3 @@
+<configuration name="testdata" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
+  <xi:include href="confml/test.confml" />
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layerproject/foo/bar/rnd/confml/test.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration name="testdata" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
+	<data>
+		<TestFeature>
+            <Rnd>false</Rnd>
+        </TestFeature>
+	</data>
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layerproject/foo/bar/rnd/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,3 @@
+<configuration name="testdata" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
+  <xi:include href="confml/test.confml" />
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layerproject/foobar_root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,10 @@
+<configuration name="layer_utils" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
+  <xi:include href="layer1/root.confml" />
+  <xi:include href="layer2/root.confml" />
+  <xi:include href="layer3/root.confml" />
+  <xi:include href="layer4/root.confml" />
+  <xi:include href="layer5/root.confml" />
+  <xi:include href="foo/bar/customer/custvariant_123_xyz/manual/root.confml" />
+  <xi:include href="foo/bar/customer/custvariant_123_xyz/configurator/root.confml" />
+  <xi:include href="foo/bar/rnd/root.confml" />
+</configuration>
\ No newline at end of file
--- a/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layerproject/layer1/confml/test.confml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/layerproject/layer1/confml/test.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -1,12 +1,22 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <configuration name="testdata" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
-	<feature name="String feature" ref="StringFeatureTest">
-		<setting name="Value 1" ref="Value1" type="string" />
-		<setting name="Value 2" ref="Value2" type="string" />
-	</feature>
-	<data>
-		<StringFeatureTest>
-			<Value1>String 1</Value1>
-		</StringFeatureTest>
-	</data>
+    <feature name="String feature" ref="StringFeatureTest">
+        <setting name="Value 1" ref="Value1" type="string" />
+        <setting name="Value 2" ref="Value2" type="string" />
+    </feature>
+    <feature name="Test feature" ref="TestFeature">
+        <setting name="Custvariant manual" ref="CustvariantManual" type="boolean"/>
+        <setting name="Custvariant configurator" ref="CustvariantConfigurator" type="boolean"/>
+        <setting name="RnD" ref="Rnd" type="boolean"/>
+    </feature>
+    <data>
+        <StringFeatureTest>
+            <Value1>String 1</Value1>
+        </StringFeatureTest>
+        <TestFeature>
+            <CustvariantManual>false</CustvariantManual>
+            <CustvariantConfigurator>false</CustvariantConfigurator>
+            <Rnd>false</Rnd>
+        </TestFeature>
+    </data>
 </configuration>
\ No newline at end of file
Binary file configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/ruleproject/layer2/confml/data.confml has changed
--- a/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/runtests.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/runtests.py	Tue Aug 10 14:29:28 2010 +0300
@@ -14,6 +14,6 @@
 # Description: 
 #
 
-import __init__
-
-__init__.runtests()
+if __name__ == '__main__':
+    import nose
+    nose.core.run(argv=['collector','--include=unittest', '--verbosity=3'])
--- a/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/unittest_accesspoint_id_counter.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/unittest_accesspoint_id_counter.py	Tue Aug 10 14:29:28 2010 +0300
@@ -15,15 +15,9 @@
 #
 
 import unittest
-import os, shutil
-import sys
-import pkg_resources
-import re
+import os
 
-import __init__
-
-from ruleplugin import ruleml, relations
-from cone.public import api, exceptions
+from cone.public import api
 from ruleplugin.evals import accesspoint_id_counter
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
 
@@ -33,29 +27,32 @@
         config = project.get_configuration('root.confml')
         dview = config.get_default_view()
         
-        container = accesspoint_id_counter._get_ApDnContainer_(dview.get_feature("APs"), dview.get_feature("DNs"), True)
+        container = accesspoint_id_counter._get_ApDnContainer_(dview.get_feature("WLAN_APs"), dview.get_feature("APs"), dview.get_feature("DNs"))
         
         self.assertEquals('Internet', container.get_all_dns()[0].get_name())
         self.assertEquals('1', container.get_all_dns()[0].get_id())
-        self.assertEquals(['IAP11', 'IAP12', 'IAP13', None, None, None, None, None, None, None], container.get_all_dns()[0].get_iaps())
+        self.assertEquals(['IAP11', 'IAP12', 'IAP13', 'WIAP16', None, None, None, None, None, None], 
+         container.get_all_dns()[0].get_iaps())
         
         self.assertEquals('MMS', container.get_all_dns()[1].get_name())
         self.assertEquals('2', container.get_all_dns()[1].get_id())
-        self.assertEquals(['IAP21', 'IAP22', 'IAP23', 'IAP13', None, None, None, None, None, None], container.get_all_dns()[1].get_iaps())
+        self.assertEquals(['IAP21', 'IAP22', 'IAP23', None, None, None, None, None, None, None], 
+         container.get_all_dns()[1].get_iaps())
         
         self.assertEquals('Operator', container.get_all_dns()[2].get_name())
         self.assertEquals('3', container.get_all_dns()[2].get_id())
-        self.assertEquals(['IAP31', 'IAP32', 'IAP33', None, None, None, None, None, None, None], container.get_all_dns()[2].get_iaps())
+        self.assertEquals(['IAP31', 'IAP32', 'IAP33', None, None, None, None, None, None, None],
+         container.get_all_dns()[2].get_iaps())
 
-        self.assertEquals('IAP11', container.get_all_aps()[0].get_name())
-        self.assertEquals('1', container.get_all_aps()[0].get_id())
+        self.assertEquals('WIAP16', container.get_all_aps()[0].get_name())
+        self.assertEquals('5', container.get_all_aps()[0].get_id())
         
     def test_get_apid_by_apname(self):
         project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'ruleproject')))
         config = project.get_configuration('root.confml')
         dview = config.get_default_view()
         
-        container = accesspoint_id_counter._get_ApDnContainer_(dview.get_feature("APs"), dview.get_feature("DNs"), True)
+        container = accesspoint_id_counter._get_ApDnContainer_(dview.get_feature("WLAN_APs"), dview.get_feature("APs"), dview.get_feature("DNs"))
         
         self.assertEquals('1', container.get_apid_by_apname('IAP11'))
         self.assertEquals('2', container.get_apid_by_apname('IAP12'))
@@ -66,7 +63,7 @@
         config = project.get_configuration('root.confml')
         dview = config.get_default_view()
         
-        container = accesspoint_id_counter._get_ApDnContainer_(dview.get_feature("APs"), dview.get_feature("DNs"), True)
+        container = accesspoint_id_counter._get_ApDnContainer_(dview.get_feature("WLAN_APs"), dview.get_feature("APs"), dview.get_feature("DNs"))
         
         self.assertEquals('1', container.get_dnid_by_dnname('Internet'))
         self.assertEquals('2', container.get_dnid_by_dnname('MMS'))
@@ -78,7 +75,7 @@
         config = project.get_configuration('root.confml')
         dview = config.get_default_view()
         
-        container = accesspoint_id_counter._get_ApDnContainer_(dview.get_feature("APs"), dview.get_feature("DNs"), True)
+        container = accesspoint_id_counter._get_ApDnContainer_(dview.get_feature("WLAN_APs"), dview.get_feature("APs"), dview.get_feature("DNs"))
         
         self.assertEquals('2', container.get_apid_by_dnname_and_apname('Internet', 'IAP12'))
 
@@ -87,25 +84,40 @@
         config = project.get_configuration('root.confml')
         dview = config.get_default_view()
         
-        container = accesspoint_id_counter._get_ApDnContainer_(dview.get_feature("APs"), dview.get_feature("DNs"), True)
-
-        self.assertEquals('9', container.get_all_aps()[6].get_id())
+        container = accesspoint_id_counter._get_ApDnContainer_(dview.get_feature("WLAN_APs"), dview.get_feature("APs"), dview.get_feature("DNs"))
+        
+        self.assertEquals('6', container.get_all_aps()[6].get_id())
+        self.assertEquals('5', container.get_all_aps()[0].get_id())
 
     def test_all_in_array(self):
         project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'ruleproject')))
         config = project.get_configuration('root.confml')
         dview = config.get_default_view()
         
-        container = accesspoint_id_counter._get_ApDnContainer_(dview.get_feature("APs"), dview.get_feature("DNs"), True)
+        container = accesspoint_id_counter._get_ApDnContainer_(dview.get_feature("WLAN_APs"), dview.get_feature("APs"), dview.get_feature("DNs"))
 
-        self.assertEquals(container.get_all_in_array(), [['Internet', '1', ['IAP11', 'IAP12', 'IAP13', None, None, None, None, None, None, None], ['1', '2', '7', None, None, None, None, None, None, None], ['1', '2', '3', None, None, None, None, None, None, None]], ['MMS', '2', ['IAP21', 'IAP22', 'IAP23', 'IAP13', None, None, None, None, None, None], ['4', '8', '6', '7', None, None, None, None, None, None], ['4', '5', '6', '3', None, None, None, None, None, None]], ['Operator', '3', ['IAP31', 'IAP32', 'IAP33', None, None, None, None, None, None, None], [None, None, '9', None, None, None, None, None, None, None], [None, None, '7', None, None, None, None, None, None, None]]])
+        self.assertEquals(container.get_all_in_array(), 
+            [
+             ['Internet', '1', 
+              ['IAP11', 'IAP12', 'IAP13', 'WIAP16', None, None, None, None, None, None], 
+              ['1', '2', '7', '5', None, None, None, None, None, None], 
+              ['1', '2', '3', '4', None, None, None, None, None, None]], 
+             ['MMS', '2', 
+              ['IAP21', 'IAP22', 'IAP23', None, None, None, None, None, None, None], 
+              ['4', '8', '6', None, None, None, None, None, None, None], 
+              ['5', '6', '7', None, None, None, None, None, None, None]], 
+             ['Operator', '3', 
+              ['IAP31', 'IAP32', 'IAP33', None, None, None, None, None, None, None], 
+              [None, None, '9', None, None, None, None, None, None, None], 
+              [None, None, '8', None, None, None, None, None, None, None]]
+             ]
+            )
 
     def test_get_next_free_id(self):
         project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'ruleproject')))
         config = project.get_configuration('root.confml')
         dview = config.get_default_view()
-        
-        container = accesspoint_id_counter._get_ApDnContainer_(dview.get_feature("APs"), dview.get_feature("DNs"), True)
+        container = accesspoint_id_counter._get_ApDnContainer_(dview.get_feature("WLAN_APs"), dview.get_feature("APs"), dview.get_feature("DNs"))
         
         self.assertEquals("4", accesspoint_id_counter._get_next_free_id_(container.get_all_dns()))
         self.assertEquals("10", accesspoint_id_counter._get_next_free_id_(container.get_all_aps()))
@@ -115,9 +127,9 @@
         config = project.get_configuration('root.confml')
         dview = config.get_default_view()
         
-        container = accesspoint_id_counter._get_ApDnContainer_(dview.get_feature("APs"), dview.get_feature("DNs"), True)
+        container = accesspoint_id_counter._get_ApDnContainer_(dview.get_feature("WLAN_APs"), dview.get_feature("APs"), dview.get_feature("DNs"))
         
-        self.assertEquals("4", container.get_apindex_by_apname("IAP21"))
+        self.assertEquals("5", container.get_apindex_by_apname("IAP21"))
         self.assertEquals("1", container.get_apindex_by_apname("IAP11"))
 
         
--- a/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/unittest_layer_utils.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/evals/tests/unittest_layer_utils.py	Tue Aug 10 14:29:28 2010 +0300
@@ -15,16 +15,9 @@
 #
 
 import unittest
-import os, shutil
-import sys
-import pkg_resources
-import re
-import logging
+import os
 
-import __init__
-
-from ruleplugin import ruleml, relations
-from cone.public import api, exceptions
+from cone.public import api
 from ruleplugin.evals import layer_utils
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
 
@@ -86,7 +79,163 @@
         self.assertFalse(layer_utils.changed_on_layers(dview.get_feature("StringFeatureTest.Value1"),8,9))
         self.assertFalse(layer_utils.changed_on_layers(dview.get_feature("StringFeatureTest.Value2"),0,1))
         self.assertTrue(layer_utils.changed_on_layers(dview.get_feature("StringFeatureTest.Value2"),1,5))
+        
+        self.assertFalse(layer_utils.changed_on_layers(dview.get_feature("StringFeatureTest.Value2"),3,5))
+        self.assertFalse(layer_utils.changed_on_layers(dview.get_feature("StringFeatureTest.Value2"),5,3))
+        self.assertFalse(layer_utils.changed_on_layers(dview.get_feature("StringFeatureTest.Value2"),-2,-1))
+        self.assertFalse(layer_utils.changed_on_layers(dview.get_feature("StringFeatureTest.Value2"),-1,-2))
+        
+        self.assertTrue(layer_utils.changed_on_layers(dview.get_feature("StringFeatureTest.Value2"),2,5))
+        self.assertTrue(layer_utils.changed_on_layers(dview.get_feature("StringFeatureTest.Value2"),5,2))
+        self.assertTrue(layer_utils.changed_on_layers(dview.get_feature("StringFeatureTest.Value2"),-3,-1))
+        self.assertTrue(layer_utils.changed_on_layers(dview.get_feature("StringFeatureTest.Value2"),-1,-3))
+        
+        self.assertFalse(layer_utils.changed_on_layers(dview.get_feature("StringFeatureTest.Value2"),3,1000))
+        self.assertFalse(layer_utils.changed_on_layers(dview.get_feature("StringFeatureTest.Value2"),-1000,1))
+        self.assertTrue(layer_utils.changed_on_layers(dview.get_feature("StringFeatureTest.Value2"),-1000,1000))
 
+    def test_layers_used_single_layer(self):
+        project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'layer_filtering_project')))
+        root_config = project.get_configuration('root.confml')
         
+        layer_base_config = root_config.get_configuration_by_index(0)
+        layer1_config = root_config.get_configuration_by_index(1)
+        layer2_config = root_config.get_configuration_by_index(2)
+        layer3_config = root_config.get_configuration_by_index(3)
+        layer4_config = root_config.get_configuration_by_index(4)
+        layer5_config = root_config.get_configuration_by_index(5)
+        layer6_config = root_config.get_configuration_by_index(6)
+        layer7_config = root_config.get_configuration_by_index(7)
+        layer8_config = root_config.get_configuration_by_index(8)
+        layer9_config = root_config.get_configuration_by_index(9)
+        layer10_config = root_config.get_configuration_by_index(10)
+        layer11_config = root_config.get_configuration_by_index(11)
+        
+        self.assertTrue(layer_utils.layers_used(root_config, [root_config], {'target' : ['uda']}))
+        self.assertTrue(layer_utils.layers_used(root_config, [root_config], {'target' : ['rofs2']}))
+        
+        self.assertTrue( layer_utils.layers_used(root_config, [layer_base_config], {'target' : ['uda']}))
+        self.assertTrue( layer_utils.layers_used(root_config, [layer1_config], {'target' : ['uda']}))
+        self.assertFalse(layer_utils.layers_used(root_config, [layer2_config], {'target' : ['uda']}))
+        self.assertFalse(layer_utils.layers_used(root_config, [layer3_config], {'target' : ['uda']}))
+        self.assertTrue( layer_utils.layers_used(root_config, [layer4_config], {'target' : ['uda']}))
+        self.assertFalse(layer_utils.layers_used(root_config, [layer5_config], {'target' : ['uda']}))
+
+        self.assertTrue( layer_utils.layers_used(root_config, [layer_base_config], {'target' : ['rofs2']}))
+        self.assertFalse(layer_utils.layers_used(root_config, [layer1_config], {'target' : ['rofs2']}))
+        self.assertTrue( layer_utils.layers_used(root_config, [layer2_config], {'target' : ['rofs2']}))
+        self.assertFalse(layer_utils.layers_used(root_config, [layer3_config], {'target' : ['rofs2']}))
+        
+        self.assertTrue( layer_utils.layers_used(root_config, [layer5_config], {'target' : ['rofs3']}))
+        self.assertFalse(layer_utils.layers_used(root_config, [layer5_config], {'target' : ['uda']}))
+        
+        self.assertFalse(layer_utils.layers_used(root_config, [layer6_config], {'target' : ['rofs2']}))
+        self.assertTrue( layer_utils.layers_used(root_config, [layer6_config], {'target' : ['rofs3']}))
+        self.assertTrue( layer_utils.layers_used(root_config, [layer6_config], {'target' : ['uda']}))
+        
+        self.assertFalse(layer_utils.layers_used(root_config, [layer7_config], {'target' : ['rofs3']}))
+        self.assertTrue( layer_utils.layers_used(root_config, [layer7_config], {'target' : ['uda']}))
+        
+        self.assertFalse(layer_utils.layers_used(root_config, [layer8_config], {'target' : ['rofs3']}))
+        self.assertFalse(layer_utils.layers_used(root_config, [layer8_config], {'target' : ['uda']}))
+        
+        self.assertFalse(layer_utils.layers_used(root_config, [layer9_config], {'target' : ['rofs3']}))
+        self.assertTrue( layer_utils.layers_used(root_config, [layer9_config], {'target' : ['uda']}))
+        
+        self.assertFalse(layer_utils.layers_used(root_config, [layer10_config], {'target' : ['rofs3']}))
+        self.assertTrue( layer_utils.layers_used(root_config, [layer10_config], {'target' : ['uda']}))
+        
+        self.assertFalse(layer_utils.layers_used(root_config, [layer11_config], {'target' : ['rofs3']}))
+        self.assertTrue( layer_utils.layers_used(root_config, [layer11_config], {'target' : ['uda']}))
+
+    def test_layers_used_regex(self):
+        project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'layer_filtering_project')))
+        root_config = project.get_configuration('root.confml')
+        
+        self.assertTrue(layer_utils.layers_used(root_config, r'/base/', {'target' : ['uda']}))
+        self.assertTrue(layer_utils.layers_used(root_config, r'/base/', {'target' : ['rofs2']}))
+        
+        self.assertTrue( layer_utils.layers_used(root_config, r'/base/', {'target' : ['uda']}))
+        self.assertTrue( layer_utils.layers_used(root_config, r'/layer1/', {'target' : ['uda']}))
+        self.assertFalse(layer_utils.layers_used(root_config, r'/layer2/', {'target' : ['uda']}))
+        self.assertFalse(layer_utils.layers_used(root_config, r'/layer3/', {'target' : ['uda']}))
+        self.assertTrue( layer_utils.layers_used(root_config, r'/layer4/', {'target' : ['uda']}))
+        self.assertFalse(layer_utils.layers_used(root_config, r'/layer5/', {'target' : ['uda']}))
+
+        self.assertTrue( layer_utils.layers_used(root_config, r'/base/', {'target' : ['rofs2']}))
+        self.assertFalse(layer_utils.layers_used(root_config, r'/layer1/', {'target' : ['rofs2']}))
+        self.assertTrue( layer_utils.layers_used(root_config, r'/layer2/', {'target' : ['rofs2']}))
+        self.assertFalse(layer_utils.layers_used(root_config, r'/layer3/', {'target' : ['rofs2']}))
+
+        self.assertTrue( layer_utils.layers_used(root_config, r'/layer5/', {'target' : ['rofs3']}))
+        self.assertFalse(layer_utils.layers_used(root_config, r'/layer5/', {'target' : ['uda']}))
+        
+        self.assertFalse(layer_utils.layers_used(root_config, r'/layer6/', {'target' : ['rofs2']}))
+        self.assertTrue( layer_utils.layers_used(root_config, r'/layer6/', {'target' : ['rofs3']}))
+        self.assertTrue( layer_utils.layers_used(root_config, r'/layer6/', {'target' : ['uda']}))
+        
+        self.assertFalse(layer_utils.layers_used(root_config, r'/layer7/', {'target' : ['rofs3']}))
+        self.assertTrue( layer_utils.layers_used(root_config, r'/layer7/', {'target' : ['uda']}))
+        
+        self.assertFalse(layer_utils.layers_used(root_config, r'/layer8/', {'target' : ['rofs3']}))
+        self.assertFalse(layer_utils.layers_used(root_config, r'/layer8/', {'target' : ['uda']}))
+        
+        self.assertFalse(layer_utils.layers_used(root_config, r'/layer9/', {'target' : ['rofs3']}))
+        self.assertTrue( layer_utils.layers_used(root_config, r'/layer9/', {'target' : ['uda']}))
+        
+        self.assertFalse(layer_utils.layers_used(root_config, r'/layer10/', {'target' : ['rofs3']}))
+        self.assertTrue( layer_utils.layers_used(root_config, r'/layer10/', {'target' : ['uda']}))
+    
+    def test_changed_on_layers_regex(self):
+        project = api.Project(api.Storage.open(os.path.join(ROOT_PATH, 'layerproject')))
+        config = project.get_configuration('foobar_root.confml')
+        dview = config.get_default_view()
+        
+        def check(regex, feature, expected):
+            self.assertEquals(layer_utils.changed_on_layers_regex(dview.get_feature(feature), regex),
+                              expected)
+        
+        check(r'.*', 'TestFeature.CustvariantManual', True)
+        
+        regex = r'/custvariant(_.*)?/manual/'
+        check(regex, 'TestFeature.CustvariantManual', True)
+        check(regex, 'TestFeature.CustvariantConfigurator', False)
+        check(regex, 'TestFeature.Rnd', False)
+        
+        regex = r'/custvariant(_.*)?/configurator/'
+        check(regex, 'TestFeature.CustvariantManual', False)
+        check(regex, 'TestFeature.CustvariantConfigurator', True)
+        check(regex, 'TestFeature.Rnd', False)
+        
+        regex = r'/custvariant(_.*)?/'
+        check(regex, 'TestFeature.CustvariantManual', True)
+        check(regex, 'TestFeature.CustvariantConfigurator', True)
+        check(regex, 'TestFeature.Rnd', False)
+        
+        regex = r'foo/bar/'
+        check(regex, 'StringFeatureTest.Value1', False)
+        check(regex, 'TestFeature.CustvariantManual', True)
+        check(regex, 'TestFeature.CustvariantConfigurator', True)
+        check(regex, 'TestFeature.Rnd', True)
+        
+        regex = r'/rnd/'
+        check(regex, 'TestFeature.CustvariantManual', False)
+        check(regex, 'TestFeature.CustvariantConfigurator', False)
+        check(regex, 'TestFeature.Rnd', True)
+    
+    def test_changed_on_custvariant_layer(self):
+        project = api.Project(api.Storage.open(os.path.join(ROOT_PATH, 'layerproject')))
+        config = project.get_configuration('foobar_root.confml')
+        dview = config.get_default_view()
+        
+        def check(feature, expected):
+            self.assertEquals(layer_utils.changed_on_custvariant_layer(dview.get_feature(feature)),
+                              expected)
+        check('StringFeatureTest.Value1', False)
+        check('StringFeatureTest.Value2', False)
+        check('TestFeature.CustvariantManual', True)
+        check('TestFeature.CustvariantConfigurator', True)
+        check('TestFeature.Rnd', False)
+
 if __name__ == "__main__":
     unittest.main()
--- a/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/relations.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/relations.py	Tue Aug 10 14:29:28 2010 +0300
@@ -40,13 +40,13 @@
             raise exceptions.NotSupportedException("No Relation class found for name %s" % relation_name)
 
     @ classmethod
-    def get_relations(cls, configuration, relation):
+    def get_relations(cls, relation):
         try:
             relations = []
             (left_expression,relation_name,right_expression) = parse_rule(relation)
-            relation = cls.get_relation_by_name(relation_name)(configuration, left_expression, right_expression)
+            relation = cls.get_relation_by_name(relation_name)(left_expression, right_expression)
             relations.append(relation)
-            propagated_relations = cls.get_relations(configuration, right_expression)
+            propagated_relations = cls.get_relations(right_expression)
             if propagated_relations:
                 for relation in propagated_relations:
                     relations.append(relation)
@@ -55,86 +55,32 @@
             return None
     
 
-class ConfigurationContext(rules.DefaultContext):
-    
-    def __init__(self, data):
-        rules.DefaultContext.__init__(self, data)
-        
-        # A note on the callback variables that follow:
-        # in order to collect rule execution results for the
-        # generation report, a callback system is implemented in
-        # ConfigurationContext.  It all boils down to ConfigureRelation
-        # using configure_expression_result_callback to catch the result
-        # in its execute() method. The ConfigurationContext just works as
-        # a "callback hub" because a reference to the context is available
-        # in all expression evaluations.
-        
-        # Callback called with a plugin.RelationExecutionResult object
-        # when a ConfigureExpression has been evaluated
-        self.configure_expression_result_callback = None
-        
-        # Callback called with the setting reference when a setting is dereferenced
-        # as a terminal expression
-        self.ref_terminal_callback = None
-        
-        # Callback called with the setting reference when a setting is dereferenced
-        # inside an EvalExpression
-        self.ref_eval_callback = None
-        
-        # Callback called with the setting reference when the value of a setting
-        # is set inside a SetExpression
-        self.ref_set_callback = None
-        
-    def handle_terminal(self, expression):
-        try:
-            value = self.data.get_default_view().get_feature(expression).get_value()
-            
-            # Got a valid ref, call the callback
-            if self.ref_terminal_callback:
-                self.ref_terminal_callback(expression)
-            
-            return value
-        except exceptions.NotFound,e:
-            """ return the expression itself if it is not a fearef """
-            #print "handle_terminal constant %s" % (expression)
-            try:
-                return eval(expression)
-            except (NameError,SyntaxError), e:
-                return expression
-
-    def eval(self, ast, expression, value):
-        #print "expression %s = %s" % (expression,value)
-        pass
-        
 class ConfigurationBaseRelation(rules.BaseRelation):
-    def __init__(self, data, left, right):
-        self.context = ConfigurationContext(data)
-        super(ConfigurationBaseRelation, self).__init__(data, left, right)
+    def __init__(self, left, right):
+        super(ConfigurationBaseRelation, self).__init__(None, left, right)
+        self.context = None
 
 class RequireRelation(ConfigurationBaseRelation):
     KEY = 'requires'
-    def __init__(self, data, left, right):
-        super(RequireRelation, self).__init__(data, left, right)
-        self.context = ConfigurationContext(data)
+    relation_name = 'requires'
+    def __init__(self, left, right):
+        super(RequireRelation, self).__init__(left, right)
 
 class ConfigureRelation(ConfigurationBaseRelation):
     KEY = 'configures'
-    def __init__(self, data, left, right):
-        self.context = ConfigurationContext(data)
-        super(ConfigureRelation, self).__init__(data, left, right)
+    relation_name = 'configures'
+    def __init__(self, left, right):
+        super(ConfigureRelation, self).__init__(left, right)
         
         # A plugin.RelationExecutionResult object is stored here
         self._execution_result = None
         
     
-    def execute(self):
+    def execute(self, context):
         self._execution_result = None
         exec_results = []
         
-        # Call BaseRelation.execute() and catch any ConfigureExpression result objects
-        self.context.configure_expression_result_callback = lambda result: exec_results.append(result)
-        result = rules.BaseRelation.execute(self)
-        self.context.configure_expression_result_callback = None
+        result = rules.BaseRelation.execute(self, context)
         
         if len(exec_results) > 0:
             # There should be only one ConfigureExpression inside a ConfigureRelation
@@ -157,9 +103,6 @@
         return True
     return False
 
-def handle_set(self, left, right):
-    left.set_value(right)
-
 def handle_filenamejoin(self, left, right):
     def extract_dirname(path):
         """Extract directory name (will always contain a trailing slash or backslash)"""
@@ -174,44 +117,21 @@
     
     return extract_dirname(left) + extract_filename(right)
 
-def handle_plus(self, left, right):
-    return left + right
-
-def handle_minus(self, left, right):
-    return left - right
-
-def handle_multiply(self, left, right):
-    return left * right
-
-def handle_divide(self, left, right):
-    return left / right
 
 class ConfigureExpression(rules.TwoOperatorExpression):
     PRECEDENCE = rules.PRECEDENCES['RELATION_OPERATORS']
     KEY = 'configures'
     OP = handle_configure
 
-    def eval(self, context):
+    def eval(self, context, **kwargs):
         input_refs = []
         affected_refs = []
         
-        # Evaluate the left-hand side expression, catching refs for the result
-        try:
-            context.ref_terminal_callback = lambda ref: input_refs.append(ref)
-            context.ref_eval_callback = lambda ref: input_refs.append(ref)
-            evaluated_left = self.left.eval(context)
-        finally:
-            context.ref_terminal_callback = None
-            context.ref_eval_callback = None
-        
+        # Evaluate the left-hand side expression
+        evaluated_left = self.left.eval(context, **kwargs)
         if evaluated_left:
-            # If left evaluated to True, evaluate the right-hand side and
-            # catch refs from SetExpression evaluations
-            try:
-                context.ref_set_callback = lambda ref: affected_refs.append(ref)
-                self.value = self.right.eval(context)
-            finally:
-                context.ref_set_callback = None
+            # If left evaluated to True, evaluate the right-hand side
+            self.value = self.right.eval(context, **kwargs)
         else:
             self.value = True
         
@@ -220,53 +140,20 @@
             for ref in self.ast.extract_refs(str(self.left)):
                 for key in context.get_keys(ref):
                     left_keys.append(key)
-
             for key in left_keys:
                 self.ast.add_error(key, { 'error_string' : 'CONFIGURES right side value is "False"',
                                           'left_key' : key,
                                           'rule' : self.ast.expression
                                           })
-        
-        # Return a RelationExecutionResult if necessary
-        if input_refs or affected_refs:
-            if context.configure_expression_result_callback:
-                result = plugin.RelationExecutionResult(utils.distinct_array(input_refs),
-                                                        utils.distinct_array(affected_refs))
-                context.configure_expression_result_callback(result)
-                
         return self.value
 
-class MultiplyExpression(rules.TwoOperatorExpression):
-    expression = "multiply_operation"
-    PRECEDENCE = rules.PRECEDENCES['MULDIV_OPERATORS']
-    KEY= '*'
-    OP = handle_multiply
-
-class DivideExpression(rules.TwoOperatorExpression):
-    expression = "divide_operation"
-    PRECEDENCE = rules.PRECEDENCES['MULDIV_OPERATORS']
-    KEY= '/'
-    OP = handle_divide
-
-class PlusExpression(rules.TwoOperatorExpression):
-    expression = "plus_operation"
-    PRECEDENCE = rules.PRECEDENCES['ADDSUB_OPERATORS']
-    KEY= '+'
-    OP = handle_plus
-
-class MinusExpression(rules.TwoOperatorExpression):
-    expression = "minus_operation"
-    PRECEDENCE = rules.PRECEDENCES['ADDSUB_OPERATORS']
-    KEY= '-'
-    OP = handle_minus
-
 class EvalExpression(rules.OneParamExpression):
     expression = "__eval__"
     PRECEDENCE = rules.PRECEDENCES['PREFIX_OPERATORS']
     KEY = '__eval__'
     
-    def __init__(self, ast, expression):
-        super(rules.OneParamExpression, self).__init__(ast)
+    def __init__(self, ast, expression): 
+        super(EvalExpression, self).__init__(ast, expression)
         self.expression = expression
         self._str_to_eval = eval(expression.expression)
         #self.default_view = default_view
@@ -277,26 +164,26 @@
         result.extend(utils.extract_delimited_tokens(self._str_to_eval, delimiters=('@{', '}')))
         return result
     
-    def eval(self, context):
+    def get_refs(self):
+        return self.extract_refs()
+    
+    def eval(self, context, **kwargs):
         # Using the configuration to pass the eval globals dictionary to here,
         # since there isn't any easy way to do this more elegantly
         globals_and_locals = {}
-        if hasattr(context.data, '_eval_expression_globals_dict'):
-            globals_and_locals = context.data._eval_expression_globals_dict
+        if hasattr(context, '_eval_expression_globals_dict'):
+            globals_and_locals = context._eval_expression_globals_dict
         
         str_to_eval = self._str_to_eval
         
         def expand_feature_ref(ref, index):
             var_name = "__fea_%05d" % index
-            globals_and_locals[var_name] = context.data.get_default_view().get_feature(ref)
-            if context.ref_eval_callback:
-                context.ref_eval_callback(ref)
+            globals_and_locals[var_name] = context.configuration.get_default_view().get_feature(ref)
             return var_name
+
         def expand_value_ref(ref, index):
             var_name = "__feaval_%05d" % index
-            globals_and_locals[var_name] = context.data.get_default_view().get_feature(ref).get_value()
-            if context.ref_eval_callback:
-                context.ref_eval_callback(ref)
+            globals_and_locals[var_name] = context.configuration.get_default_view().get_feature(ref).get_value()
             return var_name
         
         str_to_eval = utils.expand_delimited_tokens(str_to_eval, expand_feature_ref, delimiters=('@{', '}'))
@@ -317,7 +204,6 @@
             logging.getLogger('cone.ruleml').warning("Execution failed for eval: %s %s: %s" % (str_to_eval, type(e), e) )
             self.ast.add_error(self.expression, { 'error_string' : 'Execution failed for eval', 'str_to_eval' : str_to_eval, 'rule' : self.ast.expression })
 
-rules.OPERATORS[EvalExpression.KEY] = EvalExpression
 
 class FilenamejoinExpression(rules.TwoOperatorExpression):
     expression = "filenamejoin"
@@ -325,62 +211,12 @@
     KEY = 'filenamejoin'
     OP = handle_filenamejoin
     
+# Register relations and operators to rules
+rules.RELATIONS[RequireRelation.KEY] = RequireRelation
+rules.RELATIONS[ConfigureRelation.KEY] = ConfigureRelation
 rules.OPERATORS[FilenamejoinExpression.KEY] = FilenamejoinExpression
-    
-class SetExpression(rules.TwoOperatorExpression):
-    PRECEDENCE = rules.PRECEDENCES['SET_OPERATORS']
-    KEY= '='
-    OP = handle_set
-
-    def eval(self, context):
-        try:
-            variable = context.data.get_default_view().get_feature(self.left.expression)
-            value = self.right.eval(context)
-            variable.set_value(value)
-            logging.getLogger('cone.ruleml').info("Set %r = %r from %r" % (self.left.expression, value, self.right.expression) )
-            if context.ref_set_callback:
-                context.ref_set_callback(self.left.expression)
-            return True
-        except exceptions.NotFound,e:
-            self.ast.add_error(self.left.expression, { 'error_string' : 'Setting value failed, because of %s' % e,
-                               'left_key' : self.left.expression,
-                               'rule' : self.ast.expression})
-            return False
-
-_relations_and_operators_backup = None
-
-def register():
-    """
-    Register the relations and operators to ConE rules.
-    """
-    global _relations_and_operators_backup
-    if _relations_and_operators_backup is None:
-        # Create the backup copies of the dictionaries
-        rels_backup = rules.RELATIONS.copy()
-        ops_backup = rules.OPERATORS.copy()
-        assert rels_backup is not rules.RELATIONS
-        assert ops_backup is not rules.OPERATORS
-        _relations_and_operators_backup = (rels_backup, ops_backup)
-        
-        # Register relations and operators to rules
-        rules.RELATIONS[RequireRelation.KEY] = RequireRelation
-        rules.RELATIONS[ConfigureRelation.KEY] = ConfigureRelation
-        rules.OPERATORS[ConfigureExpression.KEY] = ConfigureExpression
-        rules.OPERATORS[PlusExpression.KEY] = PlusExpression
-        rules.OPERATORS[SetExpression.KEY] = SetExpression
-        rules.OPERATORS[MinusExpression.KEY] = MinusExpression
-        rules.OPERATORS[MultiplyExpression.KEY] = MultiplyExpression
-        rules.OPERATORS[DivideExpression.KEY] = DivideExpression
-
-def unregister():
-    """
-    Undo the changes made by a call to register().
-    """
-    global _relations_and_operators_backup
-    if _relations_and_operators_backup is not None:
-        rules.RELATIONS = _relations_and_operators_backup[0]
-        rules.OPERATORS = _relations_and_operators_backup[1]
-        _relations_and_operators_backup = None
+rules.OPERATORS[EvalExpression.KEY] = EvalExpression
+rules.OPERATORS[ConfigureExpression.KEY] = ConfigureExpression
 
 def parse_rule(rulestring):
     """
--- a/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/ruleml.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/ruleml.py	Tue Aug 10 14:29:28 2010 +0300
@@ -19,21 +19,13 @@
 
 
 import os
-import sys
 import logging
-import shutil
-
-import __init__
-import re
+import pkg_resources
 
 from ruleplugin import relations
-from cone.public import exceptions,plugin,utils,api,rules
+from cone.public import plugin,utils,rules
 
 class RuleImpl(plugin.ImplBase):
-    """
-    MakeImpl plugin finds feature references that are configured in a .ruleml file
-    and generate a rule from them
-    """
     IMPL_TYPE_ID = 'ruleml'
     DEFAULT_INVOCATION_PHASE = 'pre'
     
@@ -42,7 +34,6 @@
         Overloading the default constructor
         """
         plugin.ImplBase.__init__(self,ref,configuration)
-        self.logger = logging.getLogger('cone.ruleml(%s)' % self.ref)
         self.relation_container = relation_container
 
     def list_output_files(self):
@@ -51,19 +42,63 @@
         """
         return []
     
+    def get_refs(self):
+        """
+        Return a list of all ConfML setting references that affect this
+        implementation. May also return None if references are not relevant
+        for the implementation.
+        """
+        refs = []
+        relations = self.get_relations()
+        for relation in relations:
+            # get refs from relation return a tuple (left side refs, right side refs)
+            # only the left side refs are the "input" refs  
+            refs += relation.get_refs()
+        # If the rules do not have any references return None to disable filter by refs 
+        if refs == []: 
+            refs = None
+        return refs
+    
+    def get_target_refs(self):
+        """
+        Return a list of all ConfML setting references that are affected by this
+        implementation. May also return None if references are not relevant
+        for the implementation.
+        """
+        refs = []
+        relations = self.get_relations()
+        for relation in relations:
+            refs += relation.get_set_refs()
+        return refs
+
+    def get_outputs(self):
+        """
+        Return a list of GenerationOutput objets as a list. 
+        """
+        outputs = []
+        phase = None 
+        if self.generation_context: phase = self.generation_context.phase
+        for rel in self.get_relations():
+            outrefs = rel.get_set_refs()
+            for ref in outrefs:
+                outputs.append(plugin.GenerationOutput(ref,rel,type='ref', phase=phase))
+        return outputs
+    
     def generate(self, context=None):
-        self.logger.info("Generating rules from %s" % self.ref)
+        logging.getLogger('cone.ruleml(%s)' % self.ref).info("Generating rules from %s" % self.ref)
         relation_container = self.get_relation_container()
         relation_container.context = context
-        return relation_container.execute()
-    
-    def has_tag(self, tags, policy=None):
-        # RuleML should always be executed, regardless of the tags
-        return True
+        return relation_container.execute(context)
     
     def get_relation_container(self):
         return self.relation_container
 
+    def get_relations(self):
+        return self.relation_container.get_relations()
+
+class RuleBuiltinsModule(object):
+    pass
+
 class RulemlRelationContainer(plugin.RelationContainer):
     """
     Relation container for RuleML rules.
@@ -73,7 +108,6 @@
     """
     def __init__(self, configuration, source, rule_list, eval_globals):
         plugin.RelationContainer.__init__(self, configuration, source=source)
-        self.logger = logging.getLogger('cone.ruleml_relation_container(%s)' % self.source)
         self.configuration = configuration
         self.relation_container = rules.RelationContainerImpl()
         self.eval_globals = eval_globals
@@ -81,124 +115,100 @@
         for rule in rule_list:
             self.relation_container.add_relation(rule)
     
-    def execute(self):
+    def execute(self, context=None):
         results = []
-        
+        if context: self.context = context
+         
         # Create the autoconfig if not done already
-        plugin.get_autoconfig(self.configuration)
+        autoconfig = plugin.get_autoconfig(self.configuration)
         
-        # Register relations etc. to the rule engine.
-        # Due to unit test issues the relations are not registered
-        # in the relations module, but only for the duration of
-        # rule parsing and execution
-        relations.register()
-        try:
-            # Using the configuration to pass the eval globals dict to the
-            # eval expression. The configuration only contains the globals
-            # dict for the duration of the rule execution, so hopefully this
-            # shouldn't mess anything up
-            self._set_builtin_eval_globals()
-            self.configuration._eval_expression_globals_dict = self.eval_globals
-            for i, rel in enumerate(self.relation_container):
-                index = i + 1
-                
-                # Execute
-                self._execute_relation_and_log_error(rel, self.source, index)
-                
-                # Collect execution result if supported
-                if hasattr(rel, 'get_execution_result'):
-                    result = rel.get_execution_result()
-                    if isinstance(result, plugin.RelationExecutionResult):
-                        result.source = self.source
-                        result.index = index
-                        results.append(result)
+        # Using the configuration to pass the eval globals dict to the
+        # eval expression. The configuration only contains the globals
+        # dict for the duration of the rule execution, so hopefully this
+        # shouldn't mess anything up
+        self._set_builtin_eval_globals()
+        self.context._eval_expression_globals_dict = self.eval_globals
+        for i, rel in enumerate(self.relation_container):
+            index = i + 1
+            # Execute
+            self._execute_relation_and_log_error(rel, self.source, index, context)
             
-            del self.configuration._eval_expression_globals_dict
-            
-            if self.relation_container.has_errors():
-                for error in self.relation_container.get_errors():
-                    self.logger.error(error)
-            
-            if self.context:
-                self.context.results += results
-            return results
-        finally:
-            relations.unregister()
+        del self.context._eval_expression_globals_dict
+        
+        if self.relation_container.has_errors():
+            for error in self.relation_container.get_errors():
+                logging.getLogger('cone.ruleml_relation_container(%s)' % self.source).error(error)
+        
+        if self.context:
+            self.context.results += results
+        return results
     
     def get_relation_count(self):
         return len(self.relation_container)
     
+    def get_relations(self):
+        return list(self.relation_container)
+
     def _set_builtin_eval_globals(self):
         """
         Add built-in attributes into the eval globals dictionary.
         """
-        class RuleBuiltinsModule(object):
-            pass
-                
-        builtins = RuleBuiltinsModule()
+        builtins = RuleBuiltinsModule() 
         builtins.configuration = self.configuration
+        builtins.context       = self.context
         
         self.eval_globals['ruleml'] = builtins
 
-class RuleImplReaderBase(plugin.ReaderBase):
-    NAMESPACE = None # Used as a base class, so should have no namespace
+class RuleImplReader(plugin.ReaderBase):
+    NAMESPACE = 'http://www.s60.com/xml/ruleml/3'
+    NAMESPACE_ID = 'ruleml3'
+    ROOT_ELEMENT_NAME = 'ruleml'
     FILE_EXTENSIONS = ['ruleml']
     
     def __init__(self, resource_ref, configuration):
         self.resource_ref = resource_ref
         self.configuration = configuration
-        self.logger = logging.getLogger('cone.ruleml(%s)' % self.resource_ref)
     
     @classmethod
     def read_impl(cls, resource_ref, configuration, etree):
         reader = cls(resource_ref, configuration)
+        rules = reader.parse_rules(resource_ref, etree)
+        eval_globals = reader.parse_eval_globals(etree)
+        lineno = utils.etree.get_lineno(etree)
         
-        # Register relations etc. to the rule engine.
-        # Due to unit test issues the relations are not registered
-        # in the relations module, but only for the duration of
-        # rule parsing and execution
-        relations.register()
-        try:
-            rules = reader.parse_rules(etree)
-            eval_globals = reader.parse_eval_globals(etree)
-            
+        # Create an ImplContainer to hold each rule as its own
+        # RuleML implementation
+        main_impl = plugin.ImplContainer(resource_ref, configuration)
+        main_impl.lineno = lineno
+        
+        for rule in rules:
             relation_container = RulemlRelationContainer(
                 configuration   = configuration,
-                source          = resource_ref,
-                rule_list       = rules,
+                source          = "%s:%d" % (resource_ref, rule.lineno),
+                rule_list       = [rule],
                 eval_globals    = eval_globals)
-            
-            impl = RuleImpl(resource_ref, configuration, relation_container)
-        finally:
-            relations.unregister()
         
-        return impl
-        
-class RuleImplReader1(RuleImplReaderBase):
-    NAMESPACE = 'http://www.s60.com/xml/ruleml/1'
+            impl = RuleImpl(resource_ref, configuration, relation_container)
+            impl.lineno = rule.lineno
+            rule.implml = impl
+            
+            main_impl.append(impl)
+        return main_impl
     
-    def __init__(self, resource_ref, configuration):
-        RuleImplReaderBase.__init__(self, resource_ref, configuration)
+    @classmethod
+    def get_schema_data(cls):
+        return pkg_resources.resource_string('ruleplugin', 'xsd/ruleml3.xsd')
     
-    def parse_rules(self, etree):
+    def parse_rules(self, ref, etree):
         rules = []
         for elem in etree.getiterator("{%s}rule" % self.NAMESPACE):
-            rules.extend(relations.RelationFactory.get_relations(self.configuration, elem.text))
-        return rules
-    
-    def parse_eval_globals(self, etree):
-        return {}
-
-class RuleImplReader2(RuleImplReaderBase):
-    NAMESPACE = 'http://www.s60.com/xml/ruleml/2'
-    
-    def __init__(self, resource_ref, configuration):
-        RuleImplReaderBase.__init__(self, resource_ref, configuration)
-    
-    def parse_rules(self, etree):
-        rules = []
-        for elem in etree.getiterator("{%s}rule" % self.NAMESPACE):
-            rules.extend(relations.RelationFactory.get_relations(self.configuration, self._replace_eval_blocks(elem.text)))
+            lineno = utils.etree.get_lineno(elem)
+            rule_str = self._replace_eval_blocks(elem.text or '')
+            rels = relations.RelationFactory.get_relations(rule_str) or []
+            for rule in rels:
+                rule.ref = ref
+                rule.lineno = lineno
+                rules.append(rule)
         return rules
     
     def parse_eval_globals(self, etree):
@@ -214,7 +224,7 @@
                     text = elem.text.strip()
                     exec(text, eval_globals)
                 except Exception, e:
-                    self.logger.warning('Failed to evaluate eval_globals block, exception: %s' % (e))
+                    logging.getLogger('cone.ruleml(%s)' % self.resource_ref).warning('Failed to evaluate eval_globals block, exception: %s' % (e))
         return eval_globals
     
     def _read_eval_globals_from_file(self, relative_path, eval_globals):
@@ -228,7 +238,7 @@
             text = resource.read()
             exec(text.replace('\r', ''), eval_globals)
         except Exception, e:
-            self.logger.warning('Cannot import eval file: %s. Exception: %s' % (pyfile_path, e))
+            logging.getLogger('cone.ruleml(%s)' % self.resource_ref).warning('Cannot import eval file: %s. Exception: %s' % (pyfile_path, e))
         finally:
             if resource is not None: resource.close()
         
--- a/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/__init__.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/__init__.py	Tue Aug 10 14:29:28 2010 +0300
@@ -18,19 +18,5 @@
 # Path to the directory where this file is located
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
 
-# Import common plug-in initialization
-PLUGINS_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../../../..'))
-assert os.path.split(PLUGINS_ROOT)[1] == 'plugins'
-if PLUGINS_ROOT not in sys.path: sys.path.append(PLUGINS_ROOT)
-import plugin_utils
-
+from testautomation import plugin_utils
 plugin_utils.plugin_test_init(ROOT_PATH)
-
-def collect_suite():
-    return plugin_utils.collect_test_suite_from_dir(ROOT_PATH)
-
-def runtests():
-    unittest.TextTestRunner(verbosity=2).run(collect_suite())
-
-if __name__ == '__main__':
-    runtests()
--- a/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test1/implml/terminalexpression.ruleml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test1/implml/terminalexpression.ruleml	Tue Aug 10 14:29:28 2010 +0300
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<ruleml xmlns="http://www.s60.com/xml/ruleml/2">
-  <rule>True configures EvalTest.StringLenResult = 22</rule>
-  <rule>True configures EvalTest.StringLenResult = {% SOME_VALUE %}</rule>
+<ruleml xmlns="http://www.s60.com/xml/ruleml/3">
+  <rule>True configures ${EvalTest.StringLenResult} = 22</rule>
+  <rule>True configures ${EvalTest.StringLenResult} = {% SOME_VALUE %}</rule>
   <eval_globals>SOME_VALUE = 12345</eval_globals>
 </ruleml>
\ No newline at end of file
--- a/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test2/implml/invalid_python_eval.ruleml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test2/implml/invalid_python_eval.ruleml	Tue Aug 10 14:29:28 2010 +0300
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<ruleml xmlns="http://www.s60.com/xml/ruleml/2">
-  <rule>True configures EvalTest2.StringResult = {% -> this is invalid python code %}</rule>
+<ruleml xmlns="http://www.s60.com/xml/ruleml/3">
+  <rule>True configures ${EvalTest2.StringResult} = {% -> this is invalid python code %}</rule>
 </ruleml>
\ No newline at end of file
--- a/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test3/implml/invalid_python_eval.ruleml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test3/implml/invalid_python_eval.ruleml	Tue Aug 10 14:29:28 2010 +0300
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<ruleml xmlns="http://www.s60.com/xml/ruleml/2">
-  <rule>True configures EvalTest3.StringResult = 22</rule>
+<ruleml xmlns="http://www.s60.com/xml/ruleml/3">
+  <rule>True configures ${EvalTest3.StringResult} = 22</rule>
   <eval_globals file="scripts/test_eval.py"/>
 </ruleml>
\ No newline at end of file
--- a/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test4/implml/invalid_python_eval.ruleml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test4/implml/invalid_python_eval.ruleml	Tue Aug 10 14:29:28 2010 +0300
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<ruleml xmlns="http://www.s60.com/xml/ruleml/2">
-  <rule>True configures EvalTest4.StringResult = 22</rule>
+<ruleml xmlns="http://www.s60.com/xml/ruleml/3">
+  <rule>True configures ${EvalTest4.StringResult} = 22</rule>
   <eval_globals file="scripts/not_valid_filename.py"/>
 </ruleml>
\ No newline at end of file
--- a/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test5/implml/invalid_python_eval.ruleml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test5/implml/invalid_python_eval.ruleml	Tue Aug 10 14:29:28 2010 +0300
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<ruleml xmlns="http://www.s60.com/xml/ruleml/2">
-  <rule>True configures EvalTest5.StringResult = {% 7/0 %}</rule>
+<ruleml xmlns="http://www.s60.com/xml/ruleml/3">
+  <rule>True configures ${EvalTest5.StringResult} = {% 7/0 %}</rule>
 </ruleml>
\ No newline at end of file
--- a/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test6/implml/invalid_python_eval.ruleml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/errorruleproject/test6/implml/invalid_python_eval.ruleml	Tue Aug 10 14:29:28 2010 +0300
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<ruleml xmlns="http://www.s60.com/xml/ruleml/2">
-  <rule>True configures EvalTest6.StringResult = Invalid.setting</rule>
+<ruleml xmlns="http://www.s60.com/xml/ruleml/3">
+  <rule>True configures ${EvalTest6.StringResult} = ${Invalid.setting}</rule>
 </ruleml>
\ No newline at end of file
--- a/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/confml/eval.confml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/confml/eval.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -1,6 +1,10 @@
 <configuration name="Eval test data" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
   <feature ref="EvalTest" name="Test settings for eval blocks">
   
+    <setting ref="output" name="con name" type="string" />
+    <setting ref="file" name="output file" type="string" />
+    
+    
     <setting ref="StringLenResult" name="String length result" type="int" />
     <setting ref="EvalConstantResult" name="Result set from an eval global constant" type="int" />
 	<setting ref="EvalFileImport" name="Result set from an imported pyfile" type="int" />
--- a/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/confml/testdata.confml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/confml/testdata.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -46,6 +46,12 @@
 <feature name="Unicode test feature" ref="ударениÑ">
     <setting name="Unicode test setting" ref="ελληνικά" type="string" />
   </feature>
+<feature name="Sequence setting test feature" ref="SequenceTest">
+    <setting name="Sequence 1" ref="Sequence1" type="sequence">
+        <setting name="String sub-setting" ref="String" type="string"/>
+        <setting name="Int sub-setting" ref="Int" type="int"/>
+    </setting>
+  </feature>
 <data>
     <imaker>
       <imagetarget>2</imagetarget>
@@ -83,5 +89,11 @@
     <ударениÑ>
       <ελληνικά>カタカナ</ελληνικά>
     </ударениÑ>
+    <SequenceTest>
+        <Sequence1>
+            <String>yeah</String>
+            <Int>3</Int>
+        </Sequence1>
+    </SequenceTest>
   </data>
 </configuration>
\ No newline at end of file
--- a/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/implml/arithmetic.ruleml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/implml/arithmetic.ruleml	Tue Aug 10 14:29:28 2010 +0300
@@ -1,37 +1,37 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<ruleml xmlns="http://www.s60.com/xml/ruleml/1">
+<ruleml xmlns="http://www.s60.com/xml/ruleml/3">
   <!-- Value1 = 5, Value2 = 20 -->
-  <rule>True configures Arithmetic.AdditionResult1 = 2 + 6</rule>
-  <rule>True configures Arithmetic.AdditionResult2 = Arithmetic.Value1 + 6</rule>
-  <rule>True configures Arithmetic.AdditionResult3 = 2 + Arithmetic.Value2</rule>
-  <rule>True configures Arithmetic.AdditionResult4 = Arithmetic.Value1 + Arithmetic.Value2</rule>
+  <rule>True configures ${Arithmetic.AdditionResult1} = 2 + 6</rule>
+  <rule>True configures ${Arithmetic.AdditionResult2} = ${Arithmetic.Value1} + 6</rule>
+  <rule>True configures ${Arithmetic.AdditionResult3} = 2 + ${Arithmetic.Value2}</rule>
+  <rule>True configures ${Arithmetic.AdditionResult4} = ${Arithmetic.Value1} + ${Arithmetic.Value2}</rule>
   
-  <rule>True configures Arithmetic.SubtractionResult1 = 2 - 6</rule>
-  <rule>True configures Arithmetic.SubtractionResult2 = Arithmetic.Value1 - 6</rule>
-  <rule>True configures Arithmetic.SubtractionResult3 = 2 - Arithmetic.Value2</rule>
-  <rule>True configures Arithmetic.SubtractionResult4 = Arithmetic.Value1 - Arithmetic.Value2</rule>
+  <rule>True configures ${Arithmetic.SubtractionResult1} = 2 - 6</rule>
+  <rule>True configures ${Arithmetic.SubtractionResult2} = ${Arithmetic.Value1} - 6</rule>
+  <rule>True configures ${Arithmetic.SubtractionResult3} = 2 - ${Arithmetic.Value2}</rule>
+  <rule>True configures ${Arithmetic.SubtractionResult4} = ${Arithmetic.Value1} - ${Arithmetic.Value2}</rule>
   
-  <rule>True configures Arithmetic.MultiplicationResult1 = 2 * 6</rule>
-  <rule>True configures Arithmetic.MultiplicationResult2 = Arithmetic.Value1 * 6</rule>
-  <rule>True configures Arithmetic.MultiplicationResult3 = 2 * Arithmetic.Value2</rule>
-  <rule>True configures Arithmetic.MultiplicationResult4 = Arithmetic.Value1 * Arithmetic.Value2</rule>
+  <rule>True configures ${Arithmetic.MultiplicationResult1} = 2 * 6</rule>
+  <rule>True configures ${Arithmetic.MultiplicationResult2} = ${Arithmetic.Value1} * 6</rule>
+  <rule>True configures ${Arithmetic.MultiplicationResult3} = 2 * ${Arithmetic.Value2}</rule>
+  <rule>True configures ${Arithmetic.MultiplicationResult4} = ${Arithmetic.Value1} * ${Arithmetic.Value2}</rule>
   
-  <rule>True configures Arithmetic.DivisionResult1 = 6 / 2</rule>
-  <rule>True configures Arithmetic.DivisionResult2 = Arithmetic.Value2 / 4</rule>
-  <rule>True configures Arithmetic.DivisionResult3 = 10 / Arithmetic.Value1</rule>
-  <rule>True configures Arithmetic.DivisionResult4 = Arithmetic.Value2 / Arithmetic.Value1</rule>
+  <rule>True configures ${Arithmetic.DivisionResult1} = 6 / 2</rule>
+  <rule>True configures ${Arithmetic.DivisionResult2} = ${Arithmetic.Value2} / 4</rule>
+  <rule>True configures ${Arithmetic.DivisionResult3} = 10 / ${Arithmetic.Value1}</rule>
+  <rule>True configures ${Arithmetic.DivisionResult4} = ${Arithmetic.Value2} / ${Arithmetic.Value1}</rule>
   
-  <rule>True configures Arithmetic.MixedResult1 = (6 / 2 + 3 * 9) - 7</rule> 
-  <rule>True configures Arithmetic.MixedResult2 = (6 / 2 + Arithmetic.Value1 * 9) - 7</rule> 
-  <rule>True configures Arithmetic.MixedResult3 = (Arithmetic.Value2 / 2 + Arithmetic.Value1 * 9) - 7</rule> 
-  <rule>True configures Arithmetic.MixedResult4 = (Arithmetic.Value2 / Arithmetic.Value1 + Arithmetic.Value1 * Arithmetic.Value1) - Arithmetic.Value2</rule> 
-  <rule>True configures Arithmetic.MixedResult5 = 4 + 6 / 2 - 3 * 9 + 10 / 5 - 8</rule>
+  <rule>True configures ${Arithmetic.MixedResult1} = (6 / 2 + 3 * 9) - 7</rule> 
+  <rule>True configures ${Arithmetic.MixedResult2} = (6 / 2 + ${Arithmetic.Value1} * 9) - 7</rule> 
+  <rule>True configures ${Arithmetic.MixedResult3} = (${Arithmetic.Value2} / 2 + ${Arithmetic.Value1} * 9) - 7</rule> 
+  <rule>True configures ${Arithmetic.MixedResult4} = (${Arithmetic.Value2} / ${Arithmetic.Value1} + ${Arithmetic.Value1} * ${Arithmetic.Value1}) - ${Arithmetic.Value2}</rule> 
+  <rule>True configures ${Arithmetic.MixedResult5} = 4 + 6 / 2 - 3 * 9 + 10 / 5 - 8</rule>
   
-  <rule>True configures Arithmetic.RealResult1 = 5.0 / 2.0</rule>
-  <rule>True configures Arithmetic.RealResult2 = Arithmetic.RealValue1 / 2</rule>
-  <rule>True configures Arithmetic.RealResult3 = 0.25 * Arithmetic.RealValue2</rule>
-  <rule>True configures Arithmetic.RealResult4 = Arithmetic.RealValue1 / 2.0 * Arithmetic.RealValue2</rule>
+  <rule>True configures ${Arithmetic.RealResult1} = 5.0 / 2.0</rule>
+  <rule>True configures ${Arithmetic.RealResult2} = ${Arithmetic.RealValue1} / 2</rule>
+  <rule>True configures ${Arithmetic.RealResult3} = 0.25 * ${Arithmetic.RealValue2}</rule>
+  <rule>True configures ${Arithmetic.RealResult4} = ${Arithmetic.RealValue1} / 2.0 * ${Arithmetic.RealValue2}</rule>
   
-  <rule>True configures Arithmetic.RealCalcIntoIntResult = 0.25 * Arithmetic.RealValue1</rule>
-  <rule>True configures Arithmetic.IntCalcIntoRealResult = 3 * Arithmetic.Value1</rule>
+  <rule>True configures ${Arithmetic.RealCalcIntoIntResult} = 0.25 * ${Arithmetic.RealValue1}</rule>
+  <rule>True configures ${Arithmetic.IntCalcIntoRealResult} = 3 * ${Arithmetic.Value1}</rule>
 </ruleml>
\ No newline at end of file
--- a/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/implml/commsdat.ruleml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/implml/commsdat.ruleml	Tue Aug 10 14:29:28 2010 +0300
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <ruleml xmlns="http://www.s60.com/xml/ruleml/1">
-  <rule>(APs.AP != []) or (VPN_APs.VPN_AP != []) configures KCRUidCommsDatCreator.KCommsDatCreatorInputFileName = 'test.xml'</rule>
+  <rule>(${APs.AP} != []) or (${VPN_APs.VPN_AP} != []) configures ${KCRUidCommsDatCreator.KCommsDatCreatorInputFileName} = 'test.xml'</rule>
 </ruleml>
\ No newline at end of file
--- a/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/implml/comparison_operators.ruleml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/implml/comparison_operators.ruleml	Tue Aug 10 14:29:28 2010 +0300
@@ -1,20 +1,20 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<ruleml xmlns="http://www.s60.com/xml/ruleml/1">
-  <rule>0 == 0 configures CompOperTest.LiteralsResult1 = true</rule>
-  <rule>0 != 1 configures CompOperTest.LiteralsResult2 = true</rule>
-  <rule>1 &lt; 2 configures CompOperTest.LiteralsResult3 = true</rule>
-  <rule>2 > 1 configures CompOperTest.LiteralsResult4 = true</rule>
-  <rule>1 &lt;= 1 configures CompOperTest.LiteralsResult5 = true</rule>
-  <rule>1 &lt;= 2 configures CompOperTest.LiteralsResult6 = true</rule>
-  <rule>1 >= 1 configures CompOperTest.LiteralsResult7 = true</rule>
-  <rule>2 >= 1 configures CompOperTest.LiteralsResult8 = true</rule>
+<ruleml xmlns="http://www.s60.com/xml/ruleml/3">
+  <rule>0 == 0 configures ${CompOperTest.LiteralsResult1} = true</rule>
+  <rule>0 != 1 configures ${CompOperTest.LiteralsResult2} = true</rule>
+  <rule>1 &lt; 2 configures ${CompOperTest.LiteralsResult3} = true</rule>
+  <rule>2 > 1 configures ${CompOperTest.LiteralsResult4} = true</rule>
+  <rule>1 &lt;= 1 configures ${CompOperTest.LiteralsResult5} = true</rule>
+  <rule>1 &lt;= 2 configures ${CompOperTest.LiteralsResult6} = true</rule>
+  <rule>1 >= 1 configures ${CompOperTest.LiteralsResult7} = true</rule>
+  <rule>2 >= 1 configures ${CompOperTest.LiteralsResult8} = true</rule>
 
-  <rule>CompOperTest.Zero == CompOperTest.Zero configures CompOperTest.RefsResult1 = true</rule>
-  <rule>CompOperTest.Zero != CompOperTest.One configures CompOperTest.RefsResult2 = true</rule>
-  <rule>CompOperTest.One &lt; CompOperTest.Two configures CompOperTest.RefsResult3 = true</rule>
-  <rule>CompOperTest.Two > CompOperTest.One configures CompOperTest.RefsResult4 = true</rule>
-  <rule>CompOperTest.One &lt;= CompOperTest.One configures CompOperTest.RefsResult5 = true</rule>
-  <rule>CompOperTest.One &lt;= CompOperTest.Two configures CompOperTest.RefsResult6 = true</rule>
-  <rule>CompOperTest.One >= CompOperTest.One configures CompOperTest.RefsResult7 = true</rule>
-  <rule>CompOperTest.Two >= CompOperTest.One configures CompOperTest.RefsResult8 = true</rule>
+  <rule>${CompOperTest.Zero} == ${CompOperTest.Zero} configures ${CompOperTest.RefsResult1} = true</rule>
+  <rule>${CompOperTest.Zero} != ${CompOperTest.One} configures ${CompOperTest.RefsResult2} = true</rule>
+  <rule>${CompOperTest.One} &lt; ${CompOperTest.Two} configures ${CompOperTest.RefsResult3} = true</rule>
+  <rule>${CompOperTest.Two} > ${CompOperTest.One} configures ${CompOperTest.RefsResult4} = true</rule>
+  <rule>${CompOperTest.One} &lt;= ${CompOperTest.One} configures ${CompOperTest.RefsResult5} = true</rule>
+  <rule>${CompOperTest.One} &lt;= ${CompOperTest.Two} configures ${CompOperTest.RefsResult6} = true</rule>
+  <rule>${CompOperTest.One} >= ${CompOperTest.One} configures ${CompOperTest.RefsResult7} = true</rule>
+  <rule>${CompOperTest.Two} >= ${CompOperTest.One} configures ${CompOperTest.RefsResult8} = true</rule>
 </ruleml>
--- a/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/implml/container_with_rules.ruleml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/implml/container_with_rules.ruleml	Tue Aug 10 14:29:28 2010 +0300
@@ -2,19 +2,24 @@
 <container xmlns="http://www.symbianfoundation.org/xml/implml/1">
     <container>
         <phase name="pre"/>
-        <rules:ruleml xmlns:rules="http://www.s60.com/xml/ruleml/1">
-          <rules:rule>imaker.imagetarget configures imakerapi.outputLocation = imaker.imagetarget</rules:rule>
-          <rules:rule>True configures StringConcatenationTest.Result1 = "Test " + "test"</rules:rule>
-          <rules:rule>True configures StringConcatenationTest.Result2 = StringConcatenationTest.Value1 + " Literal 2"</rules:rule>
+        <rules:ruleml xmlns:rules="http://www.s60.com/xml/ruleml/3">
+          <rules:rule>{% dummy_function(${imakerapi.PRODUCT_NAME}) %} configures ${imakerapi.PRODUCT_NAME} = "test product"</rules:rule>
+          <rules:rule>${imaker.imagetarget} configures ${imakerapi.outputLocation} = ${imaker.imagetarget}</rules:rule>
+          <rules:rule>True configures ${StringConcatenationTest.Result1} = "Test " + "test"</rules:rule>
+          <rules:rule>True configures ${StringConcatenationTest.Result2} = ${StringConcatenationTest.Value1} + " Literal 2"</rules:rule>
+          <eval_globals>
+def dummy_function(ref):
+    return ref
+        </eval_globals>
         </rules:ruleml>
     </container>
     <container>
         <phase name="normal"/>
-        <rules:ruleml xmlns:rules="http://www.s60.com/xml/ruleml/1">
-          <rules:rule>True configures StringConcatenationTest.Result3 = "Literal 1 " + StringConcatenationTest.Value2</rules:rule>
-          <rules:rule>True configures StringConcatenationTest.Result4 = StringConcatenationTest.Value1 + StringConcatenationTest.Value2</rules:rule>
-          <rules:rule>True configures StringConcatenationTest.Result5 = StringConcatenationTest.Value1 + " &amp; " + StringConcatenationTest.Value2</rules:rule>
-          <rules:rule>True configures StringConcatenationTest.Result6 = StringConcatenationTest.Value1 + u" € カタカナ"</rules:rule>      
+        <rules:ruleml xmlns:rules="http://www.s60.com/xml/ruleml/3">
+          <rules:rule>True configures ${StringConcatenationTest.Result3} = "Literal 1 " + ${StringConcatenationTest.Value2}</rules:rule>
+          <rules:rule>True configures ${StringConcatenationTest.Result4} = ${StringConcatenationTest.Value1} + ${StringConcatenationTest.Value2}</rules:rule>
+          <rules:rule>True configures ${StringConcatenationTest.Result5} = ${StringConcatenationTest.Value1} + " &amp; " + ${StringConcatenationTest.Value2}</rules:rule>
+          <rules:rule>True configures ${StringConcatenationTest.Result6} = ${StringConcatenationTest.Value1} + u" € カタカナ"</rules:rule>      
         </rules:ruleml>
     </container>
 </container>
--- a/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/implml/eval.ruleml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/implml/eval.ruleml	Tue Aug 10 14:29:28 2010 +0300
@@ -1,20 +1,20 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<ruleml xmlns="http://www.s60.com/xml/ruleml/2">
-  <rule>True configures EvalTest.StringLenResult = {% len("faklskjh") %}</rule>
-  <rule>True configures EvalTest.EvalConstantResult = {% SOME_VALUE %}</rule>
-  <rule>True configures EvalTest.EvalFileImport = {% do_something(SOME_VALUE) %}</rule>
+<ruleml xmlns="http://www.s60.com/xml/ruleml/3">
+  <rule>True configures ${EvalTest.StringLenResult} = {% len("faklskjh") %}</rule>
+  <rule>True configures ${EvalTest.EvalConstantResult} = {% SOME_VALUE %}</rule>
+  <rule>True configures ${EvalTest.EvalFileImport} = {% do_something(SOME_VALUE) %}</rule>
   
-  <rule>{% ${EvalTest.Bitmask} &amp; 0x1 %} configures EvalTest.Bit0Result = True</rule>
-  <rule>{% ${EvalTest.Bitmask} &amp; 0x2 %} configures EvalTest.Bit1Result = True</rule>
-  <rule>True configures EvalTest.Bit2Result = {% 
+  <rule>{% ${EvalTest.Bitmask} &amp; 0x1 %} configures ${EvalTest.Bit0Result} = True</rule>
+  <rule>{% ${EvalTest.Bitmask} &amp; 0x2 %} configures ${EvalTest.Bit1Result} = True</rule>
+  <rule>True configures ${EvalTest.Bit2Result} = {% 
     bool(${EvalTest.Bitmask} &amp; 0x4) 
     %}
     </rule>
   
-  <rule>True configures EvalTest.Bit3Result = {% bool(${EvalTest.Bitmask} &amp; 0x8) %}</rule>
+  <rule>True configures ${EvalTest.Bit3Result} = {% bool(${EvalTest.Bitmask} &amp; 0x8) %}</rule>
   
   <rule>
-    True configures EvalTest.FullSequence = {% append_stripped_seq_to_full_seq(
+    True configures ${EvalTest.FullSequence} = {% append_stripped_seq_to_full_seq(
         @{EvalTest.StrippedSequence},
         @{EvalTest.FullSequence})
     %}
@@ -23,10 +23,10 @@
   <!-- The eval block here should not be executed -->
   <rule>False configures {% @{EvalTest.UnchangedValue}.set_value(54321) %}</rule>
   
-  <rule>True configures EvalTest.UnicodeResult1 = {% u'100€' %}</rule>
-  <rule>True configures EvalTest.UnicodeResult2 = {% @{ударениÑ.ελληνικά}.get_value() %}</rule>
+  <rule>True configures ${EvalTest.UnicodeResult1} = {% u'100€' %}</rule>
+  <rule>True configures ${EvalTest.UnicodeResult2} = {% @{ударениÑ.ελληνικά}.get_value() %}</rule>
   
-  <rule>True configures EvalTest.EvalBuiltinResult = {% ruleml.configuration.get_name() %}</rule>
+  <rule>True configures ${EvalTest.EvalBuiltinResult} = {% ruleml.configuration.get_name() %}</rule>
   
   <eval_globals>SOME_VALUE = 12345</eval_globals>
   
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/implml/eval_generation_context.ruleml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ruleml xmlns="http://www.s60.com/xml/ruleml/3">
+  <rule>True configures ${EvalTest.output} = {% test_get_output_folder() %}</rule>
+  <rule>True configures ${EvalTest.file} = {% test_add_file_to_output_folder() %}</rule>
+ 
+  <eval_globals>SOME_VALUE = 12345</eval_globals>
+	  
+  
+<eval_globals file="scripts/test_eval_generation_context.py"/>
+</ruleml>
\ No newline at end of file
--- a/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/implml/filename_rules.ruleml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/implml/filename_rules.ruleml	Tue Aug 10 14:29:28 2010 +0300
@@ -1,14 +1,14 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<ruleml xmlns="http://www.s60.com/xml/ruleml/1">
-  <rule>True configures FilenamejoinTest.Result1 = FilenamejoinTest.String1 filenamejoin FilenamejoinTest.File1.localPath</rule>
-  <rule>True configures FilenamejoinTest.Result2 = "some/content/dir/somefile.csv" filenamejoin FilenamejoinTest.File1.localPath</rule>
-  <rule>True configures FilenamejoinTest.Result3 = "some/content/dir/" filenamejoin FilenamejoinTest.File1.localPath</rule>
-  <rule>True configures FilenamejoinTest.Result4 = "some\\content\\dir\\somefile.csv" filenamejoin FilenamejoinTest.File1.localPath</rule>
-  <rule>True configures FilenamejoinTest.Result5 = "some\\content\\dir\\" filenamejoin FilenamejoinTest.File1.localPath</rule>
-  <rule>True configures FilenamejoinTest.Result6 = "Z:\\\\some\\\\content\\\\dir\\\\somefile.csv" filenamejoin FilenamejoinTest.File1.localPath</rule>
-  <rule>True configures FilenamejoinTest.Result7 = "Z:\\\\some\\\\content\\\\dir\\\\" filenamejoin FilenamejoinTest.File1.localPath</rule>
-  <rule>True configures FilenamejoinTest.Result8 = "somedir" filenamejoin FilenamejoinTest.File1.localPath</rule>
-  <rule>True configures FilenamejoinTest.Result9 = "somedir" filenamejoin "somefile.txt"</rule>
-  <rule>True configures FilenamejoinTest.Result10 = "somedir" filenamejoin "somefile.txt" + ';' + r'Z:\\some\\dir\\' filenamejoin FilenamejoinTest.File1.localPath</rule>
-  <rule>True and FilenamejoinTest.String1==r'Z:\\data\\sound.mp3' and True configures FilenamejoinTest.Result11 = "some" + "dir" filenamejoin "somefile.txt"</rule>
+<ruleml xmlns="http://www.s60.com/xml/ruleml/3">
+  <rule>True configures ${FilenamejoinTest.Result1} = ${FilenamejoinTest.String1} filenamejoin ${FilenamejoinTest.File1.localPath}</rule>
+  <rule>True configures ${FilenamejoinTest.Result2} = "some/content/dir/somefile.csv" filenamejoin ${FilenamejoinTest.File1.localPath}</rule>
+  <rule>True configures ${FilenamejoinTest.Result3} = "some/content/dir/" filenamejoin ${FilenamejoinTest.File1.localPath}</rule>
+  <rule>True configures ${FilenamejoinTest.Result4} = "some\\content\\dir\\somefile.csv" filenamejoin ${FilenamejoinTest.File1.localPath}</rule>
+  <rule>True configures ${FilenamejoinTest.Result5} = "some\\content\\dir\\" filenamejoin ${FilenamejoinTest.File1.localPath}</rule>
+  <rule>True configures ${FilenamejoinTest.Result6} = "Z:\\\\some\\\\content\\\\dir\\\\somefile.csv" filenamejoin ${FilenamejoinTest.File1.localPath}</rule>
+  <rule>True configures ${FilenamejoinTest.Result7} = "Z:\\\\some\\\\content\\\\dir\\\\" filenamejoin ${FilenamejoinTest.File1.localPath}</rule>
+  <rule>True configures ${FilenamejoinTest.Result8} = "somedir" filenamejoin ${FilenamejoinTest.File1.localPath}</rule>
+  <rule>True configures ${FilenamejoinTest.Result9} = "somedir" filenamejoin "somefile.txt"</rule>
+  <rule>True configures ${FilenamejoinTest.Result10} = "somedir" filenamejoin "somefile.txt" + ';' + r'Z:\\some\\dir\\' filenamejoin ${FilenamejoinTest.File1.localPath}</rule>
+  <rule>True and ${FilenamejoinTest.String1}==r'Z:\\data\\sound.mp3' and True configures ${FilenamejoinTest.Result11} = "some" + "dir" filenamejoin "somefile.txt"</rule>
 </ruleml>
\ No newline at end of file
--- a/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/implml/rules.ruleml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/implml/rules.ruleml	Tue Aug 10 14:29:28 2010 +0300
@@ -1,22 +1,27 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<ruleml xmlns="http://www.s60.com/xml/ruleml/1">
-  <rule>imaker.imagetarget configures imakerapi.outputLocation = imaker.imagetarget</rule>
-  <rule>mms.imagesize == 'large' configures pd.ref1 = True and pd.ref2 = True</rule>
-  <rule>mms.imagesize == 'small' configures pd.ref1 = False and pd.ref2 = True</rule>
-  <rule>mms.imagesize == 'extrasmall' configures pd.ref1 = False and pd.ref2 = False</rule>
-  <rule>mms.imagesize == 'extralarge' configures pd.ref1 = True and pd.ref2 = False</rule>
-  <rule>imakerapi.outputLocationY == None configures imakerapi.outputLocationY = 'hello'</rule>
-  <rule>operations.minus == 5 configures operations.minus = operations.minus1 - operations.minus2</rule>
-  <rule>operations.minus1 == 25 configures operations.minus1 = operations.minus3 * operations.minus2</rule>
-  <rule>operations.minus4 == 10 configures operations.minus4 = operations.minus4 / operations.minus5</rule>
-  <rule>operations.minus6 == 5 configures operations.minus6 = operations.minus7 + operations.minus8</rule>
+<ruleml xmlns="http://www.s60.com/xml/ruleml/3">
+  <rule>{% ${imaker.imagetarget} %} configures ${imakerapi.outputLocation} = ${imaker.imagetarget}</rule>
+  <rule>${mms.imagesize} == 'large' configures ${pd.ref1} = True and ${pd.ref2} = True</rule>
+  <rule>${mms.imagesize} == 'small' configures ${pd.ref1} = False and ${pd.ref2} = True</rule>
+  <rule>${mms.imagesize} == 'extrasmall' configures ${pd.ref1} = False and ${pd.ref2} = False</rule>
+  <rule>${mms.imagesize} == 'extralarge' configures ${pd.ref1} = True and ${pd.ref2} = False</rule>
+  <rule>${imakerapi.outputLocationY} == None configures ${imakerapi.outputLocationY} = 'hello'</rule>
+  <rule>${operations.minus} == 5 configures ${operations.minus} = ${operations.minus1} - ${operations.minus2}</rule>
+  <rule>${operations.minus1} == 25 configures ${operations.minus1} = ${operations.minus3} * ${operations.minus2}</rule>
+  <rule>${operations.minus4} == 10 configures ${operations.minus4} = ${operations.minus4} / ${operations.minus5}</rule>
+  <rule>${operations.minus6} == 5 configures ${operations.minus6} = ${operations.minus7} + ${operations.minus8}</rule>
   
-  <rule>True configures StringConcatenationTest.Result1 = "Test " + "test"</rule>
-  <rule>True configures StringConcatenationTest.Result2 = StringConcatenationTest.Value1 + " Literal 2"</rule>
-  <rule>True configures StringConcatenationTest.Result3 = "Literal 1 " + StringConcatenationTest.Value2</rule>
-  <rule>True configures StringConcatenationTest.Result4 = StringConcatenationTest.Value1 + StringConcatenationTest.Value2</rule>
-  <rule>True configures StringConcatenationTest.Result5 = StringConcatenationTest.Value1 + " &amp; " + StringConcatenationTest.Value2</rule>
-  <rule>True configures StringConcatenationTest.Result6 = StringConcatenationTest.Value1 + u" € カタカナ"</rule>
+  <rule>True configures ${StringConcatenationTest.Result1} = "Test " + "test"</rule>
+  <rule>True configures ${StringConcatenationTest.Result2} = ${StringConcatenationTest.Value1} + " Literal 2"</rule>
+  <rule>True configures ${StringConcatenationTest.Result3} = "Literal 1 " + ${StringConcatenationTest.Value2}</rule>
+  <rule>True configures ${StringConcatenationTest.Result4} = ${StringConcatenationTest.Value1} + ${StringConcatenationTest.Value2}</rule>
+  <rule>True configures ${StringConcatenationTest.Result5} = ${StringConcatenationTest.Value1} + " &amp; " + ${StringConcatenationTest.Value2}</rule>
+  <rule>True configures ${StringConcatenationTest.Result6} = ${StringConcatenationTest.Value1} + u" € カタカナ"</rule>
   
-  <rule>True configures ударениÑ.ελληνικά = ударениÑ.ελληνικά + u" € カタカナ"</rule>
+  <rule>True configures ${ударениÑ.ελληνικά} = ${ударениÑ.ελληνικά} + u" € カタカナ"</rule>
+  
+  <rule>True configures ${SequenceTest.Sequence1} = {% [['foo', 1], ['bar', 2], ['baz', 3]] %}</rule>
+  
+  <rule>{% @{Foo.Bar}.value %} configures ${Foo.Baz} = 'gaa'</rule>
+  
 </ruleml>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/ruleproject/rules/implml/scripts/test_eval_generation_context.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,34 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+
+
+def test_get_output_folder():
+    output = ruleml.context.output
+    return output
+
+
+#add file to output folder
+def test_add_file_to_output_folder():
+
+    filename = "output_test.txt"
+    output = ruleml.context.output
+     
+    f = open(output + '/' + filename,'w')
+    f.writelines("Test!")
+    f.close()
+    
+    return output + '/' + filename
--- a/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/runtests.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/runtests.py	Tue Aug 10 14:29:28 2010 +0300
@@ -14,6 +14,6 @@
 # Description: 
 #
 
-import __init__
-
-__init__.runtests()
+if __name__ == '__main__':
+    import nose
+    nose.core.run(argv=['collector','--include=unittest', '--verbosity=3'])
--- a/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/unittest_eval.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/unittest_eval.py	Tue Aug 10 14:29:28 2010 +0300
@@ -20,8 +20,6 @@
 import sys
 import re
 
-import __init__
-
 from ruleplugin import ruleml, relations
 from cone.public import api, exceptions
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
@@ -42,10 +40,10 @@
 
 class MockConfigurationContext(object):
     def __init__(self, feature_values):
-        self.data = MockObject()
+        self.configuration = MockObject()
         default_view = MockObject()
         default_view.get_feature = lambda ref: MockFeature(ref, feature_values)
-        self.data.get_default_view = lambda: default_view
+        self.configuration.get_default_view = lambda: default_view
         self.ref_eval_callback = None
 
 class MockExpression(object):
@@ -85,7 +83,7 @@
 
 class TestReplaceEvalBlocks(unittest.TestCase):
     def test_replace_eval_blocks(self):
-        replace = ruleml.RuleImplReader2._replace_eval_blocks
+        replace = ruleml.RuleImplReader._replace_eval_blocks
         
         orig = """some.setting configures x = y"""
         self.assertEquals(replace(orig), orig)
--- a/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/unittest_parseruleml.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/unittest_parseruleml.py	Tue Aug 10 14:29:28 2010 +0300
@@ -28,28 +28,24 @@
         except ImportError:
             from xml.etree import ElementTree
 
-import __init__
-
 from ruleplugin import ruleml, relations
 from cone.public import api, exceptions, utils, plugin
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
 
 ruleml_string = \
 '''<?xml version="1.0" encoding="UTF-8"?>
-<ruleml xmlns="http://www.s60.com/xml/ruleml/2">
-  <rule>imaker.imagetarget configures imakerapi.outputLocation = imaker.imagetarget</rule>
-  <rule>imaker.imagename configures imakerapi.outputLocation = imaker.imagename</rule>
+<ruleml xmlns="http://www.s60.com/xml/ruleml/3">
+  <rule>${imaker.imagetarget} configures ${imakerapi.outputLocation} = ${imaker.imagetarget}</rule>
+  <rule>${imaker.imagename} configures ${imakerapi.outputLocation} = ${imaker.imagename}</rule>
 </ruleml>
 '''
 
 class TestParseRuleimpl(unittest.TestCase):    
-    def setUp(self):    relations.register()
-    def tearDown(self): relations.unregister()
     
     def test_parse_rules(self):
-        etree = ElementTree.fromstring(ruleml_string)
-        reader = ruleml.RuleImplReader2(None, None)
-        rules = reader.parse_rules(etree)
+        etree = utils.etree.fromstring(ruleml_string)
+        reader = ruleml.RuleImplReader(None, None)
+        rules = reader.parse_rules("", etree)
         self.assertTrue(isinstance(rules[0],relations.ConfigureRelation))
         self.assertTrue(isinstance(rules[1],relations.ConfigureRelation))
         self.assertTrue(rules[0].has_ref('imaker.imagetarget'))
@@ -58,8 +54,6 @@
 
 
 class TestRulemlFromFile(unittest.TestCase):
-    def setUp(self):    pass
-    def tearDown(self): relations.unregister()
     
     def test_create_from_file(self):
         project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'ruleproject/rules')))
@@ -67,15 +61,18 @@
         ruleimpl = plugin.ImplFactory.get_impls_from_file('implml/rules.ruleml', config)[0]
         relation_container = ruleimpl.get_relation_container()
         self.assertTrue(isinstance(relation_container, plugin.RelationContainer))
-        self.assertEquals(relation_container.get_relation_count(), 17)
-
+        self.assertEquals(relation_container.get_relation_count(), 19)
+        self.assertEquals(len(relation_container.get_relations()), 19)
+        self.assertEquals(relation_container.get_relations()[0].get_refs(),[u'imaker.imagetarget'])
+        self.assertEquals(relation_container.get_relations()[0].implml.ref, 'implml/rules.ruleml')
+        
     def test_create_from_file_with_common_container(self):
         project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'ruleproject/rules')))
         config = project.get_configuration('root.confml')
         ruleimpl = plugin.ImplFactory.get_impls_from_file('implml/container_with_rules.ruleml', config)[0]
         relation_container = ruleimpl.get_relation_container()
         self.assertTrue(isinstance(relation_container, plugin.RelationContainer))
-        self.assertEquals(relation_container.get_relation_count(), 7)
+        self.assertEquals(relation_container.get_relation_count(), 8)
 
     def test_create_from_file_filename(self):
         project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'ruleproject/rules')))
--- a/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/unittest_rule_empty_plugin.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/unittest_rule_empty_plugin.py	Tue Aug 10 14:29:28 2010 +0300
@@ -19,8 +19,6 @@
 import sys
 import logging
 
-import __init__
-
 from cone.public import exceptions,plugin,api,container
 from cone.storage import filestorage
 from ruleplugin import ruleml
--- a/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/unittest_rule_plugin.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/unittest_rule_plugin.py	Tue Aug 10 14:29:28 2010 +0300
@@ -15,14 +15,12 @@
 #
 
 import unittest
-import os, shutil
-import sys
+import os
 import logging
-import __init__
 
-from cone.public import exceptions,plugin,api,container
-from cone.storage import filestorage
+from cone.public import plugin,api
 from ruleplugin import ruleml
+from testautomation.base_testcase import BaseTestCase
 
 # Hardcoded value of testdata folder that must be under the current working dir
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
@@ -35,23 +33,68 @@
     def tearDown(self):
         pass
 
-class TestRulePluginOnFileStorage(unittest.TestCase):    
+class TestRulePluginOnFileStorage(BaseTestCase):
     def test_get_impl_container(self):
         project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'ruleproject/rules')))
         config = project.get_configuration('root.confml')
         implcontainer = plugin.get_impl_set(config, 'ruleml$')
         impl = implcontainer.get_implementations_by_file('implml/rules.ruleml')[0]
         
-        self.assertEquals(None, impl.get_refs())
+        EXPECTED_REFS = ['imaker.imagetarget',
+                         'mms.imagesize',
+                         'imakerapi.outputLocationY',
+                         'operations.minus',
+                         'operations.minus1',
+                         'operations.minus4',
+                         'operations.minus6',
+                         'Foo.Bar']
+        self.assertEquals(sorted(EXPECTED_REFS), sorted(impl.get_child_refs()))
         self.assertEquals([], impl.list_output_files())
 
-    def test_impl_container_execute_pre_rules(self):
+    def test_rules_get_refs(self):
         project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'ruleproject/rules'), "a" ))
         config = project.get_configuration('root.confml')
         
         implcontainer = plugin.get_impl_set(config, 'ruleml$')
         ruleimpl = implcontainer.get_implementations_by_file('implml/container_with_rules.ruleml')[0]
-        context = plugin.GenerationContext()
+        self.assertEquals(ruleimpl.get_child_refs(), [u'imakerapi.PRODUCT_NAME',
+                                                      u'imaker.imagetarget'])
+        self.assertEquals(len(ruleimpl.get_outputs()), 8)
+        outputs = [output.name for output in ruleimpl.get_outputs()]
+        self.assertEquals(outputs, [u'imakerapi.PRODUCT_NAME', 
+                                    u'imakerapi.outputLocation', 
+                                    u'StringConcatenationTest.Result1', 
+                                    u'StringConcatenationTest.Result2', 
+                                    u'StringConcatenationTest.Result3', 
+                                    u'StringConcatenationTest.Result4', 
+                                    u'StringConcatenationTest.Result5', 
+                                    u'StringConcatenationTest.Result6'])
+        inputs = []
+        for output in ruleimpl.get_outputs():
+            inputs += output.implementation.get_refs()
+        self.assertEquals(inputs, [u'imakerapi.PRODUCT_NAME', 
+                                   u'imaker.imagetarget'])
+        impls_refs = []
+        for output in ruleimpl.get_outputs():
+            impls_refs.append("%s <= %s" % (output.name, output.implementation.implml.ref))
+        self.assertEquals(impls_refs, [u'imakerapi.PRODUCT_NAME <= implml/container_with_rules.ruleml',
+                                       u'imakerapi.outputLocation <= implml/container_with_rules.ruleml', 
+                                       u'StringConcatenationTest.Result1 <= implml/container_with_rules.ruleml', 
+                                       u'StringConcatenationTest.Result2 <= implml/container_with_rules.ruleml', 
+                                       u'StringConcatenationTest.Result3 <= implml/container_with_rules.ruleml', 
+                                       u'StringConcatenationTest.Result4 <= implml/container_with_rules.ruleml', 
+                                       u'StringConcatenationTest.Result5 <= implml/container_with_rules.ruleml', 
+                                       u'StringConcatenationTest.Result6 <= implml/container_with_rules.ruleml'])
+        
+        
+    def test_impl_container_execute_pre_rules(self):
+        
+        project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'ruleproject/rules'), "a" ))
+        config = project.get_configuration('root.confml')
+        
+        implcontainer = plugin.get_impl_set(config, 'ruleml$')
+        ruleimpl = implcontainer.get_implementations_by_file('implml/container_with_rules.ruleml')[0]
+        context = plugin.GenerationContext(configuration=config)
         context.phase = "pre"
         ruleimpl.generate(context)
         
@@ -68,18 +111,51 @@
         project.close()
 
     def test_impl_container_execute_rules(self):
-        project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'ruleproject/rules'), "a" ))
+        project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'ruleproject/rules'), "r" ))
         config = project.get_configuration('root.confml')
         
         implcontainer = plugin.get_impl_set(config, 'ruleml$')
-        implcontainer.generate()
+        context = plugin.GenerationContext(configuration=config)
+        implcontainer.generate(context)
         
         lastconfig = config.get_last_configuration()
         self.assertEquals(lastconfig.get_path(), plugin.AUTOCONFIG_CONFML)
         self.assertEquals(lastconfig.get_data('imakerapi.outputLocation').get_ref(),'outputLocation')
         self.assertEquals(lastconfig.get_data('imakerapi.outputLocation').get_value(),'2')
         project.close()
+    
+    def _prepare_log(self, log_file, level=logging.DEBUG, formatter="%(levelname)s - %(name)s - %(message)s", logger='cone'):
+        FULL_PATH = os.path.join(ROOT_PATH, "temp", log_file)
+        self.remove_if_exists(FULL_PATH)
+        self.create_dir_for_file_path(FULL_PATH)
         
+        handler = logging.FileHandler(FULL_PATH)
+        handler.setLevel(level)
+        frm = logging.Formatter(formatter)
+        handler.setFormatter(frm)
+        logger = logging.getLogger(logger)
+        logger.addHandler(handler)
+        
+        return [FULL_PATH, handler, logger]
+    
+    def test_rule_debug_messages(self):
+        log_file, handler, logger = self._prepare_log('debug_msg_test.log')
+        project = None
+        try:
+            project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,'ruleproject/rules'), "r" ))
+            config = project.get_configuration('root.confml')
+            
+            implcontainer = plugin.get_impl_set(config, r'rules\.ruleml$')
+            context = plugin.GenerationContext(configuration=config)
+            implcontainer.generate(context)
+            
+            self.assert_file_contains(log_file,
+                ["Set imakerapi.outputLocationY = 'hello' from ConfigureRelation(ref='implml/rules.ruleml', lineno=8)",
+                 "Set operations.minus = 18 from ConfigureRelation(ref='implml/rules.ruleml', lineno=9)",
+                 "Set SequenceTest.Sequence1 = [['foo', 1], ['bar', 2], ['baz', 3]] from ConfigureRelation(ref='implml/rules.ruleml', lineno=23)"])
+        finally:
+            logger.removeHandler(handler)
+            if project: project.close()
         
 if __name__ == '__main__':
     unittest.main()
--- a/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/unittest_rule_plugin_errors.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/unittest_rule_plugin_errors.py	Tue Aug 10 14:29:28 2010 +0300
@@ -18,7 +18,6 @@
 import os, shutil
 import sys
 import logging
-import __init__
 
 from cone.public import exceptions,plugin,api,container
 from cone.storage import filestorage
@@ -58,9 +57,9 @@
     def _execute_rules(self, project_location):
         project = api.Project(api.Storage.open(os.path.join(ROOT_PATH, project_location)))
         config = project.get_configuration('root.confml')
-        
+        context = plugin.GenerationContext(configuration=config)
         implcontainer = plugin.get_impl_set(config, r'\.ruleml$')
-        implcontainer.get_relation_container().execute()
+        implcontainer.get_relation_container().execute(context)
         lastconfig = config.get_last_configuration()
         project.close()
     
@@ -75,9 +74,7 @@
         log_file, handler, logger = self._prepare_log('test2.log')
         self._execute_rules('errorruleproject/test2')
         logger.removeHandler(handler)
-        self.assert_file_contains(log_file, "INFO - cone.ruleml - Set u'EvalTest2.StringResult' = None from '-> this is invalid python code'")
         self.assert_file_contains(log_file, "WARNING - cone.ruleml - Invalid syntax in eval: -> this is invalid python code")
-        self.assert_file_contains(log_file, "ERROR - cone.ruleml_relation_container(implml/invalid_python_eval.ruleml) - '-> this is invalid python code'")
 
     def test_invalid_python_code_eval_globals(self):
         log_file, handler, logger = self._prepare_log('test3.log')
@@ -96,7 +93,7 @@
         log_file, handler, logger = self._prepare_log('test5.log')
         self._execute_rules('errorruleproject/test5')
         logger.removeHandler(handler)
-
+        
         self.assert_file_contains(log_file, "Execution failed for eval: 7/0 <type 'exceptions.ZeroDivisionError'>: integer division or modulo by zero")
 
     def test_references_non_existent_settings(self):
--- a/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/unittest_rules.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/tests/unittest_rules.py	Tue Aug 10 14:29:28 2010 +0300
@@ -18,8 +18,7 @@
 import unittest
 import os, shutil
 import sys
-import __init__
-        
+
 from ruleplugin import ruleml
 from cone.public import api, plugin
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
@@ -35,10 +34,29 @@
     
     def _execute_rules(self, impl_filter):
         implcontainer = plugin.get_impl_set(self.config, impl_filter)
-        context = plugin.GenerationContext()
+        context = plugin.GenerationContext(configuration=self.config)
+        context.output = os.path.join(ROOT_PATH,'temp/output')
+ 
+        if not os.path.exists(context.output):
+            os.makedirs(context.output)
+        
         implcontainer.generate(context)
-        return context.results
+        return context.generation_output
     
+    def test_eval_generation_context_access(self):
+        config = self.config
+        
+        self._execute_rules(r'^implml/eval_generation_context\.ruleml$')
+        dview = config.get_default_view()
+        self.assertEquals(dview.get_feature("EvalTest.output").value, os.path.join(ROOT_PATH,'temp/output'))
+        self.assertEquals(True, os.path.isfile(dview.get_feature("EvalTest.file").value))
+        
+        self.config.close()
+        self.project.close()
+        
+        if os.path.exists(os.path.join(ROOT_PATH, 'temp/output')):
+            shutil.rmtree(os.path.join(ROOT_PATH, 'temp/output'))
+            
     def test_arithmetic_operations(self):
         self._execute_rules(r'^implml/arithmetic\.ruleml$')
         
@@ -128,8 +146,8 @@
         config = self.config
         
         self.assert_setting_equals(config, 'EvalTest.FullSequence',
-            [['Full 1', '10', '1.5', 'true'],
-             ['Full 2', '20', '2.5', 'false']])
+            [['Full 1', 10, 1.5, True],
+             ['Full 2', 20, 2.5, False]])
         
         self._execute_rules(r'^implml/eval\.ruleml$')
         
@@ -144,10 +162,10 @@
         self.assert_setting_equals(config, 'EvalTest.Bit2Result', False)
         self.assert_setting_equals(config, 'EvalTest.Bit3Result', True)
         self.assert_setting_equals(config, 'EvalTest.FullSequence',
-            [['Full 1', '10', '1.5', 'true'],
-             ['Full 2', '20', '2.5', 'false'],
-             ['Stripped 1', '1', '0.1', 'false'],
-             ['Stripped 2', '2', '0.1', 'false']])
+            [['Full 1', 10, 1.5, True],
+             ['Full 2', 20, 2.5, False],
+             ['Stripped 1', 1, 0.1, False],
+             ['Stripped 2', 2, 0.1, False]])
         self.assert_setting_equals(config, 'EvalTest.EvalBuiltinResult', 'ruleml_test_config')
     
     def assert_setting_equals(self, config, setting, expected_value, msg=None):
@@ -159,28 +177,21 @@
     def test_rule_execution_results(self):
         results = self._execute_rules(r'^implml/rules\.ruleml$')
         
-        def r(index, input_refs, affected_refs):
-            return plugin.RelationExecutionResult(index         = index,
-                                                  source        = 'implml/rules.ruleml',
-                                                  input_refs    = input_refs,
-                                                  affected_refs = affected_refs)
-        expected = [
-            r(1,  ['imaker.imagetarget'],         ['imakerapi.outputLocation']),
-            r(6,  ['imakerapi.outputLocationY'],  ['imakerapi.outputLocationY']),
-            r(7,  ['operations.minus'],           ['operations.minus']),
-            r(8,  ['operations.minus1'],          ['operations.minus1']),
-            r(9,  ['operations.minus4'],          ['operations.minus4']),
-            r(10, ['operations.minus6'],          ['operations.minus6']),
-            r(11, [],                             ['StringConcatenationTest.Result1']),
-            r(12, [],                             ['StringConcatenationTest.Result2']),
-            r(13, [],                             ['StringConcatenationTest.Result3']),
-            r(14, [],                             ['StringConcatenationTest.Result4']),
-            r(15, [],                             ['StringConcatenationTest.Result5']),
-            r(16, [],                             ['StringConcatenationTest.Result6']),
-            r(17, [],                             [u'ударениÑ.ελληνικά']),
-        ]
-        
-        self.assertEquals(results, expected)
+        outputs = [(output.name, output.implementation.get_refs()) for output in results if output.type == 'ref']  
+        self.assertEquals(outputs, [(u'imakerapi.outputLocation', [u'imaker.imagetarget']), 
+                                   (u'imakerapi.outputLocationY', [u'imakerapi.outputLocationY']), 
+                                   (u'operations.minus', [u'operations.minus']), 
+                                   (u'operations.minus1', [u'operations.minus1']), 
+                                   (u'operations.minus4', [u'operations.minus4']), 
+                                   (u'operations.minus6', [u'operations.minus6']), 
+                                   (u'StringConcatenationTest.Result1', []), 
+                                   (u'StringConcatenationTest.Result2', []), 
+                                   (u'StringConcatenationTest.Result3', []), 
+                                   (u'StringConcatenationTest.Result4', []), 
+                                   (u'StringConcatenationTest.Result5', []), 
+                                   (u'StringConcatenationTest.Result6', []), 
+                                   (u'ударениÑ.ελληνικά', []),
+                                   (u'SequenceTest.Sequence1', [])])
             
 if __name__ == '__main__':
     unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/ruleplugin/xsd/ruleml3.xsd	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema 
+	xmlns:xs="http://www.w3.org/2001/XMLSchema"
+	targetNamespace="http://www.s60.com/xml/ruleml/3"
+	xmlns:ruleml="http://www.s60.com/xml/ruleml/3"
+	elementFormDefault="qualified">
+
+    <xs:element name="ruleml">
+        <xs:annotation>
+            <xs:documentation>
+                RuleML v3 implementation for specifying rules to execute.
+            </xs:documentation>
+        </xs:annotation>
+        <xs:complexType>
+            <xs:choice minOccurs="0" maxOccurs="unbounded">
+                <xs:element name="rule" type="xs:string">
+                    <xs:annotation>
+                        <xs:documentation>
+                            <![CDATA[
+                            <p>The rule element specifies a single rule to execute.</p><br/>
+                            
+                            <p>
+                            For example:<br/>
+                            <b>&lt;rule>${MyFeature.MySetting1} == 'test' configures ${MyFeature.MySetting2} = '1'&lt;/rule></b><br/>
+                            This would cause the value '1' to be assigned to the setting 'MyFeature.MySetting2'
+                            if the value of the setting 'MyFeature.MySetting1' is 'test'.
+                            </p><br/>
+                            
+                            <p>
+                            Arbitrary Python code can also be executed in the rule by enclosing the eval block
+                            with {% %}. For example:<br/>
+                            <b>&lt;rule>True configures ${MyFeature.MySetting} = {% get_some_value() %}&lt;/rule></b><br/>
+                            This would cause the value got from evaluating the Python function call
+                            get_some_value() to be assigned to the setting 'MyFeature.MySetting'.
+                            </p><br/>
+                            
+                            <p>
+                            Any settings referenced inside an eval block must be enclosed with ${ }
+                            to differentiate them from the Python code. For example:<br/>
+                              <b>&lt;rule>True configures ${MyFeature.MySetting} = {% get_some_value(${MyFeature.MySetting1}) %}&lt;/rule></b><br/>
+                            This would cause the value of the setting 'MyFeature.MySetting1' to be passed as a
+                            parameter to the function call.
+                            The actual feature object handled by ConE can be accessed by enclosing the setting
+                            reference with @{ }.
+                            </p><br/>                            
+                            
+                            <p>
+                            Any functions or variables (like get_some_value() in the above examples) need
+                            to be defined using eval_globals elements inside the ruleml element.
+                            </p>
+                            ]]>
+                        </xs:documentation>
+                    </xs:annotation>
+                </xs:element>
+                <xs:element name="eval_globals" type="ruleml:evalGlobalsType">
+                    <xs:annotation>
+                        <xs:documentation>
+                            An eval_globals block can be used to add Python variables
+                            or functions to the evaluation context of the rules contained
+                            within the current ruleml implementation. The Python code can be contained
+                            either directly inside the XML element or inside a file pointed by the
+                            'file' attribute.
+                        </xs:documentation>
+                    </xs:annotation>
+                </xs:element>
+            </xs:choice>
+        </xs:complexType>
+    </xs:element>
+    
+    <xs:complexType name="evalGlobalsType">
+        <xs:simpleContent>
+            <xs:extension base="xs:string">
+                <xs:attribute name="file" type="xs:string" use="optional">
+                    <xs:annotation>
+                        <xs:documentation>
+                            Path to the file containing the Python code of the eval_globals element.
+                            Should be a path relative to the current implementation file.
+                            Specifying the 'file' attribute causes the text content of the eval_globals
+                            element to be ignored.
+                        </xs:documentation>
+                    </xs:annotation>
+                </xs:attribute>
+            </xs:extension>
+        </xs:simpleContent>
+    </xs:complexType>
+</xs:schema>
\ No newline at end of file
--- a/configurationengine/source/plugins/common/ConeRulePlugin/setup.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeRulePlugin/setup.py	Tue Aug 10 14:29:28 2010 +0300
@@ -22,6 +22,7 @@
     name = "coneruleplugin",
     version = __version__,
     packages = find_packages(exclude=["*.tests"]),
+    package_data = {'ruleplugin': ['xsd/*.xsd']},
     test_suite = "ruleplugin.tests.collect_suite",
 
     # metadata for upload to PyPI
@@ -34,6 +35,5 @@
     zip_safe = True,
     
     # entrypoint info
-    entry_points={'cone.plugins.implmlreaders': ['ruleml_1 = ruleplugin.ruleml:RuleImplReader1',
-                                                 'ruleml_2 = ruleplugin.ruleml:RuleImplReader2']}
+    entry_points={'cone.plugins.implmlreaders': ['ruleml_3 = ruleplugin.ruleml:RuleImplReader']}
 )
--- a/configurationengine/source/plugins/common/ConeTemplatePlugin/setup.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/setup.py	Tue Aug 10 14:29:28 2010 +0300
@@ -22,6 +22,7 @@
     name = "conetemplateplugin",
     version = __version__,
     packages = find_packages(exclude=["*.tests"]),
+    package_data = {'templatemlplugin': ['xsd/*.xsd']},
     test_suite = "plugintemplate.tests.collect_suite",
 
     # metadata for upload to PyPI
--- a/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/templatemlplugin.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/templatemlplugin.py	Tue Aug 10 14:29:28 2010 +0300
@@ -19,11 +19,10 @@
 
 import re
 import os
-import sys
 import logging
 import codecs
-import xml.parsers.expat
-from jinja2 import Environment, PackageLoader, FileSystemLoader, Template, DictLoader
+import pkg_resources
+from jinja2 import Environment, DictLoader
 import traceback
 try:
     from cElementTree import ElementTree
@@ -47,10 +46,8 @@
         except ImportError:
             from xml.etree import ElementInclude
 
-import __init__
 
-from cone.public import exceptions,plugin,utils,api 
-from cone.confml import persistentconfml
+from cone.public import exceptions,plugin,utils 
 
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
 
@@ -62,8 +59,7 @@
     Implementation class of template plugin.
     """
     
-    IMPL_TYPE_ID = "templateml" 
-    
+    IMPL_TYPE_ID = "templateml"
     
     def __init__(self,ref,configuration, reader=None):
         """
@@ -75,24 +71,35 @@
         self.reader = reader
         if self.reader and self.reader.tags:
             self.set_tags(self.reader.tags)
+    
+    def __getstate__(self):
+        state = super(TemplatemlImpl, self).__getstate__()
+        state['reader'] = self.reader
+        return state
 
-    def get_context(self):
-        if TemplatemlImpl.context == None:
-            TemplatemlImpl.context = self.create_dict()
-        
-        return TemplatemlImpl.context
+    def get_context(self, generation_context):
+        ddict = generation_context.impl_data_dict 
+        if ddict.get('templateml_context', None) is None:
+            ddict['templateml_context'] = self.create_dict()
+        return ddict['templateml_context']
     
     def generate(self, context=None):
         """
         Generate the given implementation.
         """
-
-        self.create_output()
+        self.context = context
+        self.logger.debug('Generating from %s:%s' % (self.ref, self.lineno))
+        self.create_output(context)
         return 
     
-    def create_output(self, layers=None):
-        generator = Generator(self.reader.outputs, self.reader.filters, self.get_context(), self.configuration)
-        generator.generate(self.output, self.ref)
+    def create_output(self, generation_context):
+        templateml_context = self.get_context(generation_context)
+        templateml_context['gen_context'] = generation_context
+        if not generation_context.configuration:
+            generation_context.configuration = self.configuration
+        self.reader.expand_output_refs_by_default_view()
+        generator = Generator(self.reader.outputs, self.reader.filters, templateml_context, self)
+        generator.generate(generation_context, self.ref)
         return
     
     def get_refs(self):
@@ -100,6 +107,22 @@
         for output in self.reader.outputs:
             template = output.template.template
             refs.extend(self._extract_refs_from_template(template))
+            refs_oa = self._extract_refs_from_output_attribs(output)
+            for r in refs_oa:
+                if refs.count(r) < 1:
+                    refs.append(r)
+        return refs
+    
+    def _extract_refs_from_output_attribs(self, output):
+        refs = [] 
+        pattern = re.compile(r'\$\{(.*)\}', re.UNICODE)
+        for key, value in vars(output).iteritems():
+            m = pattern.search(str(value))
+            if m:
+                ref = m.group(1)
+                refs.append(ref)
+            if key == 'ref':
+                refs.append(value)
         return refs
     
     @classmethod
@@ -132,20 +155,19 @@
         for output in self.reader.outputs:
             if re.search("feat_list.*", output.template.template) != None:
                 return True
-        
-        refs_in_templates = self.get_refs()
-            
-        for ref in refs:
-            if ref in refs_in_templates:
-                return True
-        return False
+        return plugin.uses_ref(refs, self.get_refs())
     
     
     def list_output_files(self):
         """ Return a list of output files as an array. """
         result = []
         for output in self.reader.outputs:
-            result.append(os.path.normpath(os.path.join(self.output, output.path, output.filename)))
+            filename = ""
+            if output.fearef != None:
+                filename = self.configuration.get_default_view().get_feature(output.fearef).value
+            else:
+                filename = output.filename
+            result.append(os.path.normpath(os.path.join(self.output, output.path, filename)))
         return result
     
     def create_dict(self):
@@ -158,7 +180,7 @@
         if self.configuration:
             dview = self.configuration.get_default_view()
             feat_list = []
-            feat_tree = {}
+            feat_tree = FeatureDictProxy(None)
             
             def add_feature(feature, feature_dict):
                 fea_dict = FeatureDictProxy(feature)
@@ -202,7 +224,10 @@
     Parses a single templateml file
     """ 
     NAMESPACE = 'http://www.s60.com/xml/templateml/1'
+    NAMESPACE_ID = 'templateml'
+    ROOT_ELEMENT_NAME = 'templateml'
     FILE_EXTENSIONS = ['templateml']
+    NEWLINE_WIN_PARSE_OPTIONS = ['win', 'windows', 'dos', 'symbian', 'symbianos', 'cr+lf', 'crlf']
     
     def __init__(self, resource_ref=None, configuration=None):
         self.desc = None
@@ -220,6 +245,10 @@
         reader.from_elementtree(etree)
         return TemplatemlImpl(resource_ref, configuration, reader)
     
+    @classmethod
+    def get_schema_data(cls):
+        return pkg_resources.resource_string('templatemlplugin', 'xsd/templateml.xsd')
+    
     def fromstring(self, xml_string):
         etree = ElementTree.fromstring(xml_string)
         self.from_elementtree(etree)
@@ -289,6 +318,7 @@
                     logging.getLogger('cone.templateml').warning("In template element file attribute and text defined. Using template found from file attribute.")
                 template_text = _read_relative_file(self.configuration, file, self.resource_ref)
                 tempfile.set_template(template_text)
+        
         return tempfile
     
     def parse_outputs(self, etree):
@@ -297,51 +327,73 @@
         for output_elem in output_elems:
             if output_elem != None:
                 outputfile = OutputFile()
+                outputfile.set_output_elem(output_elem)
                 if output_elem.get('encoding') != None:
                     encoding = output_elem.get('encoding')
-                    # Check the encoding
-                    try:
-                        codecs.lookup(encoding)
-                    except LookupError:
-                        raise exceptions.ParseError("Invalid output encoding: %s" % encoding)
-                    
-                    if self.configuration != None:
-                        encoding = utils.expand_refs_by_default_view(encoding, self.configuration.get_default_view())
                     outputfile.set_encoding(encoding)
                 if output_elem.get('file') != None:
                     file = output_elem.get('file')
-                    
-                    if self.configuration != None:
-                        file = utils.expand_refs_by_default_view(file, self.configuration.get_default_view())
                     outputfile.set_filename(file)
                 if output_elem.get('dir') != None:
                     dir = output_elem.get('dir')
-                    if self.configuration != None:
-                        dir = utils.expand_refs_by_default_view(dir, self.configuration.get_default_view())
                     outputfile.set_path(dir)
                 if output_elem.get('ref'):
                     # Fetch the output value from a configuration reference
-                    fea = self.configuration.get_default_view().get_feature(output_elem.get('ref'))
-                    outputfile.set_filename(fea.value) 
+                    outputfile.set_fearef(output_elem.get('ref'))
                 if output_elem.get('bom'):
-                    outputfile.bom = output_elem.get('bom').lower() in ('1', 'true', 't', 'yes', 'y')
+                    outputfile.set_bom(output_elem.get('bom'))
+                if output_elem.get('newline', ''):
+                    outputfile.set_newline(output_elem.get('newline', ''))
+                
                 outputfile.set_template(self.parse_template(output_elem))
                 outputfile.set_filters(self.parse_filters(output_elem))
                 outputs.append(outputfile)
+                            
         return outputs
 
+    def expand_output_refs_by_default_view(self):
+        for output in self.outputs:     
+            if output.encoding:
+                if self.configuration != None:
+                    output.set_encoding(utils.expand_refs_by_default_view(output.encoding, self.configuration.get_default_view()))
+                try:
+                    codecs.lookup(output.encoding)
+                except LookupError:
+                    raise exceptions.ParseError("Invalid output encoding: %s" % output.encoding)
+            if output.filename:
+                if self.configuration != None:
+                    output.set_filename(utils.expand_refs_by_default_view(output.filename, self.configuration.get_default_view()))
+            if output.path:
+                if self.configuration != None:
+                    output.set_path(utils.expand_refs_by_default_view(output.path, self.configuration.get_default_view()))
+            if output.newline:
+                newline = output.newline
+                if self.configuration != None:
+                    newline = utils.expand_refs_by_default_view(output.newline, self.configuration.get_default_view())
+                if newline.lower() in self.NEWLINE_WIN_PARSE_OPTIONS:
+                    output.set_newline(OutputFile.NEWLINE_WIN)
+            if output.bom:
+                bom = output.bom
+                if self.configuration != None:
+                    bom = utils.expand_refs_by_default_view(output.bom, self.configuration.get_default_view())
+                output.bom = bom.lower() in ('1', 'true', 't', 'yes', 'y')
+            if output.fearef:
+                if self.configuration != None:
+                    fea = self.configuration.get_default_view().get_feature(output.fearef)
+                    output.set_filename(fea.value)
+
 class Generator(object):
     """
     Class that generates
     """
     
-    def __init__(self, outputs, filters, context, configuration=None):
+    def __init__(self, outputs, filters, context, implementation=None):
         self.outputs = outputs
         self.filters = filters
         self.context = context
-        self.configuration = configuration
+        self.implementation = implementation
     
-    def generate(self, output_path, ref):
+    def generate(self, generation_context, ref):
         """ 
         Generates output based on templates 
         """
@@ -349,35 +401,37 @@
         
             for output in self.outputs:
                 try:
-                    logging.getLogger('cone.templateml').debug(output)
-                    out_path = os.path.abspath(os.path.join(output_path, output.path))
-                    if out_path != '':
-                        if not os.path.exists(out_path):
-                            os.makedirs(out_path)
+                    out_path = output.path
+                    out_filepath = os.path.join(out_path, output.filename)
+                    logging.getLogger('cone.templateml').debug("Output file '%s', encoding '%s'" % (out_filepath, output.encoding))
                     
-                    out_file = open(os.path.join(out_path, output.filename), 'wb')
+                    out_file = generation_context.create_file(out_filepath, implementation=self.implementation)
                     
                     if output.template.path:
-                        output.template.template = _read_relative_file(self.configuration, output.template.path, ref)
+                        output.template.template = _read_relative_file(generation_context.configuration, output.template.path, ref)
                     
                     dict_loader = DictLoader({'template': output.template.template})
-                    env = Environment(loader=dict_loader)
+                    
+                    if output.newline == OutputFile.NEWLINE_WIN:
+                        env = Environment(loader=dict_loader, newline_sequence='\r\n')
+                    else:
+                        env = Environment(loader=dict_loader)
 
                     # Common filters
                     for filter in self.filters:
                         
                         if filter.path:
-                            filter.code = _read_relative_file(self.configuration, filter.path, ref)
+                            filter.code = _read_relative_file(generation_context.configuration, filter.path, ref)
                         
                         if not filter.code:
                             logging.getLogger('cone.templateml').warning("Skipping empty filter definition.")
                         else:
-                            env.filters[str(filter.name)] = eval(filter.code)
+                            env.filters[str(filter.name)] = eval(filter.code.replace('\r', ''))
                     
                     # Output file specific filters
                     for filter in output.filters:
                         if filter.path:
-                           filter.code = _read_relative_file(self.configuration, filter.path, ref)
+                            filter.code = _read_relative_file(generation_context.configuration, filter.path, ref)
                         
                         if not filter.code:
                             logging.getLogger('cone.templateml').warning("Skipping empty filter definition.")
@@ -391,7 +445,9 @@
                     out_file.close()
                     
                 except Exception, e:
-                    logging.getLogger('cone.templateml').error('Failed to generate template: %s %s\n%s' % (type(e), e, traceback.format_exc()) )
+                    utils.log_exception(
+                        logging.getLogger('cone.templateml'),
+                        '%r: Failed to generate output: %s: %s' % (self.implementation, type(e).__name__, e))
         else:
             logging.getLogger('cone.templateml').info('No (valid) templates found.')
     
@@ -426,6 +482,9 @@
         
 
 class OutputFile(object):
+    NEWLINE_UNIX = "unix"
+    NEWLINE_WIN = "win" 
+    
     def __init__(self):
         self.filename = ''
         self.path = ''
@@ -433,6 +492,12 @@
         self.template = TempFile()
         self.filters = []
         self.bom = None
+        self.newline = self.NEWLINE_UNIX
+        self.fearef = None
+        self.output_elem = None
+
+    def set_newline(self, newline):
+        self.newline = newline
 
     def set_filename(self, filename):
         self.filename = filename
@@ -447,14 +512,24 @@
         self.template = template
 
     def add_filter(self, filter):
-        self.filters.append(filters)
+        self.filters.append(filter)
     
     def set_filters(self, filters):
         self.filters = filters
     
+    def set_bom(self, bom):
+        self.bom = bom
+        
+    def set_fearef(self, ref):
+        self.fearef = ref
+        
+    def set_output_elem(self, output_elem):
+        self.output_elem = output_elem
+    
     def __eq__(self, other):
-        if (self.template == other.template and self.encoding == other.encoding and self.path == other.path and self.filename == other.filename and self.filters == other.filters):
-            return True
+        if other:
+            if (self.template == other.template and self.newline == other.newline and self.encoding == other.encoding and self.path == other.path and self.filename == other.filename and self.filters == other.filters):
+                return True
         return False
     
     def __repr__(self):
@@ -483,16 +558,13 @@
         self.filters.append(Filter(name, code))
         
     def __eq__(self, other):
-        if self.template == other.template and self.filters == other.filters and self.extensions == other.extensions and self.path == other.path:
-            return True
+        if other:
+            if self.template == other.template and self.filters == other.filters and self.extensions == other.extensions and self.path == other.path:
+                return True
         return False
+    
         
 class Filter(object):
-    def __init__(self, name, code):
-        self.name = name
-        self.code = code
-        self.path = None
-    
     def __init__(self):
         self.name = None
         self.code = None
@@ -522,14 +594,15 @@
         self._children = {}
     
     def _get_dict(self):
-        result = {
-            '_name'        : self._feature.name,
-            '_namespace'   : self._feature.namespace,
-            '_value'       : self._feature.get_value(),
-            '_fqr'         : self._feature.fqr,
-            '_type'        : self._feature.type}
-        for ref, obj in self._children.iteritems():
-            result[ref] = obj
+        result = {}
+        if self._feature is not None:
+            result.update({
+                '_name'        : self._feature.name,
+                '_namespace'   : self._feature.namespace,
+                '_value'       : self._feature.get_value(),
+                '_fqr'         : self._feature.fqr,
+                '_type'        : self._feature.type})
+        result.update(self._children)
         return result
     
     def items(self):
@@ -539,12 +612,21 @@
         return self._get_dict().iteritems()
     
     def __getitem__(self, name):
-        if name == '_name':         return self._feature.name        
-        elif name == '_namespace':  return self._feature.namespace
-        elif name == '_value':      return self._feature.get_value()
-        elif name == '_fqr':        return self._feature.fqr
-        elif name == '_type':       return self._feature.type
-        else:                       return self._children[name]
+        if self._feature is not None:
+            if name == '_name':         return self._feature.name
+            elif name == '_namespace':  return self._feature.namespace
+            elif name == '_value':      return self._feature.get_value()
+            elif name == '_fqr':        return self._feature.fqr
+            elif name == '_type':       return self._feature.type
+        
+        try:
+            return self._children[name]
+        except KeyError:
+            if self._feature:
+                msg = "Feature '%s.%s' not found" % (self._feature.fqr, name)
+            else:
+                msg = "Feature '%s' not found" % name
+            raise exceptions.NotFound(msg)
     
     def __setitem__(self, name, value):
         self._children[name] = value
--- a/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/__init__.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/__init__.py	Tue Aug 10 14:29:28 2010 +0300
@@ -18,19 +18,5 @@
 # Path to the directory where this file is located
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
 
-# Import common plug-in initialization
-PLUGINS_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../../../..'))
-assert os.path.split(PLUGINS_ROOT)[1] == 'plugins'
-if PLUGINS_ROOT not in sys.path: sys.path.append(PLUGINS_ROOT)
-import plugin_utils
-
+from testautomation import plugin_utils
 plugin_utils.plugin_test_init(ROOT_PATH)
-
-def collect_suite():
-    return plugin_utils.collect_test_suite_from_dir(ROOT_PATH)
-
-def runtests():
-    unittest.TextTestRunner(verbosity=2).run(collect_suite())
-
-if __name__ == '__main__':
-    runtests()
--- a/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/create_dict_test/expected_list.txt	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/create_dict_test/expected_list.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -45,13 +45,13 @@
             '_name': 'Sequence setting',
             '_namespace': 'Feature1',
             '_type': 'sequence',
-            '_value': [[['seq/file1.txt', None], 'false', 'item 1']],
+            '_value': [[['seq/file1.txt', None], False, 'item 1']],
             'BooleanSubSetting': {
                     '_fqr': 'Feature1.SequenceSetting.BooleanSubSetting',
                     '_name': 'Boolean sub-setting',
                     '_namespace': 'Feature1.SequenceSetting',
                     '_type': 'boolean',
-                    '_value': ['false'],
+                    '_value': [False],
                     },
             'FileSubSetting': {
                     '_fqr': 'Feature1.SequenceSetting.FileSubSetting',
@@ -151,13 +151,13 @@
     '_name': 'Sequence setting',
     '_namespace': 'Feature1',
     '_type': 'sequence',
-    '_value': [[['seq/file1.txt', None], 'false', 'item 1']],
+    '_value': [[['seq/file1.txt', None], False, 'item 1']],
     'BooleanSubSetting': {
             '_fqr': 'Feature1.SequenceSetting.BooleanSubSetting',
             '_name': 'Boolean sub-setting',
             '_namespace': 'Feature1.SequenceSetting',
             '_type': 'boolean',
-            '_value': ['false'],
+            '_value': [False],
             },
     'FileSubSetting': {
             '_fqr': 'Feature1.SequenceSetting.FileSubSetting',
@@ -228,7 +228,7 @@
     '_name': 'Boolean sub-setting',
     '_namespace': 'Feature1.SequenceSetting',
     '_type': 'boolean',
-    '_value': ['false'],
+    '_value': [False],
     },
 {
     '_fqr': 'Feature1.SequenceSetting.StringSubSetting',
@@ -248,13 +248,13 @@
             '_name': 'Sequence setting',
             '_namespace': 'Feature2',
             '_type': 'sequence',
-            '_value': [['1', 'seq1 2 item 1']],
+            '_value': [[1, 'seq1 2 item 1']],
             'IntSubSetting': {
                     '_fqr': 'Feature2.SequenceSetting.IntSubSetting',
                     '_name': 'Int sub-setting',
                     '_namespace': 'Feature2.SequenceSetting',
                     '_type': 'int',
-                    '_value': ['1'],
+                    '_value': [1],
                     },
             'StringSubSetting': {
                     '_fqr': 'Feature2.SequenceSetting.StringSubSetting',
@@ -284,13 +284,13 @@
     '_name': 'Sequence setting',
     '_namespace': 'Feature2',
     '_type': 'sequence',
-    '_value': [['1', 'seq1 2 item 1']],
+    '_value': [[1, 'seq1 2 item 1']],
     'IntSubSetting': {
             '_fqr': 'Feature2.SequenceSetting.IntSubSetting',
             '_name': 'Int sub-setting',
             '_namespace': 'Feature2.SequenceSetting',
             '_type': 'int',
-            '_value': ['1'],
+            '_value': [1],
             },
     'StringSubSetting': {
             '_fqr': 'Feature2.SequenceSetting.StringSubSetting',
@@ -305,7 +305,7 @@
     '_name': 'Int sub-setting',
     '_namespace': 'Feature2.SequenceSetting',
     '_type': 'int',
-    '_value': ['1'],
+    '_value': [1],
     },
 {
     '_fqr': 'Feature2.SequenceSetting.StringSubSetting',
--- a/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/create_dict_test/expected_tree.txt	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/create_dict_test/expected_tree.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -45,13 +45,13 @@
                     '_name': 'Sequence setting',
                     '_namespace': 'Feature1',
                     '_type': 'sequence',
-                    '_value': [[['seq/file1.txt', None], 'false', 'item 1']],
+                    '_value': [[['seq/file1.txt', None], False, 'item 1']],
                     'BooleanSubSetting': {
                             '_fqr': 'Feature1.SequenceSetting.BooleanSubSetting',
                             '_name': 'Boolean sub-setting',
                             '_namespace': 'Feature1.SequenceSetting',
                             '_type': 'boolean',
-                            '_value': ['false'],
+                            '_value': [False],
                             },
                     'FileSubSetting': {
                             '_fqr': 'Feature1.SequenceSetting.FileSubSetting',
@@ -101,13 +101,13 @@
                     '_name': 'Sequence setting',
                     '_namespace': 'Feature2',
                     '_type': 'sequence',
-                    '_value': [['1', 'seq1 2 item 1']],
+                    '_value': [[1, 'seq1 2 item 1']],
                     'IntSubSetting': {
                             '_fqr': 'Feature2.SequenceSetting.IntSubSetting',
                             '_name': 'Int sub-setting',
                             '_namespace': 'Feature2.SequenceSetting',
                             '_type': 'int',
-                            '_value': ['1'],
+                            '_value': [1],
                             },
                     'StringSubSetting': {
                             '_fqr': 'Feature2.SequenceSetting.StringSubSetting',
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/Layer1/implml/access_context.templateml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<templateml xmlns="http://www.s60.com/xml/templateml/1">
+    <output file="access_context.txt" encoding="UTF-8">
+        <template>Tags: {{ gen_context.tags }}</template>
+    </output>
+</templateml>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/Layer1/implml/feat_tree_iteration_test.templateml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<templateml xmlns="http://www.s60.com/xml/templateml/1">
+    <output file="feat_tree_iteration_test.txt" encoding="UTF-8">
+        <template>
+{% for key, feature in feat_tree.Feature1|dictsort -%}
+{%- if not key.startswith('_') -%} 
+{%- if feature._value -%} 
+{{ feature._name }} = {{ feature._value }}
+{% endif -%}
+{% endif -%}
+{% endfor -%}
+        </template>
+    </output>
+</templateml>
--- a/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/Layer1/implml/file1.templateml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/Layer1/implml/file1.templateml	Tue Aug 10 14:29:28 2010 +0300
@@ -2,11 +2,11 @@
 <templateml xmlns="http://www.s60.com/xml/templateml/1" xmlns:xi="http://www.w3.org/2001/XInclude">
     <desc>Description field text</desc>
 
-    <output file="test.txt" encoding="UTF-16">
+    <output file="test.txt" encoding="UTF-16" newline="unix">
         <template>ABC kissa kävelee</template>
     </output>
 
-    <output file="test2.txt" encoding="UTF-16" dir="output">
+    <output file="test2.txt" encoding="UTF-16" dir="output" newline="win">
        <template file="../../templates/template.txt"/>
     </output>
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/Layer1/implml/invalid_ref.templateml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<templateml xmlns="http://www.s60.com/xml/templateml/1" xmlns:xi="http://www.w3.org/2001/XInclude">
+    <output file="invalid_ref_1.txt" encoding="UTF-8" newline="unix">
+        <template >{{ feat_tree.Foo.Bar.Baz._value }}</template>
+    </output>
+    <output file="invalid_ref_2.txt" encoding="UTF-8" newline="unix">
+        <template >{{ feat_tree.Feature1.Nonexistent._value }}</template>
+    </output>
+    <output file="invalid_ref_3.txt" encoding="UTF-8" newline="unix">
+        <template >{{ feat_tree.Feature1.SequenceSetting.Nonexistent._value }}</template>
+    </output>
+</templateml>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/project/Layer1/implml/newline.templateml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<templateml xmlns="http://www.s60.com/xml/templateml/1" xmlns:xi="http://www.w3.org/2001/XInclude">
+    <output file="test_newline_unix.txt" encoding="UTF-8" dir="output" newline="unix">
+<template >line1
+line2
+</template>
+    </output>
+
+    <output file="test_newline_win.txt" encoding="UTF-8" dir="output" newline="win">
+<template >line1
+line2
+</template>
+    </output>
+</templateml>
--- a/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/runtests.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/runtests.py	Tue Aug 10 14:29:28 2010 +0300
@@ -14,6 +14,6 @@
 # Description: 
 #
 
-import __init__
-
-__init__.runtests()
+if __name__ == '__main__':
+    import nose
+    nose.core.run(argv=['collector','--include=unittest', '--verbosity=3'])
--- a/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/unittest_templatemlplugin.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/tests/unittest_templatemlplugin.py	Tue Aug 10 14:29:28 2010 +0300
@@ -15,7 +15,8 @@
 # Description: 
 #
 
-import unittest, os, shutil, sys
+import unittest, os, sys
+import logging
 
 try:
     from cElementTree import ElementTree, ElementInclude
@@ -28,9 +29,7 @@
         except ImportError:
             from xml.etree import ElementTree
 
-import __init__	
 from templatemlplugin import templatemlplugin
-from types import NoneType
 from testautomation.base_testcase import BaseTestCase
 from testautomation.utils import hex_to_bindata
 
@@ -77,10 +76,14 @@
              "<filter name=\"test_filter\" file=\"../../filter/filter.py\"/>" \
           "</templateml>"
 
-TEMPML1 = "<ns0:output encoding=\"ASCII\" file=\"test.txt\" xmlns:ns0=\"http://www.s60.com/xml/templateml/1\">" \
+TEMPML1 = "<ns0:output encoding=\"ASCII\" file=\"test.txt\" xmlns:ns0=\"http://www.s60.com/xml/templateml/1\" newline=\"win\">" \
           "<ns0:template extension=\"foo/foobar:MyClass\">ABCDF</ns0:template>" \
           "</ns0:output>"
 
+TEMPML1_LINUX = "<ns0:output encoding=\"ASCII\" file=\"test.txt\" xmlns:ns0=\"http://www.s60.com/xml/templateml/1\">" \
+          "<ns0:template extension=\"foo/foobar:MyClass\" newline=\"unix\">ABCDF</ns0:template>" \
+          "</ns0:output>"
+
 TEMPML2 = "<ns0:output encoding=\"ASCII\" file=\"test.txt\" xmlns:ns0=\"http://www.s60.com/xml/templateml/1\" xmlns:xi=\"http://www.w3.org/2001/XInclude\">" \
           "<ns0:template extension=\"foo/foobar:MyClass\">" \
           "include AABBCC" \
@@ -101,13 +104,9 @@
           
           
 def impl_from_resource(resource_ref, configuration):
-    doc_root = plugin.ReaderBase._read_xml_doc_from_resource(resource_ref, configuration)
-    readers = { templateml.TemplatemlImplReader.NAMESPACE: templateml.TemplatemlImplReader }
-    ns = utils.xml.split_tag_namespace(doc_root.tag)[0]
-    if ns in readers:
-        return readers[ns].read_impl(resource_ref, configuration, doc_root)
-    else:
-        return None
+    impls = plugin.ImplFactory.get_impls_from_file(resource_ref, configuration)
+    assert len(impls) == 1
+    return impls[0]
           
 class TestTemplatemlPlugin(BaseTestCase):    
     def setUp(self):
@@ -130,23 +129,24 @@
         impls.output = self.output
         impl_list = impls.get_implementations_by_file(resource_ref)
         self.assertEquals(1, len(impl_list))
-        return impl_list[0]
+        return (configuration,impl_list[0])
     
     def test_parse_desc(self):
-        impl = self.load_impl('Layer1/implml/file1.templateml')
+        (config,impl) = self.load_impl('Layer1/implml/file1.templateml')
         self.assertEqual("Description field text", impl.reader.desc)
 
     def test_parse_output_with_file_ref(self):
-        impl = self.load_impl('Layer1/implml/output_with_ref.templateml')
-        self.assertEquals(impl.list_output_files(), [os.path.normpath('output/confmlref_filename.txt')])
+        (config,impl) = self.load_impl('Layer1/implml/output_with_ref.templateml')
+        self.assertEquals(impl.list_output_files(), [os.path.normpath('confmlref_filename.txt')])
         
     def test_parse_outputs(self):
-        impl = self.load_impl('Layer1/implml/file1.templateml')
+        (config,impl) = self.load_impl('Layer1/implml/file1.templateml')
         outputs = []
         output1 = templatemlplugin.OutputFile()
         output1.set_encoding("UTF-16")
         output1.set_filename("test.txt")
         output1.set_path('')
+        output1.set_newline('unix')
         temp1 = templatemlplugin.TempFile()
         temp1.set_template(u'ABC kissa k\xe4velee')
         output1.set_template(temp1)
@@ -156,6 +156,7 @@
         output2.set_encoding("UTF-16")
         output2.set_filename("test2.txt")
         output2.set_path("output")
+        output2.set_newline('win')
         temp2 = templatemlplugin.TempFile()
         temp2.set_template('AABBCC')
         output2.set_template(temp2)
@@ -175,6 +176,7 @@
         self.assertEqual(outputs[0].encoding, impl.reader.outputs[0].encoding)
         self.assertEqual(outputs[0].filename, impl.reader.outputs[0].filename)
         self.assertEqual(outputs[0].path, impl.reader.outputs[0].path)
+        self.assertEqual(outputs[0].newline, impl.reader.outputs[0].newline)
         self.assertEqual(outputs[0].template.template, impl.reader.outputs[0].template.template)
         self.assertEqual(outputs[0].template.extensions, impl.reader.outputs[0].template.extensions)
         self.assertEqual(outputs[0].template.filters, impl.reader.outputs[0].template.filters)
@@ -184,6 +186,7 @@
         self.assertEqual(outputs[1].encoding, impl.reader.outputs[1].encoding)
         self.assertEqual(outputs[1].filename, impl.reader.outputs[1].filename)
         self.assertEqual(outputs[1].path, impl.reader.outputs[1].path)
+        self.assertEqual(outputs[1].newline, impl.reader.outputs[1].newline)
         #self.assertEqual(outputs[1].template.template, impl.reader.outputs[1].template.template)
         self.assertEqual(outputs[1].template.extensions, impl.reader.outputs[1].template.extensions)
         self.assertEqual(outputs[1].template.filters, impl.reader.outputs[1].template.filters)
@@ -265,7 +268,7 @@
         self.assertEqual(filters1[0].code, filter2.code)
         self.assertEqual(filters1[0], filter2)
         
-    def test_parse_template_filter(self):
+    def test_parse_template_filter_2(self):
         class DummyConfiguration(object):
             def get_resource(self, ref):
                 class DummyResource(object):
@@ -299,9 +302,10 @@
         
         self.remove_if_exists(os.path.normpath("output/output/test.txt"))
         
-        impl = self.load_impl('Layer1/implml/file2.templateml')
+        (config,impl) = self.load_impl('Layer1/implml/file2.templateml')
         #impl.context = {'name' : 'some value'}
-        impl.generate()
+        gc = plugin.GenerationContext(configuration=config)
+        impl.generate(gc)
         
         self.assertTrue(os.path.exists(os.path.normpath("output/output/test.txt")))
         result_file = None
@@ -312,12 +316,41 @@
         finally:
             if result_file != None: result_file.close()
     
+    def test_simple_generate_newline(self):
+        
+        self.remove_if_exists(os.path.normpath("output/output/test_newline_win.txt"))
+        self.remove_if_exists(os.path.normpath("output/output/test_newline_unix.txt"))
+        
+        (config,impl) = self.load_impl('Layer1/implml/newline.templateml')
+        gc = plugin.GenerationContext(configuration=config)
+        impl.generate(gc)
+        
+        self.assertTrue(os.path.exists(os.path.normpath("output/output/test_newline_win.txt")))
+        self.assertTrue(os.path.exists(os.path.normpath("output/output/test_newline_unix.txt")))
+
+        result_file_win = None
+        try:
+            result_file_win = open(os.path.normpath("output/output/test_newline_win.txt"),'rb')
+            line = result_file_win.read()
+            self.assertEquals(line, "line1\r\nline2")
+        finally:
+            if result_file_win != None: result_file_win.close()
+
+        result_file_unix = None
+        try:
+            result_file_unix = open(os.path.normpath("output/output/test_newline_unix.txt"), 'rb')
+            line = result_file_unix.read()
+            self.assertEquals(line, "line1\nline2")
+        finally:
+            if result_file_unix != None: result_file_unix.close()
+
     def test_simple_generate_prj3(self):
         
         self.remove_if_exists(os.path.normpath("output/output/test3.txt"))
         
-        impl = self.load_impl('Layer1/implml/file3.templateml')
-        impl.generate()
+        (config,impl) = self.load_impl('Layer1/implml/file3.templateml')
+        gc = plugin.GenerationContext(configuration=config)
+        impl.generate(gc)
         
         self.assertTrue(os.path.exists(os.path.normpath("output/output/test3.txt")))
         result_file = None
@@ -328,6 +361,7 @@
         finally:
             if result_file != None: result_file.close()
 
+
     def test_simple_generate_prj4_with_filters(self):
         
         self.remove_if_exists(os.path.normpath("output/output/test4a.txt"))
@@ -335,9 +369,10 @@
         self.remove_if_exists(os.path.normpath("output/output/test4c.txt"))
         self.remove_if_exists(os.path.normpath("output/output/test4d.txt"))
         
-        impl = self.load_impl('Layer1/implml/file4.templateml')
+        (config,impl) = self.load_impl('Layer1/implml/file4.templateml')
         #impl.context = {'name' : 'John Doe'}
-        impl.generate()
+        gc = plugin.GenerationContext(configuration=config)
+        impl.generate(gc)
         
         self.assertTrue(os.path.exists(os.path.normpath("output/output/test4a.txt")))
         self.assertTrue(os.path.exists(os.path.normpath("output/output/test4b.txt")))
@@ -389,9 +424,9 @@
         
         self.remove_if_exists(os.path.normpath("output/output/test_ext_temp_file.txt"))
         
-        impl = self.load_impl('Layer1/implml/external_tempfile.templateml')
-        
-        impl.generate()
+        (config,impl) = self.load_impl('Layer1/implml/external_tempfile.templateml')
+        gc = plugin.GenerationContext(configuration=config)
+        impl.generate(gc)
         
         self.assertTrue(os.path.exists(os.path.normpath("output/output/test_ext_temp_file.txt")))
         
@@ -417,8 +452,9 @@
         
         self.remove_if_exists(os.path.normpath("output/output/test5a.txt"))
         
-        impl = self.load_impl('Layer1/implml/file5.templateml')
-        impl.generate()
+        (config,impl) = self.load_impl('Layer1/implml/file5.templateml')
+        gc = plugin.GenerationContext(configuration=config)
+        impl.generate(gc)
         self.assertTrue(os.path.exists(os.path.normpath("output/output/test5a.txt")))
         
         result_file1 = None
@@ -437,8 +473,9 @@
         
         self.remove_if_exists(os.path.normpath("output/access_configuration.txt"))
         
-        impl = self.load_impl('Layer1/implml/access_configuration.templateml')
-        impl.generate()
+        (config,impl) = self.load_impl('Layer1/implml/access_configuration.templateml')
+        gc = plugin.GenerationContext(configuration=config)
+        impl.generate(gc)
         self.assertTrue(os.path.exists(os.path.normpath("output/access_configuration.txt")))
         
         result_file1 = None
@@ -453,12 +490,13 @@
             if result_file1 != None: result_file1.close()
     
     def test_create_context_dict1(self):
-        impl = self.load_impl('Layer1/implml/file6.templateml')
+        (config,impl) = self.load_impl('Layer1/implml/file6.templateml')
         impl.context = impl.create_dict()
-        impl.generate()
+        gc = plugin.GenerationContext(configuration=config)
+        impl.generate(gc)
     
     def test_list_output_files(self):
-        impl = self.load_impl('Layer1/implml/file1.templateml')
+        (config,impl) = self.load_impl('Layer1/implml/file1.templateml')
         impl.set_output_root('outdir')
         output_files = impl.list_output_files()
         expected = map(lambda n: os.path.normpath(n), [
@@ -471,7 +509,7 @@
         self.assertEquals(sorted(output_files), sorted(expected))
     
     def test_has_ref(self):
-        impl = self.load_impl('Layer1/implml/has_ref_template_test2.templateml')
+        (config,impl) = self.load_impl('Layer1/implml/has_ref_template_test2.templateml')
         self.assertEquals(impl.has_ref('Feature1.StringSetting_not_found'), False)
         self.assertEquals(impl.has_ref('Feature1.StringSetting1'), True)
         self.assertEquals(impl.has_ref('Feature2'), True)
@@ -480,7 +518,7 @@
         self.assertEquals(impl.has_ref('Feature1.UnicodeValueSetting'), True)
     
     def test_has_ref_external_template(self):
-        impl = self.load_impl('Layer1/implml/has_ref_template_test3.templateml')
+        (config,impl) = self.load_impl('Layer1/implml/has_ref_template_test3.templateml')
         self.assertEquals(impl.has_ref('Feature1.StringSetting_not_found'), False)
         self.assertEquals(impl.has_ref('Feature1.StringSetting1'), True)
         self.assertEquals(impl.has_ref('Feature2'), True)
@@ -489,7 +527,7 @@
         self.assertEquals(impl.has_ref('Feature1.UnicodeValueSetting'), True)
 
     def test_has_ref_with_featree(self):
-        impl = self.load_impl('Layer1/implml/has_ref_template_test.templateml')
+        (config,impl) = self.load_impl('Layer1/implml/has_ref_template_test.templateml')
         self.assertEquals(impl.has_ref('Feature1.StringSetting'), True)
         self.assertEquals(impl.has_ref('Feature2.StringSetting'), True)
     
@@ -501,8 +539,9 @@
         p = api.Project(fs)
         config = p.get_configuration('root1.confml')
         impls = plugin.get_impl_set(config,'unicode_template_test\.templateml$')
-        impls.output = OUTPUT_DIR
-        impls.generate()
+        gc = plugin.GenerationContext(output=OUTPUT_DIR,
+                                      configuration=config)
+        impls.generate(gc)
         self.assert_exists_and_contains_something(os.path.join(OUTPUT_DIR, "unicode_template_test.txt"))
         
         # Check that the output exists and contains expected lines
@@ -544,7 +583,7 @@
             self.write_data_to_file(filename, self.feature_list_to_str(expected_list))
             filename = os.path.join(dir, "actual.txt")
             self.write_data_to_file(filename, self.feature_list_to_str(feat_list))
-            self.fail("Feature tree is not what was expected, see the files in '%s'" % dir)
+            self.fail("Feature list is not what was expected, see the files in '%s'" % dir)
     
     def feature_tree_to_str(self, d, indent_amount=0):
         """
@@ -566,7 +605,7 @@
         
         for key, value in sorted(d.items(), key=key_func):
             temp.append(indent)
-            if isinstance(value, dict):
+            if isinstance(value, (dict, templatemlplugin.FeatureDictProxy)):
                 temp.append("%r: %s," % (key, self.feature_tree_to_str(value, indent_amount + INDENT_AMOUNT)))
             else:
                 temp.append("%r: %r," % (key, value))
@@ -582,7 +621,7 @@
         """
         temp = ['[\n']
         for item in lst:
-            if isinstance(item, dict):  temp.append(self.feature_tree_to_str(item))
+            if isinstance(item, (dict, templatemlplugin.FeatureDictProxy)):  temp.append(self.feature_tree_to_str(item))
             else:                       temp.append(repr(item))
             temp.append(',\n')
         temp.append(']')
@@ -592,9 +631,10 @@
     def test_utf_bom_support(self):
         OUTPUT_DIR = os.path.join(ROOT_PATH, 'temp/utf_bom_test')
         self.recreate_dir(OUTPUT_DIR)
-        impl = self.load_impl('Layer1/implml/utf_bom_test.templateml')
-        impl.set_output_root(OUTPUT_DIR)
-        impl.generate()
+        (config,impl) = self.load_impl('Layer1/implml/utf_bom_test.templateml')
+        gc = plugin.GenerationContext(output=OUTPUT_DIR,
+                                      configuration=config)
+        impl.generate(gc)
         
         def check(file, contents):
             FILE = os.path.join(OUTPUT_DIR, file)
@@ -635,8 +675,78 @@
             <output file="test.txt" encoding="foocode">foo</output>
           </templateml>"""
         reader = templatemlplugin.TemplatemlImplReader()
-        self.assertRaises(exceptions.ParseError, reader.fromstring, DATA)
+        reader.fromstring(DATA)
+        self.assertRaises(exceptions.ParseError, reader.expand_output_refs_by_default_view)
+    
+    def test_generate_from_template_with_feat_tree_iteration(self):
+        OUTPUT_DIR = os.path.join(ROOT_PATH, 'temp/feat_tree_iteration')
+        self.recreate_dir(OUTPUT_DIR)
+        (config,impl) = self.load_impl('Layer1/implml/feat_tree_iteration_test.templateml')
+        gc = plugin.GenerationContext(output=OUTPUT_DIR,
+                                      configuration=config)
+        impl.generate(gc)
+        
+        OUTPUT_FILE = os.path.join(OUTPUT_DIR, 'feat_tree_iteration_test.txt')
+        self.assert_exists_and_contains_something(OUTPUT_FILE)
+        self.assert_file_content_equals(OUTPUT_FILE,
+            u"\n"\
+            u"Boolean setting = True\n"\
+            u"File setting = default_file.txt\n"\
+            u"Folder setting = default_folder\n"\
+            u"Int setting = 10\n"\
+            u"Real setting = 3.14\n"\
+            u"Selection setting = 1\n"\
+            u"Sequence setting = [[[None, None], 1.25, [None, None], 128, 'def1', False, '1'], [[None, None], 1.5, [None, None], 256, 'def2', False, '1']]\n"\
+            u"String setting = John Doe\n"\
+            u"String for unicode value test = カタカナ\n".encode('utf-8'))
     
+    def test_generate_from_template_generation_context_accessed(self):
+        OUTPUT_DIR = os.path.join(ROOT_PATH, 'temp/access_context')
+        self.recreate_dir(OUTPUT_DIR)
+        (config,impl) = self.load_impl('Layer1/implml/access_context.templateml')
+        context = plugin.GenerationContext(output=OUTPUT_DIR,
+                                           configuration=config)
+        context.tags = {'sometag': ['foo', 'bar']}
+        impl.generate(context)
+        
+        OUTPUT_FILE = os.path.join(OUTPUT_DIR, 'access_context.txt')
+        self.assert_exists_and_contains_something(OUTPUT_FILE)
+        self.assert_file_content_equals(OUTPUT_FILE,
+            "Tags: {'sometag': ['foo', 'bar']}")
+    
+    def test_invalid_ref_in_template(self):
+        OUTPUT_DIR = os.path.join(ROOT_PATH, 'temp/invalid_ref')
+        self.recreate_dir(OUTPUT_DIR)
+        (config,impl) = self.load_impl('Layer1/implml/invalid_ref.templateml')
+        context = plugin.GenerationContext(output=OUTPUT_DIR,
+                                           configuration=config)
+        
+        log_file, handler, logger = self._prepare_log('invalid_refs.log')
+        impl.generate(context)
+        logger.removeHandler(handler)
+        
+        self.assert_file_content_equals(os.path.join(OUTPUT_DIR, 'invalid_ref_1.txt'), "")
+        self.assert_file_content_equals(os.path.join(OUTPUT_DIR, 'invalid_ref_2.txt'), "")
+        self.assert_file_content_equals(os.path.join(OUTPUT_DIR, 'invalid_ref_3.txt'), "")
+        
+        self.assert_file_contains(log_file,
+            ["TemplatemlImpl(ref='Layer1/implml/invalid_ref.templateml', type='templateml', lineno=2): Failed to generate output: NotFound: Feature 'Foo' not found",
+             "TemplatemlImpl(ref='Layer1/implml/invalid_ref.templateml', type='templateml', lineno=2): Failed to generate output: NotFound: Feature 'Feature1.Nonexistent' not found",
+             "TemplatemlImpl(ref='Layer1/implml/invalid_ref.templateml', type='templateml', lineno=2): Failed to generate output: NotFound: Feature 'Feature1.SequenceSetting.Nonexistent' not found"])
+    
+    def _prepare_log(self, log_file, level=logging.DEBUG, formatter="%(levelname)s - %(name)s - %(message)s", logger='cone'):
+        FULL_PATH = os.path.join(ROOT_PATH, "temp/logs", log_file)
+        self.remove_if_exists(FULL_PATH)
+        self.create_dir_for_file_path(FULL_PATH)
+        
+        handler = logging.FileHandler(FULL_PATH)
+        handler.setLevel(level)
+        frm = logging.Formatter(formatter)
+        handler.setFormatter(frm)
+        logger = logging.getLogger(logger)
+        logger.addHandler(handler)
+        
+        return [FULL_PATH, handler, logger]
 
 class TestExtractRefsFromTemplate(unittest.TestCase):
     def test_extract_refs_from_template(self):
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/ConeTemplatePlugin/templatemlplugin/xsd/templateml.xsd	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,158 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema 
+	xmlns:xs="http://www.w3.org/2001/XMLSchema"
+	xmlns:xi="http://www.w3.org/2001/XInclude"
+	xmlns:templ="http://www.s60.com/xml/templateml/1"
+	targetNamespace="http://www.s60.com/xml/templateml/1"
+	elementFormDefault="qualified">
+
+	 <xs:import namespace="http://www.w3.org/2001/XInclude" schemaLocation="XInclude.xsd"/>
+    
+    <xs:simpleType name="boolType">
+		<xs:restriction base="xs:string">
+            <xs:enumeration value="true"/>
+            <xs:enumeration value="false"/>
+        </xs:restriction>
+	</xs:simpleType>
+    
+    <xs:complexType name="tagType">
+		<xs:attribute name="name" type="xs:string"/>
+		<xs:attribute name="value" type="xs:string"/>
+	</xs:complexType>
+    
+	<xs:complexType name="templateType" mixed="true">
+		<xs:sequence>
+			<xs:element ref="xi:include" minOccurs="0" maxOccurs="unbounded"/>
+		</xs:sequence>	
+        <xs:attribute name="file" type="xs:string">
+            <xs:annotation>
+                <xs:documentation>
+                    Path to the file where the template's text is defined.
+                    Should be relative to the current implementation file.
+                </xs:documentation>
+            </xs:annotation>
+        </xs:attribute>
+	</xs:complexType>
+
+		
+	<xs:complexType name="outputType">
+		<xs:choice minOccurs="0" maxOccurs="unbounded">
+			<xs:element name="template" type="templ:templateType">
+                <xs:annotation>
+                    <xs:documentation><![CDATA[
+                        Specifies the template used to generate the current output file.<br/>
+                        <br/>
+                        The template text can either be specified directly in the element, or
+                        in a file specified by the 'file' attribute.
+                        ]]>
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:element>
+            <xs:element name="filter" type="templ:filterType">
+                <xs:annotation>
+                    <xs:documentation><![CDATA[
+                        Defines a filter usable in the Jinja template of the current output file.<br/>
+                        <br/>
+                        The filter is defined as a Python lambda function either directly in the element, or
+                        in a file specified by the 'file' attribute.
+                        ]]>
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:element>
+		</xs:choice>
+		<xs:attribute name="file" type="xs:string">
+            <xs:annotation>
+                <xs:documentation>
+                    The name of the output file.
+                </xs:documentation>
+            </xs:annotation>
+        </xs:attribute>
+		<xs:attribute name="dir" type="xs:string">
+            <xs:annotation>
+                <xs:documentation>
+                    The directory where the output file is generated.
+                </xs:documentation>
+            </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="ref" type="xs:string">
+            <xs:annotation>
+                <xs:documentation>
+                    The ConfML setting reference from where the output file's path and name are
+                    taken from.
+                </xs:documentation>
+            </xs:annotation>
+        </xs:attribute>
+		<xs:attribute name="encoding" type="xs:string">
+            <xs:annotation>
+                <xs:documentation>
+                    Defines the encoding of the output file. Can be any of the encodings supported
+                    by the Python codecs module (see http://docs.python.org/library/codecs.html#standard-encodings).
+                </xs:documentation>
+            </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="bom" type="templ:boolType" use="optional">
+            <xs:annotation>
+                <xs:documentation>
+                    <![CDATA[
+                    Defines the BOM scheme for Unicode encodings.<br/>
+                    <br/>
+                    If set to 'true', a BOM will always be written to the output file,
+                    if to 'false', it will never be. If the bom attribute is not defined
+                    at all, the BOM scheme is left up to the used encoding, e.g. UTF-16
+                    writes the BOM, but UTF-16-BE doesn't.<br/>
+                    <br/>
+                    For encodings other than Unicode, this attribute does nothing.
+                    ]]>
+                </xs:documentation>
+            </xs:annotation>
+        </xs:attribute>
+	</xs:complexType>
+	
+	<xs:complexType name="filterType" mixed="true">
+		<xs:sequence>
+			<xs:element ref="xi:include" minOccurs="0" maxOccurs="unbounded"/>
+		</xs:sequence>
+		<xs:attribute name="name" type="xs:NCName">
+            <xs:annotation>
+                <xs:documentation>
+                    The name of the filter, used to reference it from the Jinja template.
+                </xs:documentation>
+            </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="file" type="xs:string">
+            <xs:annotation>
+                <xs:documentation>
+                    Path to the file where the filter's Python code is defined.
+                    Should be relative to the current implementation file.
+                </xs:documentation>
+            </xs:annotation>
+        </xs:attribute>
+	</xs:complexType>
+	
+    <xs:element name="templateml">
+        <xs:complexType>
+            <xs:choice minOccurs="0" maxOccurs="unbounded">
+                <xs:element name="desc" type="xs:string"/>
+                <xs:element name="tag" type="templ:tagType"/>
+                <xs:element name="output" type="templ:outputType">
+                    <xs:annotation>
+                        <xs:documentation>
+                            Defines an output file, its properties and the template used to generate it.
+                        </xs:documentation>
+                    </xs:annotation>
+                </xs:element>
+                <xs:element name="filter" type="templ:filterType">
+                    <xs:annotation>
+                        <xs:documentation><![CDATA[
+                            Defines a filter usable in any template in the current TemplateML implementation.<br/>
+                            <br/>
+                            The filter is defined as a Python lambda function either directly in the element, or
+                            in a file referenced by the 'file' attribute.
+                            ]]>
+                        </xs:documentation>
+                    </xs:annotation>
+                </xs:element>
+            </xs:choice>
+        </xs:complexType>
+    </xs:element>
+</xs:schema>
\ No newline at end of file
--- a/configurationengine/source/plugins/common/integration-test/__init__.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/integration-test/__init__.py	Tue Aug 10 14:29:28 2010 +0300
@@ -14,24 +14,3 @@
 # Description: 
 #
 
-import unittest, os, sys
-
-ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
-PLUGIN_SOURCE_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../..'))
-assert os.path.split(PLUGIN_SOURCE_ROOT)[1] == 'plugins'
-
-# Import plugin_utils from the plug-in sources root
-if PLUGIN_SOURCE_ROOT not in sys.path: sys.path.append(PLUGIN_SOURCE_ROOT)
-import plugin_utils
-
-# Run integration test initialization
-plugin_utils.integration_test_init(ROOT_PATH)
-
-def collect_suite():
-    return plugin_utils.collect_test_suite_from_dir(ROOT_PATH)
-
-def runtests():
-    unittest.TextTestRunner(verbosity=2).run(collect_suite())
-
-if __name__ == '__main__':
-    runtests()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/integration-test/export_standalone.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,29 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+import os
+from testautomation.copy_dir import copy_dir
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+def export_standalone(target_path):
+    """
+    Export any needed extra data for standalone tests.
+    @param target_path: The path where the standalone tests are being exported.
+    """
+    copy_dir(source_dir             = os.path.join(ROOT_PATH, '../ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project'),
+             target_dir             = os.path.join(target_path, 'testdata/uses_layer_test_project'),
+             dir_ignore_functions   = [lambda d: d == '.svn'])
--- a/configurationengine/source/plugins/common/integration-test/runtests.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/integration-test/runtests.py	Tue Aug 10 14:29:28 2010 +0300
@@ -14,6 +14,6 @@
 # Description: 
 #
 
-import __init__
-
-__init__.runtests()
+if __name__ == '__main__':
+    import nose
+    nose.core.run(argv=['collector','--include=unittest', '--verbosity=3'])
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/integration-test/testdata/generate/expected/test.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,1 @@
+jeejeejee
\ No newline at end of file
--- a/configurationengine/source/plugins/common/integration-test/testdata/generate/project/custom/implml/unicode_rule_test.ruleml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/integration-test/testdata/generate/project/custom/implml/unicode_rule_test.ruleml	Tue Aug 10 14:29:28 2010 +0300
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<ruleml xmlns="http://www.s60.com/xml/ruleml/1">
-  <rule>True configures Feature1.StringSetting = Feature1.StringSetting + " " + BasicSettingTypesTest.StringSetting + u" (from rule: カタカナ)"</rule>
+<ruleml xmlns="http://www.s60.com/xml/ruleml/3">
+  <rule>True configures ${Feature1.StringSetting} = ${Feature1.StringSetting} + " " + ${BasicSettingTypesTest.StringSetting} + u" (from rule: カタカナ)"</rule>
 </ruleml>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/integration-test/testdata/generate/project/custom/implml/xcreate_file.implml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<container xmlns="http://www.symbianfoundation.org/xml/implml/1">
+    <tempVariable ref="TempText" type="string" value="jeejeejee"/>
+    <tempVariable ref="TempBool" type="boolean" value="true"/>
+
+    <commandml xmlns="http://www.s60.com/xml/commandml/1">
+    <condition value="${TempBool} == True">
+            <command executable="python" shell="True">
+		        <argument value="-c &quot;import os; if not os.path.exists('%CONE_OUT%'): os.makedirs('%CONE_OUT%')&quot;" />
+		    </command>
+            <command executable="python" shell="True">
+		        <argument value="-c &quot;open('%CONE_OUT%/test.txt','w').write('${TempText}')&quot;" />
+		    </command>
+		</condition>
+	    <condition value="${TempBool} == False">   
+	        <command executable="python" shell="true">
+			    <argument value="-c &quot;open('%CONE_OUT%/test2.txt','w').write('${TempText}')&quot;" />
+		    </command>
+		</condition>		    
+    </commandml>
+</container>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/integration-test/testdata/templateml_test_project/layer/confml/feature1.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,88 @@
+<configuration xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+  <feature ref="Feature1" name="Feature 1 (ConfML v1.0)">
+    <desc>Feature with all supported setting types for ConfML v1.0</desc>
+    <setting ref="RealSetting" name="Real setting" type="real">
+      <desc>A real setting</desc>
+    </setting>
+    <setting ref="IntSetting" name="Int setting" type="int">
+      <desc>An int setting</desc>
+    </setting>
+    <setting ref="StringSetting" name="String setting" type="string">
+      <desc>A string setting</desc>
+    </setting>
+    <setting ref="BooleanSetting" name="Boolean setting" type="boolean">
+      <desc>A boolean setting</desc>
+    </setting>
+    <setting ref="SelectionSetting" name="Selection setting" type="selection">
+      <desc>A selection setting</desc>
+      <option name="Option0" value="0"/>
+      <option name="Option1" value="1"/>
+      <option name="Option2" value="2"/>
+      <option name="Option3" value="3"/>
+      <option name="Option4" value="4"/>
+    </setting>
+    <setting ref="SequenceSetting" name="Sequence setting" type="sequence">
+      <desc>A sequence setting</desc>
+      <setting ref="RealSubSetting" name="Real sub-setting" type="real">
+        <desc>A real sub-setting</desc>
+      </setting>
+      <setting ref="IntSubSetting" name="Int sub-setting" type="int">
+        <desc>An int sub-setting</desc>
+      </setting>
+      <setting ref="StringSubSetting" name="String sub-setting" type="string">
+        <desc>A string sub-setting</desc>
+      </setting>
+      <setting ref="BooleanSubSetting" name="Boolean sub-setting" type="boolean">
+        <desc>A boolean sub-setting</desc>
+      </setting>
+      <setting ref="SelectionSubSetting" name="Selection sub-setting" type="selection">
+        <desc>A selection sub-setting</desc>
+        <option name="Op0" value="0"/>
+        <option name="Op1" value="1"/>
+        <option name="Op2" value="2"/>
+        <option name="Op3" value="3"/>
+        <option name="Op4" value="4"/>
+      </setting>
+    </setting>
+  </feature>
+  <data>
+    <Feature1>
+      <RealSetting>3.14</RealSetting>
+      <IntSetting>10</IntSetting>
+      <StringSetting>default string</StringSetting>
+      <BooleanSetting>true</BooleanSetting>
+      <SelectionSetting>1</SelectionSetting>
+      <SequenceSetting template="true">
+        <RealSubSetting>1.0</RealSubSetting>
+        <IntSubSetting>1</IntSubSetting>
+        <StringSubSetting>template</StringSubSetting>
+        <BooleanSubSetting>false</BooleanSubSetting>
+        <SelectionSubSetting>0</SelectionSubSetting>
+      </SequenceSetting>
+      <SequenceSetting>
+        <RealSubSetting>1.25</RealSubSetting>
+        <IntSubSetting>128</IntSubSetting>
+        <StringSubSetting>def1</StringSubSetting>
+        <BooleanSubSetting>false</BooleanSubSetting>
+        <SelectionSubSetting>1</SelectionSubSetting>
+      </SequenceSetting>
+      <SequenceSetting>
+        <RealSubSetting>1.5</RealSubSetting>
+        <IntSubSetting>256</IntSubSetting>
+        <StringSubSetting>def2</StringSubSetting>
+        <BooleanSubSetting>false</BooleanSubSetting>
+        <SelectionSubSetting>1</SelectionSubSetting>
+      </SequenceSetting>
+    </Feature1>
+  </data>
+  
+  <rfs>
+    <Feature1>
+      <RealSetting>true</RealSetting>
+      <IntSetting>false</IntSetting>
+      <StringSetting>false</StringSetting>
+      <BooleanSetting>true</BooleanSetting>
+      <SelectionSetting>true</SelectionSetting>
+    </Feature1>
+  </rfs>
+</configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/integration-test/testdata/templateml_test_project/layer/implml/output_test.implml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<container xmlns="http://www.symbianfoundation.org/xml/implml/1">
+    <container>
+    <!-- Define the temporary variables and set their values -->
+    <tempVariable ref="Tempfeature.Outputfile1" type="string" value="orig1.txt"/>
+    <tempVariable ref="Tempfeature.Outputfile2" type="string" value="orig2.txt"/>
+    <tempVariable ref="Tempfeature.Outputdir"   type="string" value="origdir"/>
+    <tempVariable ref="Tempfeature.Encoding"    type="string" value="ASCII"/>
+    <tempVariable ref="Tempfeature.BOM"         type="string" value="true"/>
+    <tempVariable ref="Tempfeature.Newline"     type="string" value="win"/>
+    
+    <!-- Print out the values to a text file -->
+    <container>
+    <phase name="normal"/>
+    <templateml xmlns="http://www.s60.com/xml/templateml/1">
+        <output file="${Tempfeature.Outputfile1}" dir="${Tempfeature.Outputdir}" encoding="${Tempfeature.Encoding}" bom="${Tempfeature.BOM}" newline="${Tempfeature.Newline}">
+            <template>
+TempFeature.Outputfile1:  {{ feat_tree.Tempfeature.Outputfile1._value }}
+TempFeature.Outputdir:    {{ feat_tree.Tempfeature.Outputdir._value }}
+TempFeature.Encoding:     {{ feat_tree.Tempfeature.Encoding._value }}
+TempFeature.BOM:          {{ feat_tree.Tempfeature.BOM._value }}
+TempFeature.Newline:      {{ feat_tree.Tempfeature.Newline._value }}
+Feature1.RealSetting:     {{ feat_tree.Feature1.RealSetting._value }}
+            </template>
+        </output>
+
+        <output ref="Tempfeature.Outputfile2" dir="${Tempfeature.Outputdir}" encoding="UTF-8" bom="true" newline="win">
+            <template>
+TempFeature.Outputfile2:  {{ feat_tree.Tempfeature.Outputfile2._value }}
+TempFeature.Outputdir:    {{ feat_tree.Tempfeature.Outputdir._value }}
+TempFeature.Encoding:     UTF-8
+TempFeature.BOM:          true
+TempFeature.Newline:      win
+            </template>
+        </output>
+    </templateml>
+    </container>
+    </container>
+</container>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/integration-test/testdata/templateml_test_project/layer/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,3 @@
+<configuration xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+<xi:include href="confml/feature1.confml" />
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/integration-test/testdata/templateml_test_project/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,3 @@
+<configuration xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+<xi:include href="layer/root.confml" />
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/common/integration-test/testdata/uses_layers_test_expected.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,37 @@
+Layer                        Tag     Expected Actual   Outcome
+assets/base/root.confml      uda     True     True     OK
+assets/base/root.confml      rofs3   True     True     OK
+assets/base/root.confml      rofs2   True     True     OK
+assets/layer1/root.confml    uda     True     True     OK
+assets/layer1/root.confml    rofs3   False    False    OK
+assets/layer1/root.confml    rofs2   False    False    OK
+assets/layer2/root.confml    uda     False    False    OK
+assets/layer2/root.confml    rofs3   False    False    OK
+assets/layer2/root.confml    rofs2   True     True     OK
+assets/layer3/root.confml    uda     False    False    OK
+assets/layer3/root.confml    rofs3   False    False    OK
+assets/layer3/root.confml    rofs2   False    False    OK
+assets/layer4/root.confml    uda     True     True     OK
+assets/layer4/root.confml    rofs3   False    False    OK
+assets/layer4/root.confml    rofs2   False    False    OK
+assets/layer5/root.confml    uda     False    False    OK
+assets/layer5/root.confml    rofs3   True     True     OK
+assets/layer5/root.confml    rofs2   False    False    OK
+assets/layer6/root.confml    uda     True     True     OK
+assets/layer6/root.confml    rofs3   True     True     OK
+assets/layer6/root.confml    rofs2   False    False    OK
+assets/layer7/root.confml    uda     True     True     OK
+assets/layer7/root.confml    rofs3   False    False    OK
+assets/layer7/root.confml    rofs2   False    False    OK
+assets/layer8/root.confml    uda     False    False    OK
+assets/layer8/root.confml    rofs3   False    False    OK
+assets/layer8/root.confml    rofs2   False    False    OK
+assets/layer9/root.confml    uda     True     True     OK
+assets/layer9/root.confml    rofs3   False    False    OK
+assets/layer9/root.confml    rofs2   False    False    OK
+assets/layer10/root.confml   uda     True     True     OK
+assets/layer10/root.confml   rofs3   False    False    OK
+assets/layer10/root.confml   rofs2   False    False    OK
+assets/layer11/root.confml   uda     True     True     OK
+assets/layer11/root.confml   rofs3   False    False    OK
+assets/layer11/root.confml   rofs2   False    False    OK
--- a/configurationengine/source/plugins/common/integration-test/unittest_generate.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/integration-test/unittest_generate.py	Tue Aug 10 14:29:28 2010 +0300
@@ -18,7 +18,7 @@
 # @author Lasse Salo
 
 import sys, os, shutil, unittest
-import __init__
+
 from testautomation.base_testcase import BaseTestCase
 from testautomation import zip_dir
 
@@ -27,7 +27,7 @@
 if sys.platform == "win32":
     CONE_SCRIPT = "cone.cmd"
 else:
-    CONE_SCRIPT = "cone.sh"
+    CONE_SCRIPT = "cone"
 
 def get_cmd(action='generate'):
     """Return the command used to run the ConE sub-action"""
@@ -42,6 +42,17 @@
         cmd = 'python "%s" %s' % (os.path.normpath(os.path.join(SOURCE_ROOT, 'scripts/cone_tool.py')), action)
         return cmd
 
+def get_uses_layer_test_project():
+    # If running from the working copy
+    dir1 = os.path.normpath(os.path.join(ROOT_PATH, '../ConeRulePlugin/ruleplugin/evals/tests/layer_filtering_project'))
+    if os.path.isdir(dir1): return dir1
+    
+    # If running from standalone
+    dir2 = os.path.normpath(os.path.join(ROOT_PATH, 'testdata/uses_layer_test_project'))
+    if os.path.isdir(dir2): return dir2
+    
+    raise RuntimeError("layers_used() test project found neither in '%s' nor '%s'!" % (dir1, dir2))
+
 class TestCommonGenerateAllImplsOnLastLayer(BaseTestCase):
     
     def _prepare_workdir(self, workdir):
@@ -67,6 +78,133 @@
         self.assert_exists_and_contains_something(project_zip)
         
         self._run_test_generate_all_impls_on_last_layer('temp/gen_ll2', project_zip)
+
+    def test_uses_layers_rule(self):
+        project_dir = get_uses_layer_test_project()
+        self.assert_exists_and_contains_something(project_dir)
+        
+        orig_workdir = os.getcwd()
+        workdir = self._prepare_workdir("temp/uses_layers_test")
+        os.chdir(workdir)
+        
+        try:
+            cmd = '%s -p "%s" --output output --add-setting-file imaker_variantdir.cfg' % (get_cmd(), project_dir)
+            self.run_command(cmd)
+            
+            self.assert_file_contents_equal(
+                os.path.join(ROOT_PATH, "testdata/uses_layers_test_expected.txt"),
+                "output/uses_layers_test.txt",
+                ignore_endline_style=True)
+        finally:
+            os.chdir(orig_workdir)
+            
+    def test_override_templateml_outputattribs_from_cmd_line(self):
+        project_dir = os.path.join(ROOT_PATH, 'testdata', 'templateml_test_project')
+        
+        #Added because of known bug #1018 (test data missing)
+        # Remove after fix ->
+        if os.path.isdir(project_dir):
+            if len(os.listdir(project_dir)) == 0:
+                self.fail("Path '%s' exists (is a directory) but does not contain anything)" % project_dir)
+        elif os.path.isfile(project_dir):
+            if os.stat(project_dir).st_size == 0:
+                self.fail("Path '%s' exists (is a file) but does not contain anything)" % project_dir)
+        else:
+            self.fail("Known bug #1018: Test data missing. Path '%s' does not exist" % project_dir)
+        # Remove after fix <-
+        
+        self.assert_exists_and_contains_something(project_dir)
+        
+        workdir = os.getcwd()
+        workdir = self._prepare_workdir(os.path.join('temp','gen_tmplml_out_from_cmd_line'))
+        
+        logfile = os.path.join(workdir, 'cone.log')
+        
+        file1 = os.path.join(workdir,'setdir','setfile1.txt')
+        file2 = os.path.join(workdir,'setdir','setfile2.txt')        
+        
+        cmd = ['%(cone_cmd)s',
+               '-p "%(project)s"',
+               '-c root.confml',
+               '--output "%(output)s"',
+               '--log-file="%(log_file)s"',
+               '--all-layers',
+               '--set=Tempfeature.Outputfile1=setfile1.txt',
+               '--set=Tempfeature.Outputfile2=setfile2.txt',
+               '--set=Tempfeature.Outputdir=setdir',
+               '--set=Tempfeature.Encoding=UTF-16',
+               '--set=Tempfeature.BOM=false',
+               '--set=Tempfeature.Newline=unix',]
+        cmd = ' '.join(cmd) % {'cone_cmd':      get_cmd(),
+                               'project':       project_dir,
+                               'output':        workdir,
+                               'log_file':      logfile}
+
+        self.run_command(cmd)
+        
+        self.assert_exists_and_contains_something(os.path.join(workdir,'setdir'))
+        self.assert_file_contains(file1, ['TempFeature.Outputfile1:  setfile1.txt',
+                                          'TempFeature.Outputdir:    setdir',
+                                          'TempFeature.Encoding:     UTF-16',
+                                          'TempFeature.BOM:          false',
+                                          'TempFeature.Newline:      unix'],
+                                          encoding='UTF-16')
+        self.assert_file_contains(file2, ['TempFeature.Outputfile2:  setfile2.txt',
+                                          'TempFeature.Outputdir:    setdir',
+                                          'TempFeature.Encoding:     UTF-8',
+                                          'TempFeature.BOM:          true',
+                                          'TempFeature.Newline:      win'])
+        
+
+    def test_set_tempvariables_as_templateml_outputattribs(self):
+        project_dir = os.path.join(ROOT_PATH, 'testdata', 'templateml_test_project')
+        
+        #Added because of known bug #1018 (test data missing)
+        # Remove after fix ->
+        if os.path.isdir(project_dir):
+            if len(os.listdir(project_dir)) == 0:
+                self.fail("Path '%s' exists (is a directory) but does not contain anything)" % project_dir)
+        elif os.path.isfile(project_dir):
+            if os.stat(project_dir).st_size == 0:
+                self.fail("Path '%s' exists (is a file) but does not contain anything)" % project_dir)
+        else:
+            self.fail("Known bug #1018: Test data missing. Path '%s' does not exist" % project_dir)
+        # Remove after fix <-
+        
+        self.assert_exists_and_contains_something(project_dir)
+        
+        workdir = os.getcwd()
+        workdir = self._prepare_workdir(os.path.join('temp','gen_tmplml_out_from_ref'))
+        
+        logfile = os.path.join(workdir, 'cone.log')
+        
+        file1 = os.path.join(workdir,'origdir','orig1.txt')
+        file2 = os.path.join(workdir,'origdir','orig2.txt')
+        
+        cmd = ['%(cone_cmd)s',
+               '-p "%(project)s"',
+               '-c root.confml',
+               '--output "%(output)s"',
+               '--log-file="%(log_file)s"',
+               '--all-layers',]
+        cmd = ' '.join(cmd) % {'cone_cmd':      get_cmd(),
+                               'project':       project_dir,
+                               'output':        workdir,
+                               'log_file':      logfile}
+
+        self.run_command(cmd)
+        
+        self.assert_exists_and_contains_something(os.path.join(workdir,'origdir'))
+        self.assert_file_contains(file1, ['TempFeature.Outputfile1:  orig1.txt',
+                                          'TempFeature.Outputdir:    origdir',
+                                          'TempFeature.Encoding:     ASCII',
+                                          'TempFeature.BOM:          true',
+                                          'TempFeature.Newline:      win'])
+        self.assert_file_contains(file2, ['TempFeature.Outputfile2:  orig2.txt',
+                                          'TempFeature.Outputdir:    origdir',
+                                          'TempFeature.Encoding:     UTF-8',
+                                          'TempFeature.BOM:          true',
+                                          'TempFeature.Newline:      win'])
     
     def _run_test_generate_all_impls_on_last_layer(self, workdir, project):
         # Create a temp workdir and go there to run the test
@@ -83,5 +221,8 @@
         finally:
             os.chdir(orig_workdir)
 
+
+
+
 if __name__ == '__main__':
       unittest.main()
--- a/configurationengine/source/plugins/common/runtests.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/common/runtests.py	Tue Aug 10 14:29:28 2010 +0300
@@ -14,19 +14,6 @@
 # Description:
 #
 
-import sys, os, re, unittest
-
-ROOT_PATH = os.path.abspath(os.path.dirname(__file__))
-
-PLUGINS_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '..'))
-assert os.path.split(PLUGINS_ROOT)[1] == 'plugins'
-if PLUGINS_ROOT not in sys.path: sys.path.append(PLUGINS_ROOT)
-import plugin_utils
-
-if __name__ == "__main__":
-    # Collect a list of plug-in source paths and plug-in module names
-    paths_and_modnames = plugin_utils.find_plugin_sources(ROOT_PATH)
-    # Create a test suite from them
-    suite = plugin_utils.collect_suite_from_source_list(paths_and_modnames)
-    # Run the suite
-    unittest.TextTestRunner(verbosity=2).run(suite)
+if __name__ == '__main__':
+    import nose
+    nose.core.run(argv=['collector','--include=unittest', '--verbosity=3'])
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/ConeExamplePlugin/__init__.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,16 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
--- a/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/exampleml_impl.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/exampleml_impl.py	Tue Aug 10 14:29:28 2010 +0300
@@ -39,7 +39,7 @@
     def generate(self, context=None):
         for output in self.output_objects:
             self.logger.debug("Generating '%s'" % output.get_output_file(self.output, self.configuration))
-            output.write_to_file(self.output, self.configuration)
+            output.write_to_file(self.output, context)
     
     def list_output_files(self):
         files = []
@@ -51,4 +51,8 @@
         refs = []
         for output in self.output_objects:
             refs.extend(output.get_refs())
+        # return None in case there are no refs in the implementations 
+        # to prevent filtering based on refs
+        if not refs:
+            refs = None
         return refs
--- a/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/exampleml_model.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/exampleml_model.py	Tue Aug 10 14:29:28 2010 +0300
@@ -25,10 +25,11 @@
     Class representing an ExampleML output element.
     """
     
-    def __init__(self, file, encoding, text):
+    def __init__(self, file, encoding, text, lineno=None):
         self.file = file
         self.encoding = encoding
         self.text = text
+        self.lineno = lineno
     
     def get_refs(self):
         """
@@ -44,26 +45,22 @@
         file = utils.expand_refs_by_default_view(self.file, config.get_default_view())
         return os.path.normpath(os.path.join(output_dir, file))
     
-    def write_to_file(self, output_dir, config):
+    def write_to_file(self, output_dir, context):
         """
         Write the text file specified by this output object to the
         given output directory.
         """
         # Get the actual output path and encoding
-        file_path = self.get_output_file(output_dir, config)
-        encoding = utils.expand_refs_by_default_view(self.encoding, config.get_default_view())
+        file_path = self.get_output_file(output_dir, context.configuration)
+        encoding = utils.expand_refs_by_default_view(self.encoding, context.configuration.get_default_view())
         
         # Generate the binary data to write
-        text = utils.expand_refs_by_default_view(self.text, config.get_default_view())
+        text = utils.expand_refs_by_default_view(self.text, context.configuration.get_default_view())
         data = text.encode(encoding)
         
-        # Make sure that the output directory exists
-        dir = os.path.dirname(file_path)
-        if dir != '' and not os.path.exists(dir):
-            os.makedirs(dir)
         
         # Write the file.
-        f = open(file_path, "wb")
+        f = context.create_file(file_path, mode="wb")
         try:        f.write(data)
         finally:    f.close()
     
--- a/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/exampleml_reader.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/exampleml_reader.py	Tue Aug 10 14:29:28 2010 +0300
@@ -14,12 +14,16 @@
 # Description:
 #
 
-from cone.public import exceptions, plugin
+import pkg_resources
+from cone.public import exceptions, plugin, utils
 import exampleml_impl
 import exampleml_model
 
 class ExamplemlReader(plugin.ReaderBase):
     NAMESPACE = 'http://www.example.org/xml/exampleml/1'
+    NAMESPACE_ID = 'exampleml'
+    ROOT_ELEMENT_NAME = 'exampleml'
+    SCHEMA_PROBLEM_SUB_ID = 'exampleml'
     FILE_EXTENSIONS = ['exampleml']
     
     @classmethod
@@ -28,6 +32,10 @@
         outputs = reader._read_outputs(etree)
         return exampleml_impl.ExamplemlImpl(resource_ref, configuration, outputs)
     
+    @classmethod
+    def get_schema_data(cls):
+        return pkg_resources.resource_string('examplemlplugin', 'xsd/exampleml.xsd')
+    
     def _read_outputs(self, elem):
         """
         Read output objects from the given XML element.
@@ -46,4 +54,5 @@
             raise exceptions.ParseError("Element <output> does not have the mandatory 'file' attribute")
         return exampleml_model.Output(file     = file,
                                       encoding = elem.get('encoding', 'UTF-8'),
-                                      text     = elem.text or '')
\ No newline at end of file
+                                      text     = elem.text or '',
+                                      lineno   = utils.etree.get_lineno(elem))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/exampleml_validators.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,69 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+
+import codecs
+
+from cone.public import api, exceptions, utils
+from cone.validation.implmlvalidation import ImplValidatorBase
+from examplemlplugin import exampleml_impl
+
+class ExamplemlValidatorBase(ImplValidatorBase):
+    SUPPORTED_IMPL_CLASSES = exampleml_impl.ExamplemlImpl
+
+class ExamplemlReferenceValidator(ExamplemlValidatorBase):
+    PROBLEM_TYPES = ['model.implml.exampleml.invalid_ref']
+    
+    def validate(self):
+        for output in self.impl.output_objects:
+            # Collect all refs
+            refs = set()
+            for ref in utils.extract_delimited_tokens(output.text):     refs.add(ref)
+            for ref in utils.extract_delimited_tokens(output.encoding): refs.add(ref)
+            for ref in utils.extract_delimited_tokens(output.file):     refs.add(ref)
+            
+            for ref in refs:
+                self.check_feature_reference(ref, output.lineno, self.PROBLEM_TYPES[0])
+
+class ExamplemlEncodingValidator(ExamplemlValidatorBase):
+    PROBLEM_TYPES = ['model.implml.exampleml.invalid_encoding']
+    
+    def validate(self):
+        for output in self.impl.output_objects:
+            encoding = None
+            try:
+                encoding = utils.expand_refs_by_default_view(
+                    output.encoding,
+                    self.context.configuration.get_default_view(),
+                    catch_not_found=False)
+            except exceptions.NotFound:
+                # Ignore invalid setting references, they are validated
+                # in another validator
+                continue
+            
+            if encoding is not None:
+                # Check the encoding
+                try:
+                    codecs.lookup(encoding)
+                except LookupError:
+                    prob = api.Problem(
+                        msg = u"Invalid encoding '%s'" % encoding,
+                        type = self.PROBLEM_TYPES[0],
+                        line = output.lineno,
+                        file = self.impl.ref)
+                    self.context.problems.append(prob)
+
+VALIDATOR_CLASSES = [ExamplemlReferenceValidator, ExamplemlEncodingValidator]
--- a/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/__init__.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/__init__.py	Tue Aug 10 14:29:28 2010 +0300
@@ -13,24 +13,11 @@
 #
 # Description: 
 #
+
 import sys, os, unittest
 
 # Path to the directory where this file is located
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
 
-# Import common plug-in initialization
-PLUGINS_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../../../..'))
-assert os.path.split(PLUGINS_ROOT)[1] == 'plugins'
-if PLUGINS_ROOT not in sys.path: sys.path.append(PLUGINS_ROOT)
-import plugin_utils
-
+from testautomation import plugin_utils
 plugin_utils.plugin_test_init(ROOT_PATH)
-
-def collect_suite():
-    return plugin_utils.collect_test_suite_from_dir(ROOT_PATH)
-
-def runtests():
-    unittest.TextTestRunner(verbosity=2).run(collect_suite())
-
-if __name__ == '__main__':
-    runtests()
--- a/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/gen_expected/multitest1_1.txt	Fri Mar 12 08:30:17 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-Multitest impl 1 output 1
\ No newline at end of file
Binary file configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/gen_expected/multitest1_2.txt has changed
Binary file configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/gen_expected/multitest2_1.txt has changed
Binary file configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/gen_expected/multitest2_2.txt has changed
Binary file configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/gen_expected/some/dir/out1.txt has changed
--- a/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/gen_expected/some/dir2/out2.txt	Fri Mar 12 08:30:17 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-Test 1 output 2 €
\ No newline at end of file
--- a/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/gen_expected/test.txt	Fri Mar 12 08:30:17 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-Value from ConfML: ελληνικά (unicode test), <&> (special char test)
\ No newline at end of file
--- a/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/project/Layer/confml/test.confml	Fri Mar 12 08:30:17 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<configuration xmlns="http://www.s60.com/xml/confml/1" name="TestFeature" version="1">
-  <feature ref="TestFeature" name="Settings for testing">
-    <setting ref="Value1" type="string"/>
-  
-    <setting ref="Output1File" type="string"/>
-    <setting ref="Output1Encoding" type="string"/>
-    
-    <setting ref="Output2Dir" type="string"/>
-    <setting ref="Output2Filename" type="string"/>
-  </feature>
-  <data>
-    <TestFeature>
-      <Value1>ελληνικά (unicode test), &lt;&amp;> (special char test)</Value1>
-    
-      <Output1File>some/dir/out1.txt</Output1File>
-      <Output1Encoding>UTF-16-LE</Output1Encoding>
-      
-      <Output2Dir>some/dir2</Output2Dir>
-      <Output2Filename>out2.txt</Output2Filename>
-    </TestFeature>
-  </data>
-</configuration>
--- a/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/project/Layer/implml/multitest.implml	Fri Mar 12 08:30:17 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<container xmlns="http://www.symbianfoundation.org/xml/implml/1">
-    <!-- Testing that multiple implementations in a single file works correctly -->
-    
-    <test1 xmlns="http://www.example.org/xml/exampleml/1">
-        <output file="multitest1_1.txt" encoding="UTF-8">Multitest impl 1 output 1</output>
-        <output file="multitest1_2.txt" encoding="UTF-16-LE">Multitest impl 1 output 2</output>
-    </test1>
-    
-    <!-- Also test that special characters and unicode characters outside the ASCII range work -->
-    <test2 xmlns="http://www.example.org/xml/exampleml/1">
-        <output file="multitest2_1.txt" encoding="UTF-16-BE">Unicode test: ελληνικά</output>
-        <output file="multitest2_2.txt" encoding="UTF-16-LE">Special char test: &lt;&amp;></output>
-    </test2>
-</container>
\ No newline at end of file
--- a/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/project/Layer/implml/test.exampleml	Fri Mar 12 08:30:17 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<exampleml xmlns="http://www.example.org/xml/exampleml/1">
-    <output file="test.txt">Value from ConfML: ${TestFeature.Value1}</output>
-    <output file="${TestFeature.Output1File}" encoding="${TestFeature.Output1Encoding}">Test test</output>
-    <output file="${TestFeature.Output2Dir}/${TestFeature.Output2Filename}" encoding="windows-1252">Test 1 output 2 €</output>
-</exampleml>
\ No newline at end of file
--- a/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/project/Layer/root.confml	Fri Mar 12 08:30:17 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<confml:configuration xmlns:confml="http://www.s60.com/xml/confml/1" xmlns:xi="http://www.w3.org/2001/XInclude" name="Layer 1">
-  <xi:include href="confml/test.confml#/"/>
-</confml:configuration>
Binary file configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/project/root.confml has changed
--- a/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/runtests.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/runtests.py	Tue Aug 10 14:29:28 2010 +0300
@@ -14,6 +14,6 @@
 # Description: 
 #
 
-import __init__
-
-__init__.runtests()
+if __name__ == '__main__':
+    import nose
+    nose.core.run(argv=['collector','--include=unittest', '--verbosity=3'])
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/testdata/generation/expected/multitest1_1.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,1 @@
+Multitest impl 1 output 1
\ No newline at end of file
Binary file configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/testdata/generation/expected/multitest1_2.txt has changed
Binary file configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/testdata/generation/expected/multitest2_1.txt has changed
Binary file configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/testdata/generation/expected/multitest2_2.txt has changed
Binary file configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/testdata/generation/expected/some/dir/out1.txt has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/testdata/generation/expected/some/dir2/out2.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,1 @@
+Test 1 output 2 €
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/testdata/generation/expected/test.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,1 @@
+Value from ConfML: ελληνικά (unicode test), <&> (special char test)
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/testdata/generation/project/Layer/confml/test.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/1" name="TestFeature" version="1">
+  <feature ref="TestFeature" name="Settings for testing">
+    <setting ref="Value1" type="string"/>
+  
+    <setting ref="Output1File" type="string"/>
+    <setting ref="Output1Encoding" type="string"/>
+    
+    <setting ref="Output2Dir" type="string"/>
+    <setting ref="Output2Filename" type="string"/>
+  </feature>
+  <data>
+    <TestFeature>
+      <Value1>ελληνικά (unicode test), &lt;&amp;> (special char test)</Value1>
+    
+      <Output1File>some/dir/out1.txt</Output1File>
+      <Output1Encoding>UTF-16-LE</Output1Encoding>
+      
+      <Output2Dir>some/dir2</Output2Dir>
+      <Output2Filename>out2.txt</Output2Filename>
+    </TestFeature>
+  </data>
+</configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/testdata/generation/project/Layer/implml/multitest.implml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<container xmlns="http://www.symbianfoundation.org/xml/implml/1">
+    <!-- Testing that multiple implementations in a single file works correctly -->
+    
+    <exampleml xmlns="http://www.example.org/xml/exampleml/1">
+        <output file="multitest1_1.txt" encoding="UTF-8">Multitest impl 1 output 1</output>
+        <output file="multitest1_2.txt" encoding="UTF-16-LE">Multitest impl 1 output 2</output>
+    </exampleml>
+    
+    <!-- Also test that special characters and unicode characters outside the ASCII range work -->
+    <exampleml xmlns="http://www.example.org/xml/exampleml/1">
+        <output file="multitest2_1.txt" encoding="UTF-16-BE">Unicode test: ελληνικά</output>
+        <output file="multitest2_2.txt" encoding="UTF-16-LE">Special char test: &lt;&amp;></output>
+    </exampleml>
+</container>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/testdata/generation/project/Layer/implml/test.exampleml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<exampleml xmlns="http://www.example.org/xml/exampleml/1">
+    <output file="test.txt">Value from ConfML: ${TestFeature.Value1}</output>
+    <output file="${TestFeature.Output1File}" encoding="${TestFeature.Output1Encoding}">Test test</output>
+    <output file="${TestFeature.Output2Dir}/${TestFeature.Output2Filename}" encoding="windows-1252">Test 1 output 2 €</output>
+</exampleml>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/testdata/generation/project/Layer/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<confml:configuration xmlns:confml="http://www.s60.com/xml/confml/1" xmlns:xi="http://www.w3.org/2001/XInclude" name="Layer 1">
+  <xi:include href="confml/test.confml#/"/>
+</confml:configuration>
Binary file configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/testdata/generation/project/root.confml has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/testdata/validation/expected/invalid_encoding.exampleml.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,3 @@
+Problem(msg=u"Invalid encoding 'foobar'", type='model.implml.exampleml.invalid_encoding', line=7, file='Layer1/implml/invalid_encoding.exampleml', severity='error')
+Problem(msg=u"Invalid encoding 'foocode'", type='model.implml.exampleml.invalid_encoding', line=6, file='Layer1/implml/invalid_encoding.exampleml', severity='error')
+Problem(msg=u"Setting 'Foo.Bar' not found in configuration", type='model.implml.exampleml.invalid_ref', line=10, file='Layer1/implml/invalid_encoding.exampleml', severity='error')
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/testdata/validation/expected/invalid_refs.exampleml.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,6 @@
+Problem(msg=u"Setting 'Foo.MoreText' not found in configuration", type='model.implml.exampleml.invalid_ref', line=4, file='Layer1/implml/invalid_refs.exampleml', severity='error')
+Problem(msg=u"Setting 'Foo.OutputDir' not found in configuration", type='model.implml.exampleml.invalid_ref', line=5, file='Layer1/implml/invalid_refs.exampleml', severity='error')
+Problem(msg=u"Setting 'Foo.OutputEncoding' not found in configuration", type='model.implml.exampleml.invalid_ref', line=4, file='Layer1/implml/invalid_refs.exampleml', severity='error')
+Problem(msg=u"Setting 'Foo.OutputFile' not found in configuration", type='model.implml.exampleml.invalid_ref', line=4, file='Layer1/implml/invalid_refs.exampleml', severity='error')
+Problem(msg=u"Setting 'Foo.OutputFile' not found in configuration", type='model.implml.exampleml.invalid_ref', line=5, file='Layer1/implml/invalid_refs.exampleml', severity='error')
+Problem(msg=u"Setting 'Foo.Text' not found in configuration", type='model.implml.exampleml.invalid_ref', line=3, file='Layer1/implml/invalid_refs.exampleml', severity='error')
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/testdata/validation/project/Layer1/confml/invalid_encoding.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/1" name="InvalidEncodingTest">
+    <feature ref="InvalidEncodingTest" name="Settings for invalid encoding test">
+        <setting ref="EncodingOk" name="Encoding (OK)" type="string"/>
+        <setting ref="EncodingNotOk" name="Encoding (not OK)" type="string"/>
+    </feature>
+    <data>
+        <InvalidEncodingTest>
+            <EncodingOk>utf-16</EncodingOk>
+            <EncodingNotOk>foobar</EncodingNotOk>
+        </InvalidEncodingTest>
+    </data>
+</configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/testdata/validation/project/Layer1/implml/invalid_encoding.exampleml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<exampleml xmlns="http://www.example.org/xml/exampleml/1">
+    <output file="foo1.txt" encoding="utf-16">Test</output>
+    <output file="foo2.txt" encoding="${InvalidEncodingTest.EncodingOk}">Test</output>
+    
+    <output file="foo3.txt" encoding="foocode">Test</output>
+    <output file="foo4.txt" encoding="${InvalidEncodingTest.EncodingNotOk}">Test</output>
+    
+    <!-- If the encoding comes from a setting, it should not be validated if the setting doesn't exist -->
+    <output file="foo5.txt" encoding="${Foo.Bar}">Test</output>
+</exampleml>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/testdata/validation/project/Layer1/implml/invalid_refs.exampleml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<exampleml xmlns="http://www.example.org/xml/exampleml/1">
+    <output file="test.txt">Value from ConfML: ${Foo.Text}</output>
+    <output file="${Foo.OutputFile}" encoding="${Foo.OutputEncoding}">Test test ${Foo.MoreText}</output>
+    <output file="${Foo.OutputDir}/${Foo.OutputFile}" encoding="windows-1252">Test 1 output 2 €</output>
+</exampleml>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/testdata/validation/project/Layer1/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<confml:configuration xmlns:confml="http://www.s60.com/xml/confml/1" xmlns:xi="http://www.w3.org/2001/XInclude" name="Layer 1">
+  <xi:include href="confml/invalid_encoding.confml#/"/>
+</confml:configuration>
Binary file configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/testdata/validation/project/root.confml has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/testdata/validation/schema/invalid/missing_output_file.exampleml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<exampleml xmlns="http://www.example.org/xml/exampleml/1">
+    <output>Value from ConfML: ${Foo.Text}</output>
+</exampleml>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/testdata/validation/schema/valid/test.exampleml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<exampleml xmlns="http://www.example.org/xml/exampleml/1">
+    <output file="test.txt">Value from ConfML: ${Foo.Text}</output>
+    <output file="${Foo.OutputFile}" encoding="${Foo.OutputEncoding}">Test test ${Foo.MoreText}</output>
+    <output file="${Foo.OutputDir}/${Foo.OutputFile}" encoding="windows-1252">Test 1 output 2 €</output>
+</exampleml>
\ No newline at end of file
--- a/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/unittest_exampleml_generation.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/unittest_exampleml_generation.py	Tue Aug 10 14:29:28 2010 +0300
@@ -14,15 +14,13 @@
 # Description:
 #
 
-import sys, os, unittest
-import __init__
+import os
 
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
 
 from testautomation.base_testcase import BaseTestCase
-from cone.public import exceptions, plugin, api, container
+from cone.public import plugin, api
 
-from examplemlplugin import exampleml_reader
 
 def abspath(path):
     return os.path.normpath(os.path.join(ROOT_PATH, path))
@@ -30,18 +28,19 @@
 class TestExamplemlGeneration(BaseTestCase):
 
     def test_generate_from_project(self):
-        project_dir     = abspath('project')
+        project_dir     = abspath('testdata/generation/project')
         config          = 'root.confml'
-        output_dir      = abspath('temp/output')
-        expected_dir    = abspath('gen_expected')
+        output_dir      = abspath('temp/generation/output')
+        expected_dir    = abspath('testdata/generation/expected')
         
         self.remove_if_exists(output_dir)
         
         prj = api.Project(api.Storage.open(project_dir))
         config = prj.get_configuration(config)
+        context = plugin.GenerationContext(configuration=config, 
+                                           output=output_dir)
         impls = plugin.get_impl_set(config)
-        impls.output = output_dir
-        impls.generate()
+        impls.generate(context)
         
         self.assert_dir_contents_equal(output_dir, expected_dir, ['.svn'])
         
\ No newline at end of file
--- a/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/unittest_exampleml_impl.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/unittest_exampleml_impl.py	Tue Aug 10 14:29:28 2010 +0300
@@ -15,7 +15,6 @@
 #
 
 import sys, os, unittest
-import __init__
 
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
 
@@ -26,7 +25,7 @@
 class TestExamplemlImpl(unittest.TestCase):
 
     def setUp(self):
-        project_dir = os.path.join(ROOT_PATH, 'project')
+        project_dir = os.path.join(ROOT_PATH, 'testdata/generation/project')
         self.project = api.Project(api.Storage.open(project_dir))
         self.config = self.project.get_configuration('root.confml')
     
@@ -42,7 +41,7 @@
     
     def test_list_output_files(self):
         def oj( p2): # oj = output_join
-            return os.path.normpath(os.path.join('output', p2))
+            return os.path.normpath(p2)
         
         impl = self.get_impl('Layer/implml/test.exampleml', 0)
         self.assertEquals(impl.list_output_files(), [oj('test.txt'),
--- a/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/unittest_exampleml_reader.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/unittest_exampleml_reader.py	Tue Aug 10 14:29:28 2010 +0300
@@ -15,7 +15,6 @@
 #
 
 import sys, os, unittest
-import __init__
 
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/tests/unittest_exampleml_validation.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,63 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+import os
+import __init__
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+from testautomation.base_testcase import BaseTestCase
+from cone.public import api
+from cone.validation import schemavalidation, implmlvalidation
+
+class TestExamplemlValidation(BaseTestCase):
+    
+    def _run_test(self, filename):
+        filepath = 'Layer1/implml/' + filename
+        project_dir = os.path.join(ROOT_PATH, 'testdata/validation/project')
+        config      = 'root.confml'
+        
+        prj = api.Project(api.Storage.open(project_dir))
+        config = prj.get_configuration(config)
+        problems = implmlvalidation.validate_impls(config, filter=filepath + '$')
+        
+        self.assert_problem_list_equals_expected(
+            actual = problems,
+            expected_file = os.path.join(ROOT_PATH, 'testdata/validation/expected', filename + '.txt'),
+            outdir = os.path.join(ROOT_PATH, 'temp/validation', filename))
+    
+    def test_validate_invalid_refs(self):
+        self._run_test('invalid_refs.exampleml')
+    
+    def test_validate_invalid_encoding(self):
+        self._run_test('invalid_encoding.exampleml')
+
+class TestExamplemlSchemaValidation(BaseTestCase, schemavalidation.SchemaValidationTestMixin):
+    NAMESPACE = 'http://www.example.org/xml/exampleml/1'
+    PROBLEM_TYPE = 'schema.implml.exampleml'
+    
+    def test_schemavalidate_exampleml_valid_files(self):
+        self.assert_schemavalidation_succeeds(
+            type = 'implml',
+            dir = os.path.join(ROOT_PATH, 'testdata/validation/schema/valid'),
+            namespace = self.NAMESPACE)
+    
+    def test_schemavalidate_exampleml_invalid_files(self):
+        self.assert_schemavalidation_fails(
+            type = 'implml',
+            dir = os.path.join(ROOT_PATH, 'testdata/validation/schema/invalid'),
+            namespace = self.NAMESPACE,
+            problem_type = self.PROBLEM_TYPE)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/ConeExamplePlugin/examplemlplugin/xsd/exampleml.xsd	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema 
+	xmlns:xs="http://www.w3.org/2001/XMLSchema"
+	targetNamespace="http://www.example.org/xml/exampleml/1"
+	xmlns:exampleml="http://www.example.org/xml/exampleml/1"
+	elementFormDefault="qualified">
+
+    <xs:element name="exampleml">
+        <xs:annotation>
+            <xs:documentation>
+                ExampleML implementation for demonstration/template purposes.
+            </xs:documentation>
+        </xs:annotation>
+        
+        <xs:complexType>
+            <xs:choice minOccurs="0" maxOccurs="unbounded">
+                
+                <xs:element name="output">
+                    <xs:annotation>
+                        <xs:documentation>
+                            The output element specifies a single output file, its template (text) and encoding.
+                        </xs:documentation>
+                    </xs:annotation>
+                    
+                    <xs:complexType mixed="true">
+                        <xs:attribute name="file" type="xs:string" use="required">
+                            <xs:annotation>
+                                <xs:documentation>
+                                    Specifies the location of the output file.
+                                    ConfML setting references can be used with the ${} notation.
+                                </xs:documentation>
+                            </xs:annotation>
+                        </xs:attribute>
+                        
+                        <xs:attribute name="encoding" type="xs:string" use="optional">
+                            <xs:annotation>
+                                <xs:documentation>
+                                    Specifies the encoding of the output file, defaults to UTF-8.
+                                    ConfML setting references can be used with the ${} notation.
+                                </xs:documentation>
+                            </xs:annotation>
+                        </xs:attribute>
+                    </xs:complexType>
+                </xs:element>
+            </xs:choice>
+        </xs:complexType>
+        
+    </xs:element>
+    
+</xs:schema>
\ No newline at end of file
--- a/configurationengine/source/plugins/example/ConeExamplePlugin/setup.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/example/ConeExamplePlugin/setup.py	Tue Aug 10 14:29:28 2010 +0300
@@ -22,6 +22,7 @@
     name = "coneexamplemlplugin",
     version = __version__,
     packages = find_packages(exclude=["*.tests"]),
+    package_data = {'examplemlplugin': ['xsd/*.xsd']},
     test_suite = "examplemlplugin.tests.collect_suite",
 
     # metadata for upload to PyPI
@@ -35,13 +36,20 @@
     
     # Entry point info.
     # Plug-ins can register ImplML reader classes by adding entry points
-    # pointing to reader classes under 'cone.plugins.implmlreaders'
+    # pointing to reader classes under 'cone.plugins.implmlreaders', and
+    # validator classes under 'cone.plugins.implvalidators'
     entry_points = {
         'cone.plugins.implmlreaders': [
             'exampleml = examplemlplugin.exampleml_reader:ExamplemlReader',
              # More readers (e.g. different versions of the same ImplML)
              # could also be registered:
              #'exampleml_v2 = examplemlplugin.exampleml_reader:ExamplemlReader2',
-        ]
+        ],
+        
+        'cone.plugins.implvalidators': [
+            # Each entry point is expected to be an iterable of reader
+            # classes, here it points to a list defined in exampleml_validators.py
+            'exampleml = examplemlplugin.exampleml_validators:VALIDATOR_CLASSES'
+        ],
     }
 )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/ConeExampleValidatorPlugin/examplevalidatorplugin/__init__.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,17 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+__version__ = 0.1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/ConeExampleValidatorPlugin/examplevalidatorplugin/tests/__init__.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,23 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+import sys, os, unittest
+
+# Path to the directory where this file is located
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+from testautomation import plugin_utils
+plugin_utils.plugin_test_init(ROOT_PATH)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/ConeExampleValidatorPlugin/examplevalidatorplugin/tests/runtests.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,19 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+if __name__ == '__main__':
+    import nose
+    nose.core.run(argv=['collector','--include=unittest', '--verbosity=3'])
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/ConeExampleValidatorPlugin/examplevalidatorplugin/tests/testdata/expected.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,1 @@
+Problem(msg="String 'foo' missing from value of feature 'ExampleValidatorTest.FOO_SomeSetting2'", type='model.confml.foo_missing', line=12, file='test.confml', severity='warning')
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/ConeExampleValidatorPlugin/examplevalidatorplugin/tests/testdata/test.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/1" name="ExampleValidatorTest">
+    <feature ref="ExampleValidatorTest" name="Settings for example validator testing">
+        <setting ref="SomeSetting" name="Some setting" type="string"/>
+        <setting ref="FOO_SomeSetting1" name="FOO - Some setting 1" type="string"/>
+        <setting ref="FOO_SomeSetting2" name="FOO - Some setting 2" type="string"/>
+    </feature>
+    <data>
+        <ExampleValidatorTest>
+            <SomeSetting>foo bar</SomeSetting>
+            <FOO_SomeSetting1>abc foo</FOO_SomeSetting1>
+            <FOO_SomeSetting2>abc123</FOO_SomeSetting2>
+        </ExampleValidatorTest>
+    </data>
+</configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/ConeExampleValidatorPlugin/examplevalidatorplugin/tests/unittest_validation.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,38 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+import os
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+from testautomation.base_testcase import BaseTestCase
+from cone.public import api
+from cone.validation import confmlvalidation
+
+class TestExampleValidatorValidation(BaseTestCase):
+    
+    def test_validate(self):
+        project_dir = os.path.join(ROOT_PATH, 'testdata')
+        config      = 'test.confml'
+        
+        prj = api.Project(api.Storage.open(project_dir))
+        config = prj.get_configuration(config)
+        problems = confmlvalidation.validate_configuration(config).problems
+        
+        self.assert_problem_list_equals_expected(
+            actual = problems,
+            expected_file = os.path.join(ROOT_PATH, 'testdata/expected.txt'),
+            outdir = os.path.join(ROOT_PATH, 'temp'))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/ConeExampleValidatorPlugin/examplevalidatorplugin/validators.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+from cone.public import api
+from cone.confml import model
+from cone.validation.confmlvalidation import ValidatorBase
+
+class ExampleValidator(ValidatorBase):
+    PROBLEM_TYPES = ['model.confml.foo_missing']
+    
+    def validate(self):
+        for ref, feature in self.context.feature_dict.iteritems():
+            if isinstance(feature._obj, model.ConfmlStringSetting) and feature.ref.startswith('FOO_'):
+                value = feature.get_value()
+                if isinstance(value, basestring) and 'foo' not in value:
+                    dataobj = feature.datas['data'][-1]
+                    
+                    prob = api.Problem(
+                        msg = "String 'foo' missing from value of feature '%s'" % ref,
+                        type = self.PROBLEM_TYPES[0],
+                        line = dataobj.lineno,
+                        file = dataobj.get_configuration_path(),
+                        severity = api.Problem.SEVERITY_WARNING)
+                    self.context.problems.append(prob)
+
+VALIDATOR_CLASSES = [ExampleValidator]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/ConeExampleValidatorPlugin/setup.cfg	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,2 @@
+[egg_info]
+tag_svn_revision = 1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/example/ConeExampleValidatorPlugin/setup.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,41 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+import os, os.path
+from setuptools import setup, find_packages
+from examplemlplugin import __version__
+
+setup(
+    name = "coneexamplevalidatorplugin",
+    version = __version__,
+    packages = find_packages(exclude=["*.tests"]),
+    test_suite = "examplevalidatorplugin.tests.collect_suite",
+
+    # metadata for upload to PyPI
+    author = "<author>",
+    author_email = "authors.email@example.com",
+    description = "Configuration Engine ExampleML plugin",
+    license = "Eclipse Public License v1.0",
+    keywords = "cone",
+    url = "http://developer.symbian.org/wiki/index.php/Software_Configuration_Middleware",
+    zip_safe = True,
+    
+    entry_points = {
+        'cone.plugins.confmlvalidators': [
+            'example = examplevalidatorplugin.validators:VALIDATOR_CLASSES'
+        ],
+    }
+)
--- a/configurationengine/source/plugins/example/integration-test/__init__.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/example/integration-test/__init__.py	Tue Aug 10 14:29:28 2010 +0300
@@ -16,24 +16,4 @@
 ## 
 # @author Teemu Rytkonen
 
-import unittest, os, sys
 
-ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
-PLUGIN_SOURCE_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../..'))
-assert os.path.split(PLUGIN_SOURCE_ROOT)[1] == 'plugins'
-
-# Import plugin_utils from the plug-in sources root
-if PLUGIN_SOURCE_ROOT not in sys.path: sys.path.append(PLUGIN_SOURCE_ROOT)
-import plugin_utils
-
-# Run integration test initialization
-plugin_utils.integration_test_init(ROOT_PATH)
-
-def collect_suite():
-    return plugin_utils.collect_test_suite_from_dir(ROOT_PATH)
-
-def runtests():
-    unittest.TextTestRunner(verbosity=2).run(collect_suite())
-
-if __name__ == '__main__':
-    runtests()
--- a/configurationengine/source/plugins/example/integration-test/runtests.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/example/integration-test/runtests.py	Tue Aug 10 14:29:28 2010 +0300
@@ -16,6 +16,6 @@
 ## 
 # @author
 
-import __init__
-
-__init__.runtests()
+if __name__ == '__main__':
+    import nose
+    nose.core.run(argv=['collector','--include=unittest', '--verbosity=3'])
--- a/configurationengine/source/plugins/example/integration-test/testdata/generate/project/Layer/implml/multitest.implml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/example/integration-test/testdata/generate/project/Layer/implml/multitest.implml	Tue Aug 10 14:29:28 2010 +0300
@@ -2,14 +2,14 @@
 <container xmlns="http://www.symbianfoundation.org/xml/implml/1">
     <!-- Testing that multiple implementations in a single file works correctly -->
     
-    <test1 xmlns="http://www.example.org/xml/exampleml/1">
+    <exampleml xmlns="http://www.example.org/xml/exampleml/1">
         <output file="multitest1_1.txt" encoding="UTF-8">Multitest impl 1 output 1</output>
         <output file="multitest1_2.txt" encoding="UTF-16-LE">Multitest impl 1 output 2</output>
-    </test1>
+    </exampleml>
     
     <!-- Also test that special characters and unicode characters outside the ASCII range work -->
-    <test2 xmlns="http://www.example.org/xml/exampleml/1">
+    <exampleml xmlns="http://www.example.org/xml/exampleml/1">
         <output file="multitest2_1.txt" encoding="UTF-16-BE">Unicode test: ελληνικά</output>
         <output file="multitest2_2.txt" encoding="UTF-16-LE">Special char test: &lt;&amp;></output>
-    </test2>
+    </exampleml>
 </container>
\ No newline at end of file
--- a/configurationengine/source/plugins/example/integration-test/unittest_generate.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/example/integration-test/unittest_generate.py	Tue Aug 10 14:29:28 2010 +0300
@@ -16,7 +16,7 @@
 #
 
 import sys, os, shutil, unittest
-import __init__
+
 from testautomation.base_testcase import BaseTestCase
 from testautomation import zip_dir
 
@@ -25,7 +25,7 @@
 if sys.platform == "win32":
     CONE_SCRIPT = "cone.cmd"
 else:
-    CONE_SCRIPT = "cone.sh"
+    CONE_SCRIPT = "cone"
 
 def get_cmd(action='generate'):
     """Return the command used to run the ConE sub-action"""
@@ -77,7 +77,7 @@
             self.run_command(cmd)
             
             EXPECTED_DIR = os.path.join(ROOT_PATH, "testdata/generate/expected")
-            self.assert_dir_contents_equal('output', EXPECTED_DIR, ['.svn'])
+            self.assert_dir_contents_equal(os.path.join(workdir,'output'), EXPECTED_DIR, ['.svn'])
         finally:
             os.chdir(orig_workdir)
 
--- a/configurationengine/source/plugins/example/runtests.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/example/runtests.py	Tue Aug 10 14:29:28 2010 +0300
@@ -14,19 +14,6 @@
 # Description:
 #
 
-import sys, os, re, unittest
-
-ROOT_PATH = os.path.abspath(os.path.dirname(__file__))
-
-PLUGINS_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '..'))
-assert os.path.split(PLUGINS_ROOT)[1] == 'plugins'
-if PLUGINS_ROOT not in sys.path: sys.path.append(PLUGINS_ROOT)
-import plugin_utils
-
-if __name__ == "__main__":
-    # Collect a list of plug-in source paths and plug-in module names
-    paths_and_modnames = plugin_utils.find_plugin_sources(ROOT_PATH)
-    # Create a test suite from them
-    suite = plugin_utils.collect_suite_from_source_list(paths_and_modnames)
-    # Run the suite
-    unittest.TextTestRunner(verbosity=2).run(suite)
+if __name__ == '__main__':
+    import nose
+    nose.core.run(argv=['collector','--include=unittest', '--verbosity=3'])
--- a/configurationengine/source/plugins/nose_unittests.cfg	Fri Mar 12 08:30:17 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-[nosetests]
-verbosity=3
-include=unittest
-with-xunit=1
-xunit-file=cone-unittests.xml
--- a/configurationengine/source/plugins/plugin_utils.py	Fri Mar 12 08:30:17 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,317 +0,0 @@
-#
-# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
-# All rights reserved.
-# This component and the accompanying materials are made available
-# under the terms of "Eclipse Public License v1.0"
-# which accompanies this distribution, and is available
-# at the URL "http://www.eclipse.org/legal/epl-v10.html".
-#
-# Initial Contributors:
-# Nokia Corporation - initial contribution.
-#
-# Contributors:
-#
-# Description:
-#
-
-import sys, os, unittest, re
-import build_egg_info
-
-# Path to the directory where this file is located
-ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
-
-# Path to the source/ directory
-SOURCE_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '..'))
-assert os.path.split(SOURCE_ROOT)[1] == 'source'
-
-# Path to the source/plugins directory
-PLUGIN_SOURCE_ROOT = os.path.normpath(os.path.join(SOURCE_ROOT, 'plugins'))
-assert os.path.isdir(PLUGIN_SOURCE_ROOT)
-
-def plugin_test_init(root_path, plugin_source_relative_path='../..'):
-    """
-    Initialize things so that plug-in unit tests can be run.
-    
-    @param root_path: Path of the __init__.py file calling this function. 
-    @param plugin_source_relative_path: Path to the plug-in's source root relative
-        to root_path. Usually this should be '../..', since this function is intended
-        to be called from a plug-in's tests/__init__.py file.
-    
-    """
-    # Add paths so that the unit tests work
-    # -------------------------------------
-    extra_paths = [
-        # For module 'cone'
-        SOURCE_ROOT,
-        
-        # For module 'testautomation'
-        os.path.join(SOURCE_ROOT, 'testautomation'),
-        
-        # For the plug-in module.
-        # Since the method is expected to be called from e.g.
-        # source/plugins/ConeSomePlugin/someplugin/tests/__init__.py, this will then be
-        # source/plugins/ConeSomePlugin, in which case the module 'someplugin' can be
-        # imported
-        os.path.join(root_path, plugin_source_relative_path)
-    ]
-    for p in extra_paths:
-        p = os.path.normpath(p)
-        if p not in sys.path: sys.path.append(p)
-    
-    # Generate egg-info for the plug-in.
-    # The egg-info needs to be up-to-date, or the plug-in framework will not be able
-    # to find the plug-in's ImplML reader classes
-    plugin_path = os.path.normpath(os.path.join(root_path, plugin_source_relative_path))
-    assert 'setup.py' in os.listdir(plugin_path), "Path '%s' does not contain 'setup.py" % plugin_path
-    build_egg_info.generate_egg_info(plugin_path)
-
-def integration_test_init(root_path):
-    """
-    Initialize things so that integration tests can be run.
-    
-    This function is intended to be called from a sub-package's integration-test/__init__.py file.
-    @param root_path: Path of the __init__.py file calling this function.
-    """
-    # Add paths so that the unit tests work
-    # -------------------------------------
-    extra_paths = [
-        # For module 'cone' (may be needed in some tests for e.g. asserts)
-        SOURCE_ROOT,
-        
-        # For module 'testautomation'
-        os.path.join(SOURCE_ROOT, 'testautomation'),
-    ]
-    for p in extra_paths:
-        p = os.path.normpath(p)
-        if p not in sys.path: sys.path.append(p)
-    
-    # Collect plug-in source paths (common + current)
-    temp = []
-    temp += [path for path, _ in find_plugin_sources(os.path.join(PLUGIN_SOURCE_ROOT, 'common'))]
-    temp += [path for path, _ in find_plugin_sources(os.path.normpath(os.path.join(root_path, '..')))]
-    plugin_paths = []
-    for p in temp:
-        if p not in plugin_paths: plugin_paths.append(p)
-    
-    # Add things to PYTHONPATH so that running cone_tool.py works
-    paths = []
-    paths.append(SOURCE_ROOT) # For module 'cone'
-    paths.extend(plugin_paths)
-    os.environ['PYTHONPATH'] = os.environ.get('PYTHONPATH', '') + ';' + ';'.join(paths)
-    
-    # Generate egg-info for the plug-ins.
-    # The egg-info needs to be up-to-date, or the plug-in framework will not be able
-    # to find the plug-in's ImplML reader classes
-    for p in plugin_paths:
-        assert 'setup.py' in os.listdir(p), "Path '%s' does not contain 'setup.py" % p
-        build_egg_info.generate_egg_info(p)
-
-def init_all():
-    """
-    Add all plug-ins to sys.path and PYTHONPATH so that running all
-    plug-in unit tests and integration tests work.
-    """
-    # Find all plug-in source directories
-    plugin_paths = []
-    temp = find_all_plugin_sources(os.path.join(PLUGIN_SOURCE_ROOT))
-    for package_name, sources in temp.iteritems():
-        for path, modname in sources:
-            plugin_paths.append(path)
-    
-    # Add paths so that the unit tests work
-    # -------------------------------------
-    extra_paths = [
-        # For module 'cone' (may be needed in some tests for e.g. asserts)
-        SOURCE_ROOT,
-        
-        # For module 'testautomation'
-        os.path.join(SOURCE_ROOT, 'testautomation'),
-    ] + plugin_paths
-    for p in extra_paths:
-        p = os.path.normpath(p)
-        if p not in sys.path: sys.path.append(p)
-    
-    # Add things to PYTHONPATH so that running cone_tool.py works
-    paths = []
-    paths.append(SOURCE_ROOT) # For module 'cone'
-    paths.extend(plugin_paths)
-    os.environ['PYTHONPATH'] = os.environ.get('PYTHONPATH', '') + ';' + ';'.join(paths)
-    
-    # Generate egg-info for the plug-ins.
-    # The egg-info needs to be up-to-date, or the plug-in framework will not be able
-    # to find the plug-in's ImplML reader classes
-    for p in plugin_paths:
-        assert 'setup.py' in os.listdir(p), "Path '%s' does not contain 'setup.py" % p
-        build_egg_info.generate_egg_info(p)
-
-def collect_test_suite_from_dir(root_path):
-    """
-    Return a test suite containing all tests in 'unittest_*.py' files under the given directory.
-    """
-    # Find all unittest_*.py files in the folder
-    test_modules = filter(lambda name: re.match(r'^unittest_.*\.py$', name) != None, os.listdir(root_path))
-    # Strip .py endings
-    test_modules = map(lambda name: name[:-3], test_modules)
-    
-    # Add the root path as the first one in sys.path, so that
-    # __import__() checks that first when attempting to import a module 
-    sys.path.insert(0, root_path)
-    
-    try:
-        suite = unittest.TestSuite()
-        for test_module in test_modules:
-            # Load the test module dynamically and add it to the test suite
-            module = __import__(test_module)
-            suite.addTests(unittest.TestLoader().loadTestsFromModule(module))
-        return suite
-    finally:
-        # Remove root_path from sys.path
-        del sys.path[0]
-
-def collect_suite_from_source_list(paths_and_modnames):
-    suite = unittest.TestSuite()
-    
-    # Add the source paths to sys.path
-    for path, modname in paths_and_modnames:
-        if path not in sys.path:
-            sys.path.append(path)
-    
-    # Import the tests in a separate loop, because otherwise the ImplML reader classes
-    # could be loaded before all plug-ins are in sys.path
-    for path, modname in paths_and_modnames:
-        try:
-            m = __import__(modname + '.tests')
-            suite.addTests(m.tests.collect_suite())
-        except ImportError:
-            print "Tests for '%s' not added, no 'tests' module found" % path
-    
-    return suite
-
-def get_plugin_module_name(plugin_src_path):
-    """
-    Return the name of the plug-in's module under given plug-in source path.
-    
-    >>> get_tests_module('source/plugins/common/ConeContentPlugin')
-    'contentplugin'
-    >>> get_tests_module('foo')
-    None
-    """
-    if not os.path.isdir(plugin_src_path):
-        return None
-    
-    for name in os.listdir(plugin_src_path):
-        path = os.path.join(plugin_src_path, name)
-        if os.path.isdir(path) and '__init__.py' in os.listdir(path):
-            return name
-    return None
-
-def find_plugin_sources(subpackage_root_path):
-    """
-    Return ConE plug-in source directories from the given path.
-    
-    All sub-directories in subpackage_root_path of the form Cone*Plugin/ containing
-    a sub-directory that is a python module are returned.
-    
-    @param path: The directory from where to find the entries.
-    @return: A list of tuples, each containing (<source_dir>, <module_name>).
-    """
-    pattern = re.compile(r'^Cone.*Plugin$')
-    
-    # Collect a list of plug-in source paths and plug-in module names
-    result = []
-    for name in os.listdir(subpackage_root_path):
-        path = os.path.join(subpackage_root_path, name)
-        if pattern.match(name) is not None:
-            modname = get_plugin_module_name(path)
-            if modname is not None:
-                result.append((path, modname))
-    return result
-
-def find_all_plugin_sources(plugins_root_path):
-    """
-    Return all ConE plug-in source directories from the plugins/ root
-    directory.
-    @return: A dictionary containing the output of find_plugin_sources() by
-        plug-in sub-packages.
-    >>> find_all_plugin_sources('C:/work/cone-trunk/source/plugins')
-    {'common': [('C:/work/cone-trunk/source/plugins/common/ConeContentPlugin', 'contentplugin'),
-                ('C:/work/cone-trunk/source/plugins/common/ConeTemplatePlugin', 'templatemlplugin')],
-     'example': [('C:/work/cone-trunk/source/plugins/example/ConeExamplePlugin', 'examplemlplugin')]}
-    """
-    result = {}
-    for name in os.listdir(plugins_root_path):
-        path = os.path.join(plugins_root_path, name)
-        if os.path.isdir(path):
-            sources = find_plugin_sources(path)
-            if sources: result[name] = sources
-    return result
-
-def find_plugin_package_subpaths(subpath, package_name=None):
-    """
-    Return a list of plug-in package sub-paths based on the given plug-in package name.
-    
-    The returned list always contains the sub-path for common plug-ins, and
-    additionally for an extra plug-in package based on the given package name.
-    
-    This function can be used to find specifically named files or directories
-    under the plug-in paths. E.g. find all 'integration-test' directories:
-    
-    >>> find_plugin_package_subpaths('integration-test', 'symbian')
-    [('common',  'C:\\cone\\trunk\\sources\\plugins\\common\\integration-test'),
-     ('symbian', 'C:\\cone\\trunk\\sources\\plugins\\symbian\\integration-test')]
-    
-    @param package_name: Name of the extra plug-in package. Can be None, '',
-        'common' or an existing plug-in package.
-    @return: List of tuples (package_name, subpath).
-    
-    @raise ValueError: The given package_name was invalid.
-    """
-    result = []
-    
-    def add(package_name):
-        package_dir = os.path.join(PLUGIN_SOURCE_ROOT, package_name)
-        
-        if not os.path.exists(package_dir):
-            raise ValueError("Invalid plug-in package name: '%s'" % package_name)
-        
-        path = os.path.normpath(os.path.join(package_dir, subpath))
-        if os.path.exists(path):
-            result.append((package_name, path))
-    
-    add('common')
-    if package_name not in (None, '', 'common'):
-        add(package_name)
-    
-    return result
-    
-
-def find_plugin_sources_by_package(package_name=None):
-    """
-    Return a list of plug-in source paths based on the given plug-in package name.
-    
-    The returned list always contains sources of common plug-ins, and
-    additionally extra plug-in sources based on the given package name.
-    
-    @param package_name: Name of the extra plug-in package. Can be None, '',
-        'common' or an existing plug-in package.
-    @raise ValueError: The given package_name was invalid.
-    """
-    result = []
-    
-    # Find all plug-in sources
-    sources = find_all_plugin_sources(PLUGIN_SOURCE_ROOT)
-    
-    # Always return common plug-ins
-    if 'common' in sources:
-        for path, modname in sources['common']:
-            result.append(path)
-    
-    # Return extra plug-ins if necessary
-    if package_name not in (None, '', 'common'):
-        if package_name not in sources:
-            raise ValueError("Invalid plug-in package name: '%s'" % package_name)
-        else:
-            for path, modname in sources[package_name]:
-                result.append(path)
-    
-    return result
--- a/configurationengine/source/plugins/runtests.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/runtests.py	Tue Aug 10 14:29:28 2010 +0300
@@ -14,22 +14,11 @@
 # Description:
 #
 
-import sys, os, re, unittest
-import plugin_utils
-
-ROOT_PATH = os.path.abspath(os.path.dirname(__file__))
-
-if __name__ == "__main__":
-    # Collect a list of plug-in source paths and plug-in module names
-    sources = plugin_utils.find_all_plugin_sources(ROOT_PATH)
-    
-    # Flatten the source list
-    flattened_sources = []
-    for subpackage_name, paths_and_modnames in sources.iteritems():
-        flattened_sources.extend(paths_and_modnames)
-    
-    # Create a test suite from them
-    suite = plugin_utils.collect_suite_from_source_list(flattened_sources)
-    
-    # Run the suite
-    unittest.TextTestRunner(verbosity=2).run(suite)
+if __name__ == '__main__':
+    import nose
+    nose.core.run(argv=['collector',
+                        'common',
+                        'example',
+                        'symbian',
+                        '--include=unittest', 
+                        '--verbosity=3'])
\ No newline at end of file
--- a/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/crml_impl.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/crml_impl.py	Tue Aug 10 14:29:28 2010 +0300
@@ -34,19 +34,43 @@
         self.configuration = configuration
         self.logger = logging.getLogger('cone.crml(%s)' % self.resource_ref)
         self.repository = repository
-        
+
+    def __getstate__(self):
+        state = super(CrmlImpl, self).__getstate__()
+        state['repository'] = self.__dict__.get('repository',None)
+        return state
+
+            
     def generate(self, context=None):
         # Quick fix 
         if context:
             self.generation_context = context
+        
+        # See if delta CenReps should be generated
+        delta_cenrep = context and context.changed_refs is not None \
+            and 'deltacenrep' in context.tags.get('crml', [])
+        
+        changed_refs = None
+        if delta_cenrep:
+            changed_refs = context.changed_refs
+            
+            # Hard-coded output for delta CenReps for now
+            self.output_subdir = 'deltacenreps'
+            self.plugin_output = ''
+        
         file_path = self._get_cenrep_txt_file_path()
         self.logger.debug("Generating file '%s'..." % file_path)
         
         # Generate CenRep text data and write it to the output file
-        writer = crml_writer.CrmlTxtWriter(self.configuration, self.logger)
-        data = writer.get_cenrep_txt_data(self.repository).encode('UTF-16')
+        writer = crml_writer.CrmlTxtWriter(context, self.logger)
+        data = writer.get_cenrep_txt_data(self.repository, changed_refs).encode('UTF-16')
         self._write_to_file(file_path, data)
         
+        # Add to the generated files list
+        KEY = 'crml_generated_cenrep_files'
+        lst = context.impl_data_dict.setdefault(KEY, [])
+        lst.append((os.path.basename(file_path), os.path.abspath(file_path)))
+        
         
         # Collect the record for cenrep_rfs.txt generation in post_generate()
         if self.generation_context is not None:
@@ -137,12 +161,8 @@
         return 'core' in targets or 'rofs2' in targets
     
     def _write_to_file(self, file_path, data):
-        # Create directories for the file if necessary
-        file_dir = os.path.dirname(file_path)
-        if file_dir != '' and not os.path.exists(file_dir):
-            os.makedirs(file_dir)
         
         # Write data
-        f = open(file_path, "wb")
+        f = self.generation_context.create_file(file_path, implementation=self)
         try:        f.write(data)
         finally:    f.close()
--- a/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/crml_model.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/crml_model.py	Tue Aug 10 14:29:28 2010 +0300
@@ -86,6 +86,8 @@
         self.cap_wr = kwargs.get('cap_wr')
         self.sid_rd = kwargs.get('sid_rd')
         self.sid_wr = kwargs.get('sid_wr')
+        self.line_rd = kwargs.get('line_rd')
+        self.line_wr = kwargs.get('line_wr')
 
 
 class CrmlRepository(_CrmlObjectBase):
@@ -122,6 +124,7 @@
         self.backup     = kwargs.get('backup', False)
         self.read_only  = kwargs.get('read_only', False)
         self.access     = kwargs.get('access', CrmlAccess())
+        self.line       = kwargs.get('line', None)
 
 class CrmlSimpleKey(CrmlKeyBase, _CrmlObjectBase):
     SIMPLE_EQ_VARNAMES = ['ref', 'name', 'int', 'type', 'backup', 'read_only', 'access']
@@ -174,6 +177,7 @@
             self.invert = kwargs.get('invert', False)
         except KeyError, e:
             raise ValueError("Mandatory argument '%s' not given!" % e.message)
+        self.line = kwargs.get('line')
 
 class CrmlKeyRange(CrmlKeyBase, _CrmlObjectBase):
     SIMPLE_EQ_VARNAMES = ['ref', 'name', 'first_int', 'last_int', 'first_index', 'index_bits', 'count_int', 'backup', 'read_only', 'access', 'subkeys']
@@ -219,4 +223,5 @@
             self.name   = kwargs.get('name')
         except KeyError, e:
             raise ValueError("Mandatory argument '%s' not given!" % e.message)
+        self.line = kwargs.get('line')
     
\ No newline at end of file
--- a/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/crml_reader.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/crml_reader.py	Tue Aug 10 14:29:28 2010 +0300
@@ -13,8 +13,8 @@
 #
 # Description:
 #
-
-from cone.public import exceptions, plugin
+import pkg_resources
+from cone.public import exceptions, plugin, utils
 import crml_impl
 from crml_model import *
 
@@ -44,6 +44,8 @@
 
 class CrmlReader(plugin.ReaderBase):
     NAMESPACE = 'http://www.s60.com/xml/cenrep/1'
+    NAMESPACE_ID = 'crml'
+    ROOT_ELEMENT_NAME = 'repository'
     FILE_EXTENSIONS = ['crml']
     
     @classmethod
@@ -52,6 +54,10 @@
         repository = reader.read_repository(etree)
         return crml_impl.CrmlImpl(resource_ref, configuration, repository)
     
+    @classmethod
+    def get_schema_data(cls):
+        return pkg_resources.resource_string('CRMLPlugin', 'xsd/crml.xsd')
+    
     def read_repository(self, elem):
         """
         Read a CrmlRepository object from the given XML element.
@@ -99,10 +105,12 @@
             if type == 'R' and not read_cap_found:
                 access.cap_rd = access_elem.get('capabilities')
                 access.sid_rd = access_elem.get('sid')
+                access.line_rd = utils.etree.get_lineno(access_elem)
                 read_cap_found = True
             elif type == 'W' and not write_cap_found:
                 access.cap_wr = access_elem.get('capabilities')
                 access.sid_wr = access_elem.get('sid')
+                access.line_wr = utils.etree.get_lineno(access_elem)
                 write_cap_found = True
         
         return access
@@ -145,7 +153,8 @@
         key = CrmlSimpleKey(
             ref  = get_required_attr(key_elem, 'ref').replace('/', '.'),
             int  = get_required_attr(key_elem, 'int'),
-            type = key_elem.get('type', 'int'))
+            type = key_elem.get('type', 'int'),
+            line = utils.etree.get_lineno(key_elem))
         self.read_common_key_attrs(key_elem, key)
         
         return key
@@ -161,7 +170,8 @@
         # Read attributes
         key = CrmlBitmaskKey(
             int  = get_required_attr(key_elem, 'int'),
-            type = key_elem.get('type', 'int'))
+            type = key_elem.get('type', 'int'),
+            line = utils.etree.get_lineno(key_elem))
         self.read_common_key_attrs(key_elem, key)
         
         # Read bits
@@ -171,7 +181,8 @@
             else:                                   invert = False
             index = int(bit_elem.text.strip())
             
-            key.bits.append(CrmlBit(ref=ref, index=index, type=type, invert=invert))
+            key.bits.append(CrmlBit(ref=ref, index=index, type=type, invert=invert,
+                                    line=utils.etree.get_lineno(bit_elem)))
         
         return key
     
@@ -192,7 +203,8 @@
             last_int    = get_required_attr(key_range_elem, "lastInt"),
             count_int   = key_range_elem.get('countInt'),
             first_index = convert_num(key_range_elem.get('firstIndex', '0')),
-            index_bits  = convert_num(key_range_elem.get('indexBits')))
+            index_bits  = convert_num(key_range_elem.get('indexBits')),
+            line        = utils.etree.get_lineno(key_range_elem))
         self.read_common_key_attrs(key_range_elem, key_range)
         
         # Read sub-keys
@@ -201,6 +213,7 @@
             int = get_required_attr(subkey_elem, 'int')
             name = subkey_elem.get('name')
             type = subkey_elem.get('type', 'int')
-            key_range.subkeys.append(CrmlKeyRangeSubKey(ref=ref, int=int, name=name, type=type))
+            key_range.subkeys.append(CrmlKeyRangeSubKey(ref=ref, int=int, name=name, type=type,
+                                                        line=utils.etree.get_lineno(subkey_elem)))
         
         return key_range
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/crml_validators.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,82 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+from cone.public import api, exceptions
+from cone.validation.implmlvalidation import ImplValidatorBase
+from CRMLPlugin import crml_impl
+from CRMLPlugin import crml_model
+
+class CrmlValidatorBase(ImplValidatorBase):
+    SUPPORTED_IMPL_CLASSES = crml_impl.CrmlImpl
+
+class CrmlReferenceValidator(CrmlValidatorBase):
+    PROBLEM_TYPES = ['model.implml.crml.invalid_ref']
+    
+    def validate(self):
+        self.dview = self.context.configuration.get_default_view()
+        
+        for key in self.impl.repository.keys:
+            if isinstance(key, crml_model.CrmlSimpleKey):
+                self._check_ref(key.ref, key.line)
+            elif isinstance(key, crml_model.CrmlBitmaskKey):
+                for bit in key.bits:
+                    self._check_ref(bit.ref, bit.line)
+            elif isinstance(key, crml_model.CrmlKeyRange):
+                for subkey in key.subkeys:
+                    fullref = "%s.%s" % (key.ref, subkey.ref)
+                    self._check_ref(fullref, subkey.line)
+    
+    def _check_ref(self, ref, line):
+        self.check_feature_reference(ref, line, self.PROBLEM_TYPES[0])
+
+class CrmlDuplicateUidValidator(CrmlValidatorBase):
+    PROBLEM_TYPES = ['model.implml.crml.duplicate_uid']
+    
+    def validate(self):
+        # Collect a dictionary of CRML keys by UID
+        keys_by_uid = {}
+        for key in self.impl.repository.keys:
+            if isinstance(key, (crml_model.CrmlSimpleKey, crml_model.CrmlBitmaskKey)):
+                try:
+                    try:
+                        uid = long(key.int)
+                    except ValueError:
+                        uid = long(key.int, 16)
+                except ValueError:
+                    # Silently ignore non-numeric UID values (they should be caught
+                    # by other validation)
+                    continue
+                keys = keys_by_uid.get(uid, [])
+                keys.append(key)
+                keys_by_uid[uid] = keys
+        
+        # Check for duplicates
+        for uid, keys in keys_by_uid.iteritems():
+            if len(keys) > 1:
+                if len(keys) > 2:
+                    key_lst = "keys on lines %s" % ', '.join([str(key.line) for key in keys[:-2]])
+                    key_lst += ' and %s' % keys[-2].line
+                else:
+                    key_lst = "key on line %s" % keys[-2].line
+                prob = api.Problem(
+                    msg = "Duplicate key UID 0x%08X (duplicate with %s)" % (uid, key_lst),
+                    type = self.PROBLEM_TYPES[0],
+                    line = keys[-1].line,
+                    file = self.impl.ref)
+                self.context.problems.append(prob)
+
+
+VALIDATOR_CLASSES = [CrmlReferenceValidator, CrmlDuplicateUidValidator]
--- a/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/crml_writer.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/crml_writer.py	Tue Aug 10 14:29:28 2010 +0300
@@ -14,7 +14,7 @@
 # Description:
 #
 import re
-from cone.public import exceptions
+from cone.public import exceptions, plugin
 import crml_reader
 from crml_model import *
 
@@ -58,39 +58,47 @@
     
     def __repr__(self):
         return "CenRepRfsRecord(repo_uid=%s, key_uids=%r)" % (self.repo_uid, self.key_uids)
-        
 
 class CrmlTxtWriter(object):
     """
     Writer class for generating CenRep .txt files based on a CRML model.
     """
     
-    def __init__(self, configuration, log):
-        self.configuration = configuration
+    def __init__(self, context, log):
+        self.context = context
         self.log = log
     
-    def get_cenrep_txt_data(self, repository):
+    def get_cenrep_txt_data(self, repository, changed_refs=None):
         """
         Return the text data for the CenRep txt generated based on the given
         CRML repository model.
+        @param changed_refs: List of changed refs. If this is passed, only a delta
+            CenRep txt file is generated (i.e. containing only the changed settings).
+            If None, the whole CenRep file is generated normally.
         @return: Text data for the CenRep text file.
         """
+        delta_cenrep = changed_refs is not None
         data = []
         
         # Generate header lines 
-        data.extend(self.get_header_lines(repository))
+        data.extend(self.get_header_lines(repository, delta_cenrep))
         
         self._check_repository_attrs(repository)
         
         # Generate CenRep entries for all keys
         cenrep_entries = []
         for key in repository.keys:
+            # If generating a delta CenRep file, ignore keys that don't
+            # use any of the changed settings
+            if delta_cenrep:
+                if not plugin.uses_ref(changed_refs, key.get_refs()):
+                    continue
             cenrep_entries.extend(self.get_cenrep_entries(key))
         
         # Generate entry lines based on the entries
         cenrep_entries.sort()
         for entry in cenrep_entries:
-            data.append(self.get_cenrep_entry_line(entry))
+            data.append(self.get_cenrep_entry_line(entry, delta_cenrep))
         
         data.append('')
         
@@ -179,30 +187,34 @@
         
         return feature.get_value(attr='rfs')
     
-    def get_header_lines(self, repository):
+    def get_header_lines(self, repository, delta_cenrep=False):
         """
         Return a list of lines to be written in the header section of the CenRep text file.
+        @param delta_cenrep: If True, only the data needed for a delta CenRep
+            file is returned.
         """
         data = ['cenrep',
                 'version %s' % repository.version]
         
+        # Owner seems to be required even for delta CenReps
         if repository.owner:
             data.append('[owner]')
             data.append(repository.owner)
         
         data.append('[defaultmeta]')
-        data.append(' %d' % _get_metadata(repository.backup))
-        for key in repository.keys:
-            data.append(self.get_defaultmeta_line(key))
+        if not delta_cenrep:
+            data.append(' %d' % _get_metadata(repository.backup))
+            for key in repository.keys:
+                data.append(self.get_defaultmeta_line(key))
         
         data.append('[platsec]')
-        acc_text = self.get_access_line(repository.access)
-        if acc_text: acc_text = ' ' + acc_text
-        data.append(acc_text)
-        for key in repository.keys:
+        if not delta_cenrep:
+            acc_text = self.get_access_line(repository.access)
+            if acc_text: acc_text = ' ' + acc_text
+            data.append(acc_text)
+            for key in repository.keys:
                 data.append(self.get_platsec_line(key, repository))
         
-        
         data.append('[Main]')
         return data
     
@@ -369,9 +381,11 @@
                              acc_text)
         
     
-    def get_cenrep_entry_line(self, entry):
+    def get_cenrep_entry_line(self, entry, delta_cenrep=False):
         """
         Return the text line for a CenRepEntry object.
+        @param delta_cenrep: If True, only the data needed for a delta CenRep
+            file is returned.
         """
         value = None
         if entry.crml_type in ('string', 'string8'):
@@ -404,14 +418,20 @@
         
         self._check_value(entry, value)
         
-        acc_text = self.get_access_line(entry.access)
-        if acc_text: acc_text = ' ' + acc_text
-        
-        return '%s %s %s %d%s' % (_translate_key_uid(entry.int),
-                                  entry.crml_type,
-                                  value,
-                                  entry.metadata,
-                                  acc_text)
+        if delta_cenrep:
+            return '%s %s %s' % (_translate_key_uid(entry.int),
+                                 entry.crml_type,
+                                 value)
+        else:
+            acc_text = self.get_access_line(entry.access)
+            if acc_text: acc_text = ' ' + acc_text
+            
+            return '%s %s %s %d%s' % (_translate_key_uid(entry.int),
+                                      entry.crml_type,
+                                      value,
+                                      entry.metadata,
+                                      acc_text)
+    
     def _check_value(self, entry, value):
         """
         Check that the given value is valid for the given CenRep entry,
@@ -476,7 +496,7 @@
         return ' '.join(data)
     
     def _get_feature(self, ref):
-        return self.configuration.get_default_view().get_feature(ref)
+        return self.context.configuration.get_default_view().get_feature(ref)
     
     @classmethod
     def get_index(cls,firstInt,firstIndex,indexBits,seqIndex, subIndex):
--- a/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/__init__.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/__init__.py	Tue Aug 10 14:29:28 2010 +0300
@@ -13,28 +13,11 @@
 #
 # Description: 
 #
+
 import sys, os, unittest
 
 # Path to the directory where this file is located
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
 
-# Import common plug-in initialization
-PLUGINS_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../../../..'))
-assert os.path.split(PLUGINS_ROOT)[1] == 'plugins'
-if PLUGINS_ROOT not in sys.path: sys.path.append(PLUGINS_ROOT)
-import plugin_utils
-
+from testautomation import plugin_utils
 plugin_utils.plugin_test_init(ROOT_PATH)
-
-SCRIPTS_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../../../../..', "scripts"))
-assert os.path.exists(SCRIPTS_ROOT)
-os.environ['PYTHONPATH'] = os.environ.get('PYTHONPATH', '') + ';' + SCRIPTS_ROOT + ';' + PLUGINS_ROOT
-
-def collect_suite():
-    return plugin_utils.collect_test_suite_from_dir(ROOT_PATH)
-
-def runtests():
-    unittest.TextTestRunner(verbosity=2).run(collect_suite())
-
-if __name__ == '__main__':
-    runtests()
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected/0000000E.txt has changed
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected_deltacenrep/00000002.txt has changed
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected_deltacenrep/00000003.txt has changed
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected_deltacenrep/00000005.txt has changed
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_expected_deltacenrep/00000006.txt has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer1/implml/deltacenrep_iby.implml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<container xmlns="http://www.symbianfoundation.org/xml/implml/1">
+    <tag name="crml" value="deltacenrep"/>
+    <tag name="target" value="rofs2"/>
+    <tag name="target" value="rofs3"/>
+    <phase name="post"/>
+    <settingRefsOverride refsIrrelevant="true"/>
+    
+    <templateml xmlns="http://www.s60.com/xml/templateml/1">
+        <output dir="include" file="deltacenreps.iby" encoding="UTF-8">
+<template>
+#ifndef __DELTA_CENREPS_IBY
+#define __DELTA_CENREPS_IBY
+
+{% for output in gen_context.get_output(implml_type='crml') -%}
+data = {{output.name}}			private\10202BE9\{{output.filename}} exattrib=U
+{% endfor %}
+
+#endif // __DELTA_CENREPS_IBY
+</template>
+        </output>
+    </templateml>
+</container>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer2/confml/data.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/1" name="data" version="1">
+    <data>
+        <CrmlInts>
+            <IntSetting>50</IntSetting>
+            <IntSettingHex>0xB</IntSettingHex>
+        </CrmlInts>
+        <CrmlReals>
+            <RealSetting>50.5</RealSetting>
+            <RealSetting3>11.1</RealSetting3>
+        </CrmlReals>
+        
+        <Feature2>
+            <SequenceSetting>
+                <IntSubSetting>1001</IntSubSetting>
+                <StringSubSetting>test 1</StringSubSetting>
+            </SequenceSetting>
+            <SequenceSetting>
+                <IntSubSetting>1002</IntSubSetting>
+                <StringSubSetting>test 2</StringSubSetting>
+            </SequenceSetting>
+        </Feature2>
+        <BitmaskTest>
+            <Int32Bit5>true</Int32Bit5>
+            <Int32Bit6>true</Int32Bit6>
+        </BitmaskTest>
+    </data>
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/Layer2/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<confml:configuration xmlns:confml="http://www.s60.com/xml/confml/1" xmlns:xi="http://www.w3.org/2001/XInclude" name="Layer 1">
+  <xi:include href="confml/data.confml#/"/>
+</confml:configuration>
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/gen_project/root2.confml has changed
--- a/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/runtests.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/runtests.py	Tue Aug 10 14:29:28 2010 +0300
@@ -14,6 +14,6 @@
 # Description: 
 #
 
-import __init__
-
-__init__.runtests()
+if __name__ == '__main__':
+    import nose
+    nose.core.run(argv=['collector','--include=unittest', '--verbosity=3'])
--- a/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/unittest_crml_comparator.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/unittest_crml_comparator.py	Tue Aug 10 14:29:28 2010 +0300
@@ -15,7 +15,7 @@
 #
 
 import unittest
-import __init__
+
 from cone.public import plugin
 from CRMLPlugin.crml_model import *
 from CRMLPlugin.crml_comparator import CrmlComparator
--- a/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/unittest_crml_impl.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/unittest_crml_impl.py	Tue Aug 10 14:29:28 2010 +0300
@@ -15,7 +15,6 @@
 #
 
 import sys, os, unittest
-import __init__
 
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
 
@@ -55,19 +54,19 @@
         self.assertFalse(impl.has_ref(['KeyRangeTest.Foo']))
     
     def test_list_output_files(self):
-        def oj( p2): # oj = output_join
-            return os.path.normpath(os.path.join('output', p2))
+        def on( p2): # on = output normalization
+            return os.path.normpath(p2)
         
         impl = impl_from_resource('Layer1/implml/00000001_feature1.crml', self.config)
-        self.assertEquals(impl.list_output_files(), [oj('00000001.txt')])
+        self.assertEquals(impl.list_output_files(), [on('00000001.txt')])
         
         impl = impl_from_resource('Layer1/implml/00000003_bitmask_test.crml', self.config)
-        self.assertEquals(impl.list_output_files(), [oj('00000003.txt')])
+        self.assertEquals(impl.list_output_files(), [on('00000003.txt')])
         
         gc = MockGenerationContext()
         gc.tags['target'] = ['core']
         impl.generation_context = gc
-        self.assertEquals(impl.list_output_files(), [oj('00000003.txt'), oj('private/100059C9/cenrep_rfs.txt')])
+        self.assertEquals(impl.list_output_files(), [on('00000003.txt'), on('private/100059C9/cenrep_rfs.txt')])
     
     def test_is_cenrep_rfs_txt_to_be_generated(self):
         impl = impl_from_resource('Layer1/implml/00000001_feature1.crml', self.config)
--- a/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/unittest_crml_model.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/unittest_crml_model.py	Tue Aug 10 14:29:28 2010 +0300
@@ -15,7 +15,6 @@
 #
 
 import unittest
-import __init__
 
 from cone.public import api, exceptions
 from CRMLPlugin.crml_model import *
@@ -104,6 +103,10 @@
             access      = CrmlAccess(cap_rd='ReadUserData'),
             keys        = keys)
 
+    def test_create_empty_repo(self):
+        repo = CrmlRepository()
+        self.assertEquals(repo.get_refs(), [])
+
     def test_create_repo_object(self):
         repo = CrmlRepository()
         self.assertEquals(repo.uid_value,   None)
--- a/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/unittest_crml_reader.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/unittest_crml_reader.py	Tue Aug 10 14:29:28 2010 +0300
@@ -14,23 +14,11 @@
 # Description:
 #
 
-import sys, os, unittest
-import __init__
+import os, unittest
 
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
 
-try:
-    from cElementTree import ElementTree
-except ImportError:
-    try:    
-        from elementtree import ElementTree
-    except ImportError:
-        try:
-            from xml.etree import cElementTree as ElementTree
-        except ImportError:
-            from xml.etree import ElementTree
-
-from cone.public import exceptions, plugin, api, container
+from cone.public import exceptions, plugin, api, container, utils
 
 from CRMLPlugin.crml_model import *
 from CRMLPlugin.crml_reader import CrmlReader
@@ -43,7 +31,7 @@
         self.reader = CrmlReader()
     
     def assert_read_access_equals(self, data, expected):
-        etree = ElementTree.fromstring(data)
+        etree = utils.etree.fromstring(data)
         access = self.reader.read_access(etree)
         self.assertEquals(expected, access)
     
@@ -59,7 +47,33 @@
                 """ % self.NAMESPACE
         self.assert_read_access_equals(data,
             CrmlAccess(cap_rd='AlwaysPass', cap_wr='WriteDeviceData', sid_rd='0x12345678', sid_wr='0x87654321'))
-    
+
+    def test_get_refs(self):
+        data = """<?xml version="1.0"?>
+                <repository xmlns='%s'>
+                    <access type='R' capabilities="AlwaysPass" sid="0x12345678"/>
+                    <access type='W' capabilities="WriteDeviceData" sid="0x87654321"/>
+                    <key ref="Feature1/IntSetting" name="Int setting" int="0x00000001" type="int" readOnly="false" backup="true">
+                        <access type="R" capabilities="AlwaysPass"/>
+                    </key>
+                </repository>
+                """ % self.NAMESPACE
+        etree = utils.etree.fromstring(data)
+        repo = self.reader.read_repository(etree)
+        self.assertEquals(repo.get_refs(), ['Feature1.IntSetting'])
+        
+        data = """<?xml version="1.0"?>
+                <repository xmlns='%s'>
+                    <access type='R' capabilities="AlwaysPass" sid="0x12345678"/>
+                    <access type='W' capabilities="WriteDeviceData" sid="0x87654321"/>
+                </repository>
+                """ % self.NAMESPACE
+        etree = utils.etree.fromstring(data)
+        repo = self.reader.read_repository(etree)
+        self.assertEquals(repo.get_refs(), [])
+        
+
+        
     def test_read_duplicate_access(self):
         data = """<?xml version="1.0"?>
                 <test xmlns='%s'>
@@ -74,7 +88,7 @@
     
     
     def read_key_from_xml(self, data):
-        etree = ElementTree.fromstring(data)
+        etree = utils.etree.fromstring(data)
         return self.reader.read_key(etree)
         
     def assert_read_key_equals(self, data, expected):
@@ -96,7 +110,7 @@
         self.assertRaises(exceptions.ParseError, self.read_key_from_xml, data)
     
     def assert_read_bitmask_key_equals(self, data, expected):
-        etree = ElementTree.fromstring(data)
+        etree = utils.etree.fromstring(data)
         key = self.reader.read_bitmask_key(etree)
         self.assertEquals(expected, key)
     
@@ -122,7 +136,7 @@
                                         CrmlBit(ref='BitmaskTest.Bit5', index=6, invert=True)]))
     
     def assert_read_key_range_equals(self, data, expected):
-        etree = ElementTree.fromstring(data)
+        etree = utils.etree.fromstring(data)
         key = self.reader.read_key_range(etree)
         self.assertEquals(expected, key)
     
@@ -157,7 +171,7 @@
                                   CrmlKeyRangeSubKey(ref='IntSubSetting2', name='Int2', int='0x0003', type='int')]))
     
     def assert_read_repo_equals(self, data, expected):
-        etree = ElementTree.fromstring(data)
+        etree = utils.etree.fromstring(data)
         key = self.reader.read_repository(etree)
         self.assertEquals(expected, key)
     
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/unittest_crml_validation.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,45 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import os
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+from testautomation.base_testcase import BaseTestCase
+from cone.public import api
+import cone.validation.implmlvalidation
+
+class TestCrmlValidation(BaseTestCase):
+    
+    def _run_test(self, filename):
+        filepath = 'Layer1/implml/' + filename
+        project_dir = os.path.join(ROOT_PATH, 'validation_project')
+        config      = 'root.confml'
+        
+        prj = api.Project(api.Storage.open(project_dir))
+        config = prj.get_configuration(config)
+        problems = cone.validation.implmlvalidation.validate_impls(config, filter=filepath + '$')
+        
+        self.assert_problem_list_equals_expected(
+            actual = problems,
+            expected_file = os.path.join(ROOT_PATH, 'validation_expected', filename + '.txt'),
+            outdir = os.path.join(ROOT_PATH, 'temp/validation', filename))
+    
+    def test_validate_invalid_refs(self):
+        self._run_test('00000002_invalid_refs.crml')
+    
+    def test_validate_duplicate_uids(self):
+        self._run_test('00000003_duplicate_uids.crml')
--- a/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/unittest_crml_writer.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/unittest_crml_writer.py	Tue Aug 10 14:29:28 2010 +0300
@@ -15,7 +15,6 @@
 #
 
 import sys, os, unittest, logging
-import __init__
 
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
 
@@ -66,7 +65,8 @@
 
 class TestCrmlTxtWriter(unittest.TestCase):
     def setUp(self):
-        self.writer = CrmlTxtWriter(MockConfiguration(), log)
+        self.context = plugin.GenerationContext(configuration=MockConfiguration())
+        self.writer = CrmlTxtWriter(self.context, log)
     
     def test_write_access(self):
         def check(acc, expected):
--- a/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/unittest_txt_generation.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/unittest_txt_generation.py	Tue Aug 10 14:29:28 2010 +0300
@@ -15,12 +15,11 @@
 #
 
 import sys, os, unittest
-import __init__
 
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
 
 from testautomation.base_testcase import BaseTestCase
-from cone.public import exceptions, plugin, api, container
+from cone.public import exceptions, plugin, api, container, utils
 
 from CRMLPlugin import crml_impl
 
@@ -39,11 +38,14 @@
         
         prj = api.Project(api.Storage.open(project_dir))
         config = prj.get_configuration(config)
+        gc = plugin.GenerationContext(configuration=config,
+                      output=output_dir)
+
         impls = plugin.get_impl_set(config, 'crml$')
-        impls.output = output_dir
-        impls.generation_context.tags['target'] = ['rofs2']
-        impls.generate()
-        impls.post_generate()
+        gc.tags['target'] = ['rofs2']
+        gc.filtering_disabled = True
+        impls.generate(gc)
+        impls.post_generate(gc)
         
         self.assert_dir_contents_equal(output_dir, expected_dir, ['.svn'])
     
@@ -57,11 +59,14 @@
         
         prj = api.Project(api.Storage.open(project_dir))
         config = prj.get_configuration(config)
+        gc = plugin.GenerationContext(configuration=config,
+                                      output=output_dir)
+
         impls = plugin.get_impl_set(config, 'crml$')
-        impls.output = output_dir
-        impls.generation_context.tags['target'] = []
-        impls.generate()
-        impls.post_generate()
+        gc.tags['target'] = []
+        gc.filtering_disabled = True
+        impls.generate(gc)
+        impls.post_generate(gc)
         
         self.assert_dir_contents_equal(output_dir, expected_dir, ['.svn', 'private'])
         self.assertFalse(os.path.exists(os.path.join(output_dir, 'private/100059C9/cenrep_rfs.txt')))
@@ -77,11 +82,41 @@
         
         prj = api.Project(api.Storage.open(project_dir))
         config = prj.get_configuration(config)
+        gc = plugin.GenerationContext(configuration=config,
+                                      output=output_dir)
         impls = plugin.get_impl_set(config, 'crml$')
-        impls.output = output_dir
-        impls.generation_context.tags['target'] = ['rofs2']
-        impls.generate()
-        impls.post_generate()
+        gc.tags['target'] = ['rofs2']
+        gc.filtering_disabled = True
+        impls.generate(gc)
+        impls.post_generate(gc)
         
         self.assert_dir_contents_equal(output_dir, expected_dir, ['.svn'])
     
+    def test_generate_delta_cenreps(self):
+        project_dir     = abspath('gen_project')
+        config          = 'root2.confml'
+        output_dir      = abspath('temp/gen_output_deltacenrep')
+        expected_dir    = abspath('gen_expected_deltacenrep')
+        
+        self.remove_if_exists(output_dir)
+        
+        prj = api.Project(api.Storage.open(project_dir))
+        config = prj.get_configuration(config)
+        gc = plugin.GenerationContext(configuration=config,
+                                      output=output_dir)
+        # Get refs from the last layer
+        layer = config.get_configuration_by_index(-1)
+        refs = utils.distinct_array(layer.list_leaf_datas())
+        
+        impls = plugin.get_impl_set(config, 'crml$')
+        impls = impls | plugin.get_impl_set(config, 'implml$')
+        impls = impls.filter_implementations(refs=refs)
+        
+        gc.tags['crml'] = ['deltacenrep']
+        gc.changed_refs = refs
+        gc.filtering_disabled = True
+        impls.generate(gc)
+        impls.post_generate(gc)
+        
+        output_dir = os.path.join(output_dir, 'deltacenreps')
+        self.assert_dir_contents_equal(output_dir, expected_dir, ['.svn'])
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/validation_expected/00000002_invalid_refs.crml.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+Problem(msg=u"Setting 'Foo.Bar' not found in configuration", type='model.implml.crml.invalid_ref', line=6, file='Layer1/implml/00000002_invalid_refs.crml', severity='error')
+Problem(msg=u"Setting 'Foo.Bit0' not found in configuration", type='model.implml.crml.invalid_ref', line=9, file='Layer1/implml/00000002_invalid_refs.crml', severity='error')
+Problem(msg=u"Setting 'Foo.Bit1' not found in configuration", type='model.implml.crml.invalid_ref', line=10, file='Layer1/implml/00000002_invalid_refs.crml', severity='error')
+Problem(msg=u"Setting 'Foo.Sequence.Bar' not found in configuration", type='model.implml.crml.invalid_ref', line=14, file='Layer1/implml/00000002_invalid_refs.crml', severity='error')
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/validation_expected/00000003_duplicate_uids.crml.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,7 @@
+Problem(msg='Duplicate key UID 0x00000001 (duplicate with keys on lines 6, 7 and 8)', type='model.implml.crml.duplicate_uid', line=13, file='Layer1/implml/00000003_duplicate_uids.crml', severity='error')
+Problem(msg='Duplicate key UID 0x00000002 (duplicate with key on line 10)', type='model.implml.crml.duplicate_uid', line=11, file='Layer1/implml/00000003_duplicate_uids.crml', severity='error')
+# TODO: Validation for these is still missing
+#api.Problem(msg='Duplicate bit 1 (duplicate with bits on lines 14, 15 and 16)', type=TYPE, line=17, file=FILE, severity='error'),
+#api.Problem(msg='Duplicate bit 2 (duplicate with bit on line 19)', type=TYPE, line=20, file=FILE, severity='error'),
+#api.Problem(msg='Duplicate sub-key UID 0x00000001 (duplicate with sub-keys on lines 24, 25 and 26)', type=TYPE, line=27, file=FILE, severity='error'),
+#api.Problem(msg='Duplicate sub-key UID 0x00000002 (duplicate with sub-key on line 29)', type=TYPE, line=30, file=FILE, severity='error')
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/validation_project/Layer1/confml/duplicate_uids.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/1" name="DuplicateUids">
+    <feature ref="DuplicateUids" name="Settings for duplicate UIDs test">
+        <setting ref="Int1" name="Int 1" type="int"/>
+        <setting ref="Int2" name="Int 2" type="int"/>
+        <setting ref="Int3" name="Int 3" type="int"/>
+        
+        <setting ref="Boolean1" name="Boolean 1" type="boolean"/>
+        <setting ref="Boolean2" name="Boolean 2" type="boolean"/>
+        <setting ref="Boolean3" name="Boolean 3" type="boolean"/>
+        <setting ref="Boolean4" name="Boolean 4" type="boolean"/>
+        
+        <setting ref="Sequence" name="Sequence setting" type="sequence">
+            <setting ref="Int1" name="Int 1" type="int"/>
+            <setting ref="Int2" name="Int 2" type="int"/>
+            <setting ref="Int3" name="Int 3" type="int"/>
+            <setting ref="Int4" name="Int 4" type="int"/>
+        </setting>
+    </feature>
+    <data>
+        <DuplicateUids>
+            <Int1>1</Int1>
+            <Int2>2</Int2>
+            <Int3>3</Int3>
+            
+            <Boolean1>true</Boolean1>
+            <Boolean2>false</Boolean2>
+            <Boolean3>true</Boolean3>
+            <Boolean4>false</Boolean4>
+            
+            <Sequence>
+                <Int1>1</Int1>
+                <Int2>2</Int2>
+                <Int3>3</Int3>
+                <Int4>4</Int4>
+            </Sequence>
+        </DuplicateUids>
+    </data>
+</configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/validation_project/Layer1/confml/invalid_capabilities.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/1" name="InvalidCapabilities">
+    <feature ref="InvalidCapabilities" name="Settings for invalid capabilities test">
+        <setting ref="Int1" name="Int 1" type="int"/>
+        <setting ref="Int2" name="Int 2" type="int"/>
+        <setting ref="Int3" name="Int 3" type="int"/>
+    </feature>
+    <data>
+        <InvalidCapabilities>
+            <Int1>1</Int1>
+            <Int2>2</Int2>
+            <Int3>3</Int3>
+        </InvalidCapabilities>
+    </data>
+</configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/validation_project/Layer1/confml/multiple_access_definitions.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/1" name="MultipleAccessDefinitions">
+    <feature ref="MultipleAccessDefinitions" name="Settings for duplicate UIDs test">
+        <setting ref="Int1" name="Int 1" type="int"/>
+        <setting ref="Int2" name="Int 2" type="int"/>
+        <setting ref="Int3" name="Int 3" type="int"/>
+        
+        <setting ref="Boolean1" name="Boolean 1" type="boolean"/>
+        <setting ref="Boolean2" name="Boolean 2" type="boolean"/>
+        <setting ref="Boolean3" name="Boolean 3" type="boolean"/>
+        
+        <setting ref="Sequence" name="Sequence setting" type="sequence">
+            <setting ref="Int1" name="Int 1" type="int"/>
+            <setting ref="Int2" name="Int 2" type="int"/>
+            <setting ref="Int3" name="Int 3" type="int"/>
+        </setting>
+    </feature>
+    <data>
+        <MultipleAccessDefinitions>
+            <Int1>1</Int1>
+            <Int2>2</Int2>
+            <Int3>3</Int3>
+            
+            <Boolean1>true</Boolean1>
+            <Boolean2>false</Boolean2>
+            <Boolean3>true</Boolean3>
+            
+            <Sequence>
+                <Int1>1</Int1>
+                <Int2>2</Int2>
+                <Int3>3</Int3>
+            </Sequence>
+        </MultipleAccessDefinitions>
+    </data>
+</configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/validation_project/Layer1/implml/00000002_invalid_refs.crml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<repository xmlns="http://www.s60.com/xml/cenrep/1" uidName="InvalidRefs" uidValue="0x00000002">
+    <access type="R" capabilities="AlwaysPass"/>
+    <access type="W" capabilities="AlwaysPass"/>
+    
+    <key ref="Foo/Bar" name="Foobar" int="0x00000001" type="int"/>
+    
+    <key name="Bitmask" type="int" int="0x00000002">
+        <bit ref="Foo/Bit0">1</bit>
+        <bit ref="Foo/Bit1">2</bit>
+    </key>
+
+    <keyRange firstInt="0x00010000" lastInt="0x0001FFFF" ref="Foo/Sequence" indexBits="0xFF00" firstIndex="0">
+        <key ref="Bar" name="Foo int" int="0x00000001"/>
+    </keyRange>
+</repository>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/validation_project/Layer1/implml/00000003_duplicate_uids.crml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<repository xmlns="http://www.s60.com/xml/cenrep/1" uidName="DuplicateUids" uidValue="0x00000003">
+    <access type="R" capabilities="AlwaysPass"/>
+    <access type="W" capabilities="AlwaysPass"/>
+
+    <key ref="DuplicateUids/Int1" name="Int 1" int="0x00000001" type="int"/>
+    <key ref="DuplicateUids/Int2" name="Int 2" int="0x00000001" type="int"/>
+    <key ref="DuplicateUids/Int3" name="Int 3" int="0x00000001" type="int"/>
+    
+    <key ref="DuplicateUids/Int1" name="Int 1" int="0x00000002" type="int"/>
+    <key ref="DuplicateUids/Int2" name="Int 2" int="0x00000002" type="int"/>
+  
+    <key name="Bitmask" type="int" int="0x1">
+        <bit ref="DuplicateUids/Boolean1">1</bit>
+        <bit ref="DuplicateUids/Boolean2">1</bit>
+        <bit ref="DuplicateUids/Boolean3">1</bit>
+        <bit ref="DuplicateUids/Boolean4">1</bit>
+        
+        <bit ref="DuplicateUids/Boolean1">2</bit>
+        <bit ref="DuplicateUids/Boolean2">2</bit>
+    </key>
+    
+    <keyRange firstInt="0x00010000" lastInt="0x0001FFFF" ref="DuplicateUids/Sequence" indexBits="0xFF00" firstIndex="0">
+        <key ref="Int1" name="Int 1" int="0x00000001"/>
+        <key ref="Int2" name="Int 2" int="0x0000001"/>
+        <key ref="Int3" name="Int 3" int="0x000001"/>
+        <key ref="Int4" name="Int 4" int="0x00001"/>
+        
+        <key ref="Int1" name="Int 1" int="0x00000002"/>
+        <key ref="Int2" name="Int 2" int="0x0000002"/>
+    </keyRange>
+</repository>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/validation_project/Layer1/implml/00000004_invalid_capabilities.crml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<repository xmlns="http://www.s60.com/xml/cenrep/1" uidName="InvalidCapabilities" uidValue="0x00000004">
+    <access type="R" capabilities="AlwaysPass"/>
+    <access type="W" capabilities="AlwaysPass"/>
+
+    <key ref="InvalidCapabilities/Int1" name="Int 1" int="0x00000001" type="int">
+        <!-- AlwaysPass defined in addition to others -->
+        <access type="R" capabilities="AlwaysPass MultimediaDD ReadDeviceData"/>
+    </key>
+    
+    <key ref="InvalidCapabilities/Int2" name="Int 2" int="0x00000002" type="int">
+        <!-- 8 capabilities, 7 is the maximum when there is no SID -->
+        <access type="R" capabilities="ProtServ,DiskAdmin,NetworkControl,AllFiles,SwEvent,NetworkServices,LocalServices,TrustedUi"/>
+    </key>
+    
+    <key ref="InvalidCapabilities/Int3" name="Int 3" int="0x00000003" type="int">
+        <!-- 4 capabilities, 3 is the maximum when there is a SID -->
+        <access type="R" capabilities="ProtServ,DiskAdmin,NetworkControl,AllFiles" sid="0x12344321"/>
+    </key>
+</repository>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/validation_project/Layer1/implml/00000005_multiple_access_definitions.crml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<repository xmlns="http://www.s60.com/xml/cenrep/1" uidName="MultipleAccessDefinitions" uidValue="0x00000005">
+    <access type="R" capabilities="AlwaysFail"/>
+    <access type="W" capabilities="AlwaysFail"/>
+    
+    <access type="R" capabilities="AlwaysPass"/>
+    <access type="W" capabilities="AlwaysPass"/>
+    
+    <key ref="MultipleAccessDefinitions/Int1" name="Int 1" int="0x00000001" type="int">
+        <access type="R" capabilities="AlwaysFail"/>
+        <access type="W" capabilities="AlwaysFail"/>
+        
+        <access type="R" capabilities="AlwaysPass"/>
+        <access type="W" capabilities="AlwaysPass"/>
+    </key>
+    
+    <key name="Bitmask" type="int" int="0x00000002">
+        <access type="R" capabilities="AlwaysFail"/>
+        <access type="W" capabilities="AlwaysFail"/>
+        
+        <access type="R" capabilities="AlwaysPass"/>
+        <access type="W" capabilities="AlwaysPass"/>
+        
+        <bit ref="MultipleAccessDefinitions/Boolean1">1</bit>
+        <bit ref="MultipleAccessDefinitions/Boolean2">2</bit>
+    </key>
+
+    <keyRange firstInt="0x00010000" lastInt="0x0001FFFF" ref="MultipleAccessDefinitions/Sequence" indexBits="0xFF00" firstIndex="0">
+        <access type="R" capabilities="AlwaysFail"/>
+        <access type="W" capabilities="AlwaysFail"/>
+        
+        <access type="R" capabilities="AlwaysPass"/>
+        <access type="W" capabilities="AlwaysPass"/>
+        
+        <key ref="Int1" name="Int 1" int="0x00000001"/>
+    </keyRange>
+</repository>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/validation_project/Layer1/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<confml:configuration xmlns:confml="http://www.s60.com/xml/confml/1" xmlns:xi="http://www.w3.org/2001/XInclude" name="Layer 1">
+  <xi:include href="confml/duplicate_uids.confml#/"/>
+  <xi:include href="confml/invalid_capabilities.confml#/"/>
+  <xi:include href="confml/multiple_access_definitions.confml#/"/>
+</confml:configuration>
Binary file configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/tests/validation_project/root.confml has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/CRMLPlugin/xsd/crml.xsd	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://www.s60.com/xml/cenrep/1" xmlns:cenrep="http://www.s60.com/xml/cenrep/1">
+  <xs:element name="repository">
+    <xs:complexType>
+            <xs:choice minOccurs="0" maxOccurs="unbounded">
+        <xs:element minOccurs="0" maxOccurs="2" ref="cenrep:access" />
+      	<xs:element minOccurs="0" maxOccurs="1" ref="cenrep:desc" />
+      	<xs:element minOccurs="0" maxOccurs="unbounded" ref="cenrep:key" />
+      	<xs:element minOccurs="0" maxOccurs="unbounded" ref="cenrep:keyRange" />
+      </xs:choice>
+      <xs:attribute name="backup" type="xs:boolean"/>
+      <xs:attribute name="rfs" type="xs:boolean"/>
+      <xs:attribute name="initialialisationFileVersion" type="xs:integer"/>
+      <xs:attribute name="owner" type="cenrep:hexOrDecimalNumberType"/>
+      <xs:attribute name="uidName" type="xs:string"/>
+      <xs:attribute name="uidValue" type="cenrep:hexOrDecimalNumberType"/>
+      <xs:attribute name="version" type="xs:decimal" use="optional"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="desc" type="xs:string"/>
+  <xs:element name="key">
+    <xs:complexType>
+            <xs:choice minOccurs="0" maxOccurs="unbounded">
+            	<xs:element minOccurs="0" maxOccurs="2"
+            		ref="cenrep:access" />
+            	<xs:element minOccurs="0" maxOccurs="unbounded"
+            		ref="cenrep:value" />
+            	<xs:element minOccurs="0" maxOccurs="unbounded"
+            		ref="cenrep:bit" />
+            	<xs:element ref="cenrep:desc" minOccurs="0" maxOccurs="1"></xs:element>
+            </xs:choice>
+            
+      <xs:attribute name="backup" type="xs:boolean"/>
+      <xs:attribute name="int" type="cenrep:hexOrDecimalNumberType"/>
+      <xs:attribute name="name" type="xs:string"/>
+      <xs:attribute name="readOnly" type="xs:boolean"/>
+      <xs:attribute name="ref" type="xs:string"/>
+      <xs:attribute name="type" type="cenrep:typeType"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="value">
+    <xs:complexType mixed="true">
+      <xs:attribute name="desc" />
+      <xs:attribute name="value" type="xs:string"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="bit">
+    <xs:complexType>
+      <xs:simpleContent>
+        <xs:extension base="xs:integer">
+          <xs:attribute name="ref" type="xs:string"/>
+          <xs:attribute name="value" type="xs:boolean"/>
+        </xs:extension>
+      </xs:simpleContent>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="keyRange">
+    <xs:complexType>
+      <xs:choice minOccurs="0" maxOccurs="unbounded">
+      	<xs:element ref="cenrep:desc"/>
+        <xs:element ref="cenrep:access"/>
+        <xs:element ref="cenrep:key"/>
+      </xs:choice>
+      <xs:attribute name="backup" type="xs:boolean"/>
+      <xs:attribute name="countInt" type="cenrep:hexOrDecimalNumberType"/>
+      <xs:attribute name="firstIndex" type="xs:int"/>
+      <xs:attribute name="firstInt" type="xs:string"/>
+      <xs:attribute name="indexBits" type="xs:string"/>
+      <xs:attribute name="int" type="xs:int"/>
+      <xs:attribute name="lastInt" type="xs:string"/>
+      <xs:attribute name="name" type="xs:string"/>
+      <xs:attribute name="ref" type="xs:string"/>
+      <xs:attribute name="readOnly" type="xs:boolean"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="access">
+    <xs:complexType>
+    	<xs:choice>
+    		<xs:element ref="cenrep:desc" minOccurs="0" maxOccurs="1"></xs:element>
+    	</xs:choice>
+    	<xs:attribute name="capabilities" type="xs:string" />
+    	<xs:attribute name="sid" type="xs:string" />
+    	<xs:attribute name="type" type="xs:NMTOKEN" />
+    </xs:complexType>
+  </xs:element>
+  <xs:simpleType name="typeType">
+		<xs:restriction base="xs:string">
+			<xs:enumeration id="int" value="int"></xs:enumeration>
+			<xs:enumeration value="binary"></xs:enumeration>
+			<xs:enumeration value="real"></xs:enumeration>
+			<xs:enumeration value="string"></xs:enumeration>
+			<xs:enumeration value="string8"></xs:enumeration>
+		</xs:restriction>
+	</xs:simpleType>
+    
+    <xs:simpleType name="hexOrDecimalNumberType">
+        <xs:union>
+            <xs:simpleType>
+                <xs:restriction base="xs:nonNegativeInteger"/>
+            </xs:simpleType>
+            <xs:simpleType>
+                <xs:restriction base="xs:string">
+                    <xs:pattern value="0x[0-9a-fA-F]{1,8}"/>
+                </xs:restriction>
+            </xs:simpleType>
+        </xs:union>
+    </xs:simpleType>
+
+</xs:schema>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/__init__.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,16 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
--- a/configurationengine/source/plugins/symbian/ConeCRMLPlugin/setup.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeCRMLPlugin/setup.py	Tue Aug 10 14:29:28 2010 +0300
@@ -22,6 +22,7 @@
     name = "conecrmlplugin",
     version = __version__,
     packages = find_packages(exclude=["*.tests"]),
+    package_data = {'CRMLPlugin': ['xsd/*.xsd']},
     test_suite = "crmlplugin.tests.collect_suite",
      
     # metadata for upload to PyPI
@@ -34,5 +35,6 @@
     zip_safe = True,
     
     # entrypoint info
-    entry_points={'cone.plugins.implmlreaders': ['crml = CRMLPlugin.crml_reader:CrmlReader']}
+    entry_points={'cone.plugins.implmlreaders':  ['crml = CRMLPlugin.crml_reader:CrmlReader'],
+                  'cone.plugins.implvalidators': ['crml = CRMLPlugin.crml_validators:VALIDATOR_CLASSES']}
 )
--- a/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/confflattener.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/confflattener.py	Tue Aug 10 14:29:28 2010 +0300
@@ -82,8 +82,14 @@
         toview = to_config.get_default_view()
         for fea in toview.get_features('**'):
             fromfea = dview_from.get_feature(fea.fqr)
-            if fromfea.get_value() != None:
-                fea.set_value(fromfea.get_value())
+            # If the value is an empty list, don't add it.
+            # This is because an empty list means that we have
+            # a sequence setting or sequence sub-setting that doesn't have
+            # any contents, and calling set_value() would create a data
+            # element for it with the attribute empty="true".
+            val = fromfea.get_value()
+            if val not in (None, []):
+                fea.set_value(val)
         return to_config
 
     def create_configuration(self, conf_from_org, settings, path="tempfile.confml"):
--- a/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/genconfmlplugin.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/genconfmlplugin.py	Tue Aug 10 14:29:28 2010 +0300
@@ -26,6 +26,7 @@
 import xslttransformer
 import codecs
 import tempfile
+import pkg_resources
 import tempfile
 
 try:
@@ -39,7 +40,6 @@
         except ImportError:
             from xml.etree import ElementTree
 
-import __init__
 
 from cone.public import exceptions,plugin,utils,api
 from cone.confml import persistentconfml
@@ -52,7 +52,7 @@
     IMPL_TYPE_ID = "gcfml"
     
     
-    def __init__(self,ref,configuration, output='output', linesep=os.linesep, reader=None):
+    def __init__(self,ref,configuration, output='', linesep=os.linesep, reader=None):
         """
         Overloading the default constructor
         """
@@ -63,7 +63,7 @@
         self.xslt_temp_file_name = os.path.join(tempfile.gettempdir(), "genconfml_temp_%i.xslt" % os.getpid())
         self.set_output_root(output)
         self.linesep = linesep
-        self._flatconfig = None
+        self.flatconfig = None
         self.temp_confml_file = os.path.join(tempfile.gettempdir(),'temp_flatted_%i.confml' % os.getpid())
         self.reader = reader
 
@@ -71,19 +71,28 @@
         """
         Generate the given implementation.
         """
+        self.context = context
         self.create_output()
         return 
     
     def get_refs(self):
+        """
+        Get the list of references used inside this gcfml object.
+        """
         result = []
+        refs = []
         for ref in self.reader.settings:
             # Process the reference, so that it will work with has_ref().
             # E.g. 'MyFeature/MySetting' -> 'MyFeature.MySetting'
             #      'MyFeature/*          -> 'MyFeature'
             ref = ref.replace('/', '.')
-            if ref.endswith('.*'):
-                ref = ref[:-2]
-            result.append(ref)
+            refs.append(ref)
+            
+        # Traverse through actual features in the default view, to get a full list 
+        # of refs in case of wildcard usage
+        dview = self.configuration.get_default_view()
+        for fea in dview.get_features(refs):
+            result.append(fea.fqr)
         return result
       
     def list_output_files(self):
@@ -113,7 +122,7 @@
         """ Generate all output """
         resource = self.configuration.get_resource(self.ref)
         write_element_enc(self.reader.stylesheet_elem, self.xslt_temp_file_name, self.reader.stylesheet_output_enc)
-        gen = Generator()
+        gen = Generator(self)
         
         target = self.reader.target
         if target == None: target = ""
@@ -126,10 +135,12 @@
         
         self.logger.info('Generating %s' % output_file)
         
-        flatted_conf_as_element = persistentconfml.ConfmlWriter().dumps(self.flatconfig)
+        flatted_conf_as_element = persistentconfml.ConfmlWriter().dumps(self.get_flatconfig())
         postprocessed_element = self.post_process_flattening(flatted_conf_as_element)
         write_element_enc(postprocessed_element, self.temp_confml_file, self.reader.stylesheet_output_enc)
-        gen.generate(self.configuration, resource, output_file, self.xslt_temp_file_name, self.reader.settings, self.reader.stylesheet_output_enc)
+        gen.generate(self.context, resource, output_file, self.xslt_temp_file_name, self.reader.settings, self.reader.stylesheet_output_enc,
+                     line_ending_style = self.reader.line_ending_style)
+
       
     def post_process_flattening(self, element):
         """
@@ -144,21 +155,20 @@
             new_doc = "<?xml version=\"1.0\"?><configuration>" + ElementTree.tostring(data_element) + "</configuration>"
         return ElementTree.fromstring(new_doc)
 
-    @property
-    def flatconfig(self):
-      """ 
-      Create a flat configuration from the current configuration with the given setting refs.
-      Take the last configuration element, which will contain the data elements
-      """ 
-      if not self._flatconfig:
-          try:
-              cf = confflattener.ConfigurationFlattener()
-              self._flatconfig = api.Configuration()
-              cf.flat(self.configuration, self.reader.settings, self._flatconfig)
-          except (exceptions.ConeException, TypeError, Exception), e:
-              utils.log_exception(self.logger, 'Failed to flat configuration with settings %s. Exception: %s' % (self.reader.settings, e))
-              raise exceptions.ConeException('Failed to flat configuration. Exception: %s' % e)
-      return self._flatconfig
+    def get_flatconfig(self):
+        """ 
+        Create a flat configuration from the current configuration with the given setting refs.
+        Take the last configuration element, which will contain the data elements
+        """ 
+        if not self.flatconfig:
+            try:
+                cf = confflattener.ConfigurationFlattener()
+                self.flatconfig = api.Configuration()
+                cf.flat(self.configuration, self.reader.settings, self.flatconfig)
+            except (exceptions.ConeException, TypeError, Exception), e:
+                utils.log_exception(self.logger, 'Failed to flat configuration with settings %s. Exception: %s' % (self.reader.settings, e))
+                raise exceptions.ConeException('Failed to flat configuration. Exception: %s' % e)
+        return self.flatconfig
 
 
 def write_element(element, output, linesep=os.linesep):
@@ -221,7 +231,7 @@
         try:
             tempfile.write(ElementTree.tostring(element))
         except Exception, e:
-            raise exceptions.ConeException('Cannot write Element to file (%s). Exception: %s' % (output, e))
+            raise exceptions.ConeException('Cannot write Element to file (%s). Exception: %s' % (tempfile, e))
     else:
         raise exceptions.ConeException('Cannot write element to file, because None element passed or not Element passed.')
     
@@ -230,6 +240,8 @@
     Parses a single gcfml file
     """ 
     NAMESPACE = 'http://www.s60.com/xml/genconfml/1'
+    NAMESPACE_ID = 'gcfml'
+    ROOT_ELEMENT_NAME = 'file'
     IGNORED_NAMESPACES = ['http://www.w3.org/1999/XSL/Transform', 
                           'http://www.w3.org/2001/xinclude']
     FILE_EXTENSIONS = ['gcfml']
@@ -251,17 +263,27 @@
         reader = GenconfmlImplReader()
         reader.from_etree(etree)
         return GenconfmlImpl(resource_ref, configuration, reader=reader)
-            
+    
+    @classmethod
+    def get_schema_data(cls):
+        return pkg_resources.resource_string('genconfmlplugin', 'xsd/gcfml.xsd')
+        
     def from_etree(self, etree):
         self.stylesheet = self.parse_stylesheet(etree)
         self.settings = self.parse_settings(etree)
-        self.name = self.parse_name(etree)
-        self.subdir = self.parse_subdir(etree)        
-        self.target = self.parse_target(etree)
+        self.target = etree.get('target', '')
+        self.name = etree.get('name', '')
+        self.subdir = etree.get('subdir', '')
+        self.line_ending_style = etree.get('lineEndingStyle')
         self.stylesheet_elem = self.parse_stylesheet_elem(etree)
         self.stylesheet_output_enc = self.parse_stylesheet_output_enc(etree)
         self.nss = self.parse_stylesheet_nss(etree)
         
+        if self.line_ending_style not in (None, 'CRLF', 'LF'):
+            raise exceptions.ImplmlParseError(
+                "Invalid line ending style '%s' (should be omitted or one "
+                "of ['CRLF', 'LF'])" % self.line_ending_style)
+        
         return
 
     def parse_target(self, etree):
@@ -271,8 +293,8 @@
         
         target = ""
         for elem in etree.getiterator("{%s}file" % self.namespaces[2]):
-          if elem != None:
-              target = elem.get('target')
+            if elem != None:
+                target = elem.get('target')
         
         return target
     
@@ -283,8 +305,8 @@
         
         name = ""
         for elem in etree.getiterator("{%s}file" % self.namespaces[2]):
-          if elem != None:
-              name = elem.get('name')
+            if elem != None:
+                name = elem.get('name')
         
         return name
 
@@ -295,8 +317,8 @@
         
         subdir = ""
         for elem in etree.getiterator("{%s}file" % self.namespaces[2]):
-          if elem != None:
-              subdir = elem.get('subdir')
+            if elem != None:
+                subdir = elem.get('subdir')
         if subdir == None:
             subdir = ""
         
@@ -350,21 +372,21 @@
         settings = []
         
         for elem in etree.getiterator("{%s}file" % self.namespaces[2]):
-          if elem != None:
-              setting_elems = elem.findall("{%s}setting" % self.namespaces[2])
-              for setting_elem in setting_elems:
-                  if setting_elem != None:
-                      settings.append(setting_elem.get('ref'))
-        
+            if elem != None:
+                setting_elems = elem.findall("{%s}setting" % self.namespaces[2])
+                for setting_elem in setting_elems:
+                    if setting_elem != None:
+                        settings.append(setting_elem.get('ref'))
         return settings
     
 class Generator(object):
     """
     Genconfml generator
     """ 
-    def __init__(self):
+    def __init__(self, implml):
         self.temp_confml_file = os.path.join(tempfile.gettempdir(),'temp_flatted_%i.confml' % os.getpid())
-        pass
+        self.context = None
+        self.implml = implml
 
     def post_process_flattening(self, element):
         """
@@ -380,17 +402,25 @@
         return ElementTree.fromstring(new_doc)
 
 
-    def generate(self, configuration, input, output, xslt, settings, enc=sys.getdefaultencoding()):
+    def generate(self, context, input, output, xslt, settings, enc=sys.getdefaultencoding(),
+                 line_ending_style=None):
         """
         Generates output
         """
+        self.context = context
         self.logger = logging.getLogger('cone.gcfml{%s}' % input.path)
 
+        if line_ending_style == 'LF':
+            linesep = '\n'
+        else:
+            linesep = '\r\n'
         
         try:
             tf = xslttransformer.XsltTransformer()
-            tf.transform_lxml(os.path.abspath(self.temp_confml_file), os.path.abspath(xslt), output, enc)
-            #tf.transform_4s(os.path.abspath(self.temp_confml_file), os.path.abspath(xslt), output, enc)
+            result = tf.transform_lxml(os.path.abspath(self.temp_confml_file), os.path.abspath(xslt), enc, linesep)
+            if not self.filter_file_writing(result):
+                self.write_string_to_file(result, output, enc)
+
         except (exceptions.ConeException, TypeError, Exception), e:
             logging.getLogger('cone.gcfml').warning('Failed to do XSLT tranformation. Exception: %s' % e)
             raise exceptions.ConeException('Failed to do XSLT tranformation. Exception: %s' % e)
@@ -399,3 +429,32 @@
         if not logging.getLogger('cone').getEffectiveLevel() != 10:
             os.remove(os.path.abspath(self.temp_confml_file))
             os.remove(os.path.abspath(xslt))
+
+    def filter_file_writing(self, string):
+        """
+        Returns True if writing result file should be ignored.
+        """
+        string = string.rstrip('\n\r')
+        if string == '' or string == '<?xml version="1.0" encoding="UTF-16"?>' or \
+            string == '<?xml version="1.0" encoding="UTF-8"?>':
+            return True
+        
+        return False
+
+    def write_string_to_file(self, string, output, enc):
+        """
+        Writes string to file
+        """
+        try:
+            
+            #fl = codecs.open(outfile, 'w', enc)
+            fl = self.context.create_file(output, 
+                                          implementation=self.implml,
+                                          mode='w',
+                                          encoding=enc)
+            fl.write(string)
+            fl.close()
+            
+        except Exception, e:
+            logging.getLogger('cone.gcfml').error('Cannot write Element to file (%s). Exception: %s' % (output, e))
+            raise exceptions.ConeException('Cannot write Element to file (%s). Exception: %s' % (output, e))
--- a/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/__init__.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/__init__.py	Tue Aug 10 14:29:28 2010 +0300
@@ -13,24 +13,12 @@
 #
 # Description: 
 #
+
 import sys, os, unittest
 
 # Path to the directory where this file is located
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
 
-# Import common plug-in initialization
-PLUGINS_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../../../..'))
-assert os.path.split(PLUGINS_ROOT)[1] == 'plugins'
-if PLUGINS_ROOT not in sys.path: sys.path.append(PLUGINS_ROOT)
-import plugin_utils
-
+from testautomation import plugin_utils
 plugin_utils.plugin_test_init(ROOT_PATH)
 
-def collect_suite():
-    return plugin_utils.collect_test_suite_from_dir(ROOT_PATH)
-
-def runtests():
-    unittest.TextTestRunner(verbosity=2).run(collect_suite())
-
-if __name__ == '__main__':
-    runtests()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root1/endline_crlf.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+
+default 1
+default 2
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root1/endline_lf.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+
+default 1
+default 2
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root2/endline_crlf.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,7 @@
+
+default 1
+default 2
+layer2 (1)
+layer2 (2)
+layer2 (3)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root2/endline_lf.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,7 @@
+
+default 1
+default 2
+layer2 (1)
+layer2 (2)
+layer2 (3)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root3/endline_crlf.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,9 @@
+
+layer3 (2)
+layer3 (1)
+default 1
+default 2
+layer2 (1)
+layer2 (2)
+layer2 (3)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root3/endline_lf.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,9 @@
+
+layer3 (2)
+layer3 (1)
+default 1
+default 2
+layer2 (1)
+layer2 (2)
+layer2 (3)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root4/endline_crlf.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+
+layer4 (1)
+layer4 (2)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/expected/root4/endline_lf.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+
+layer4 (1)
+layer4 (2)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer1/implml/line_ending_conversion_crlf.gcfml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,11 @@
+<file xmlns="http://www.s60.com/xml/genconfml/1" name="endline_crlf.txt" lineEndingStyle='CRLF'>
+	<setting ref="Feature2/SequenceSetting"/>
+	<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/TR/xhtml1/strict">
+		<xsl:output method="text" encoding="UTF-8"/>
+		<xsl:template match="configuration/data">
+			<xsl:for-each select="Feature2/SequenceSetting">
+				<xsl:value-of select="StringSubSetting"/><xsl:text>&#xA;</xsl:text>
+			</xsl:for-each>
+		</xsl:template>
+	</xsl:stylesheet>
+</file>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/Layer1/implml/line_ending_conversion_lf.gcfml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,11 @@
+<file xmlns="http://www.s60.com/xml/genconfml/1" name="endline_lf.txt" lineEndingStyle='LF'>
+	<setting ref="Feature2/SequenceSetting"/>
+	<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/TR/xhtml1/strict">
+		<xsl:output method="text" encoding="UTF-8"/>
+		<xsl:template match="configuration/data">
+			<xsl:for-each select="Feature2/SequenceSetting">
+				<xsl:value-of select="StringSubSetting"/><xsl:text>&#xA;</xsl:text>
+			</xsl:for-each>
+		</xsl:template>
+	</xsl:stylesheet>
+</file>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/project/assets/s60/implml/commsdatcreator_01.gcfml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,15 @@
+<file xmlns="http://www.s60.com/xml/genconfml/1" name="VariantData_commsdat.xml" target="private\10281BC3\">			 
+
+	<setting ref="APs/*"/>
+	<setting ref="WLAN_APs/*"/>
+	
+	<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xi="http://www.w3.org/2001/xinclude">
+		<xsl:output method="xml" indent="yes" encoding="UTF-8"/>
+		<xsl:template match="configuration">
+		<data>
+			<xsl:copy-of select="data/APs"/>
+			<xsl:copy-of select="data/WLAN_APs"/>
+		</data>
+		</xsl:template>				
+	</xsl:stylesheet>
+</file>
\ No newline at end of file
--- a/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/runtests.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/runtests.py	Tue Aug 10 14:29:28 2010 +0300
@@ -14,6 +14,6 @@
 # Description: 
 #
 
-import __init__
-
-__init__.runtests()
+if __name__ == '__main__':
+    import nose
+    nose.core.run(argv=['collector','--include=unittest', '--verbosity=3'])
--- a/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/unittest_confflattener.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/unittest_confflattener.py	Tue Aug 10 14:29:28 2010 +0300
@@ -14,14 +14,12 @@
 # Description: 
 #
 
-import unittest, os, shutil
+import unittest, os
 import copy
 
-import __init__	
 from genconfmlplugin import confflattener
-from cone.public import exceptions,plugin,api
+from cone.public import api
 from cone.storage import filestorage
-from cone.confml import implml
 
 # Hardcoded value of testdata folder that must be under the current working dir
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
--- a/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/unittest_gcfml_plugin.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/unittest_gcfml_plugin.py	Tue Aug 10 14:29:28 2010 +0300
@@ -14,13 +14,12 @@
 # Description: 
 #
 
-import unittest, os, shutil
+import unittest, os
 
-import __init__	
 from genconfmlplugin import genconfmlplugin
-from cone.public import exceptions,plugin,api
+from cone.public import plugin,api
 from cone.storage import filestorage
-from cone.confml import implml
+
 
 try:
     from cElementTree import ElementTree
@@ -154,6 +153,16 @@
         self.assertTrue(impl.has_ref(['Contacts.Contact.FirstName']))
         self.assertFalse(impl.has_ref(['Contacts.OtherSetting']))
         
+    def test_get_refs(self):
+        fs = filestorage.FileStorage(testdata)
+        p = api.Project(fs)
+        config = p.get_configuration('product.confml')
+        impls = plugin.get_impl_set(config,'\.gcfml$')
+        impls.output = self.output
+        impl = impls.get_implementations_by_file('assets/s60/implml/commsdatcreator_01.gcfml')[0]
+        self.assertEquals(impl.get_refs(), ['APs.AP', 'WLAN_APs.WLAN_AP'])
+        self.assertTrue(impl.has_ref(['APs.AP']))
+        
     def test_list_output_files(self):
         fs = filestorage.FileStorage(testdata)
         p = api.Project(fs)
@@ -161,7 +170,10 @@
         impls = plugin.get_impl_set(config,'\.gcfml$')
         impls.output = self.output
         impl = impls.get_implementations_by_file('assets/s60/implml/predefinedcontacts.gcfml')[0]
-        self.assertEquals(impl.list_output_files(), ['output\\private\\2000BEE5\\predefinedcontacts.xml'])
+        
+        normalize_slash = lambda l: map(lambda p: p.replace('\\', '/'), l)
+        self.assertEquals(normalize_slash(impl.list_output_files()),
+                          ['private/2000BEE5/predefinedcontacts.xml'])
 
     
 if __name__ == '__main__':
--- a/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/unittest_generation.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/unittest_generation.py	Tue Aug 10 14:29:28 2010 +0300
@@ -14,13 +14,12 @@
 # Description:
 #
 
-import sys, os, unittest
-import __init__
+import os
 
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
 
 from testautomation.base_testcase import BaseTestCase
-from cone.public import exceptions, plugin, api, container
+from cone.public import plugin, api
 
 def abspath(path):
     return os.path.normpath(os.path.join(ROOT_PATH, path))
@@ -43,8 +42,10 @@
         
         prj = api.Project(api.Storage.open(project_dir))
         config = prj.get_configuration(config)
+        context = plugin.GenerationContext(configuration=config,
+                                           output=output_dir)
+        context.filtering_disabled = True
         impls = plugin.get_impl_set(config, 'gcfml$')
-        impls.output = output_dir
-        impls.generate()
+        impls.generate(context)
         
         self.assert_dir_contents_equal(output_dir, expected_dir, ['.svn'] + ignores)
--- a/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/unittest_xslttransformer.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/tests/unittest_xslttransformer.py	Tue Aug 10 14:29:28 2010 +0300
@@ -14,19 +14,17 @@
 # Description: 
 #
 
-import unittest, os, shutil, sys
+import unittest, os, sys
 
-import __init__	
 from genconfmlplugin import xslttransformer
-from cone.public import exceptions,plugin,api
-from cone.storage import filestorage
-from cone.confml import implml
 
 # Hardcoded value of testdata folder that must be under the current working dir
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
 testdata  = os.path.join(ROOT_PATH,'project')
+expected = u'<html><body>\r\n<h2>My CD Collection</h2>\r\n<table border="1">\r\n<tr bgcolor="#9acd32">\r\n<th>Title</th>\r\n<th>Artist</th>\r\n</tr>\r\n<tr>\r\n<td>.</td>\r\n<td>.</td>\r\n</tr>\r\n</table>\r\n</body></html>\r\n\r\n'.replace('\r\n', os.linesep)
 
-class TestGenconfmlPlugin(unittest.TestCase):    
+
+class TestXstlTransformer(unittest.TestCase):    
     def setUp(self):
         self.curdir = os.getcwd()
         self.output = 'output'
@@ -40,12 +38,11 @@
         Test that the xslt transformation works
         '''
         transformer = xslttransformer.XsltTransformer()
-        transformer.transform_lxml(os.path.join(ROOT_PATH,"xslt\cdcatalog.xml"), 
-                                 os.path.join(ROOT_PATH,"xslt\cdcatalog_ex1.xsl"), 
-                                 "testioutput.xml",
+        result = transformer.transform_lxml(os.path.join(ROOT_PATH,"xslt/cdcatalog.xml"), 
+                                 os.path.join(ROOT_PATH,"xslt/cdcatalog_ex1.xsl"), 
                                  sys.getdefaultencoding())
-        os.unlink("testioutput.xml")
+        self.assertEquals(result, expected)
 
         
 if __name__ == '__main__':
-  unittest.main()
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/xsd/gcfml.xsd	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://www.s60.com/xml/genconfml/1" xmlns:gcfml="http://www.s60.com/xml/genconfml/1" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+  <xs:import namespace="http://www.w3.org/1999/XSL/Transform"/>
+  <xs:element name="file">
+    <xs:complexType>
+    	<xs:choice minOccurs="0" maxOccurs="unbounded">
+        	<xs:element minOccurs="1" maxOccurs="unbounded" ref="gcfml:setting" />
+        	<xs:any namespace="http://www.w3.org/1999/XSL/Transform" processContents="skip"/>
+      	</xs:choice>
+      	<xs:attribute name="target" type="xs:string" use="optional"/>
+      	<xs:attribute name="name" type="xs:string" use="required"/>
+        <xs:attribute name="lineEndingStyle" type="xs:string" use="optional"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="setting">
+    <xs:complexType>
+      <xs:attribute name="ref" type="xs:string" use="required"/>
+    </xs:complexType>
+  </xs:element>
+</xs:schema>
--- a/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/xslttransformer.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/xslttransformer.py	Tue Aug 10 14:29:28 2010 +0300
@@ -18,30 +18,14 @@
 '''
 
 
-import re
 import os
 import sys
-import codecs
 import logging
-import xml.parsers.expat
-import unittest, os, sys, pkg_resources
+import pkg_resources
 
 pkg_resources.require('lxml')
 
-try:
-    from cElementTree import ElementTree
-except ImportError:
-    try:    
-        from elementtree import ElementTree
-    except ImportError:
-        try:
-            from xml.etree import cElementTree as ElementTree
-        except ImportError:
-            from xml.etree import ElementTree
-
-import __init__
-
-from cone.public import exceptions,plugin,utils,api
+from cone.public import exceptions
 
 class XsltTransformer():
     """
@@ -52,117 +36,51 @@
         self.logger = logging.getLogger('cone.gcfml(%s)' % self.ref)
 
 
-    def transform_lxml(self, input, xslt, output, enc, linesep=os.linesep):
-      """
-      XSLT transform with lxml.
-      """
-      from lxml import etree
-      
-      if not enc:
-          enc = sys.getdefaultencoding()
-      try:
-          xslt_doc = etree.parse(xslt)
-          transform = etree.XSLT(xslt_doc)
-          
-          input_doc = etree.parse(input)
-          result = str(transform(input_doc))                   
-          postprocessed_result = post_process_result(result, enc, linesep)
-          
-          if not filter_file_writing(postprocessed_result):
-              write_string_to_file(postprocessed_result, output, enc)
+    def transform_lxml(self, input, xslt, enc, linesep=os.linesep):
+        """
+        XSLT transform with lxml.
+        """
+        from lxml import etree
         
-      except Exception, e:
-          logging.getLogger('cone.gcfml').error('Failed to do XSLT transformation: %s' % e)
-          raise exceptions.ConeException('Failed to do XSLT transformation: %s' % (e))
-
-
-    def transform_4s(self, input, xslt, output, enc, linesep=os.linesep):
-      """
-      XSLT transform with 4Suite
-      """
-      from Ft.Xml.Xslt import Transform
-      from Ft.Xml.Xslt import Processor
-      from Ft.Xml import InputSource
-      from Ft.Lib.Uri import OsPathToUri  
-
-      
-      if not enc:
-          enc = sys.getdefaultencoding()
-      
-      try:
-          processor = Processor.Processor()
+        if not enc:
+            enc = sys.getdefaultencoding()
+        try:
+            xslt_doc = etree.parse(xslt)
+            transform = etree.XSLT(xslt_doc)
+            
+            input_doc = etree.parse(input)
+            result = str(transform(input_doc))                   
+            postprocessed_result = post_process_result(result, enc, linesep)
+            return postprocessed_result
           
-          srcAsUri = OsPathToUri(input)
-          source = InputSource.DefaultFactory.fromUri(srcAsUri)
-
-          ssAsUri = OsPathToUri(xslt)
-          transform = InputSource.DefaultFactory.fromUri(ssAsUri)
-
-          processor.appendStylesheet(transform)
-          result = processor.run(source)
-          
-          postprocessed_result = post_process_result(result, enc, linesep)
-          
-          if not filter_file_writing(postprocessed_result):
-              write_string_to_file(postprocessed_result, output, enc)
-        
-      except Exception, e:
-          logging.getLogger('cone.gcfml').error('Failed to do XSLT transformation: %s' % e)
-          raise exceptions.ConeException('Failed to do XSLT transformation: %s' % (e))
-
-def filter_file_writing(string):
-    """
-    Returns True if writing result file should be ignored.
-    """
-    string = string.rstrip('\n\r')
-    if string == '' or string == '<?xml version="1.0" encoding="UTF-16"?>' or \
-        string == '<?xml version="1.0" encoding="UTF-8"?>':
-        return True
-    
-    return False
+        except Exception, e:
+            logging.getLogger('cone.gcfml').error('Failed to do XSLT transformation: %s' % e)
+            raise exceptions.ConeException('Failed to do XSLT transformation: %s' % (e))
 
 
 def post_process_result(string, enc, linesep):
-  """
-  Does post process for result from XSLT transform
-      - encoding
-      - removes extra line separators
-      - changes line separators
-  """
-  output_string = None
-  
-  try:
-      output_string = string.decode(enc)
-      if not output_string.startswith('<'):
-          output_string = '\n' + output_string
-      output_string = output_string.replace('<?xml version="1.0" encoding="UTF-16"?>', '<?xml version="1.0" encoding="UTF-16"?>\n\n')
-      output_string = output_string.replace('<?xml version="1.0" encoding="UTF-8"?>', '<?xml version="1.0" encoding="UTF-8"?>\n\n')
-      output_string = output_string.replace('\n\n','\n')
-      output_string = output_string.replace('\n', linesep)
-      output_string+= linesep
-  except Exception, e:
-      logging.getLogger('cone.gcfml').error('Cannot post process result: %s \nException: %s' % (string, e))
-      raise exceptions.ConeException('Cannot post process result: %s \nException: %s' % (string, e))
-  
-  return output_string
-
-def write_string_to_file(string, output, enc):
-  """
-  Writes string to file
-  """
-  try:
-      outfile = os.path.abspath(output)
-      
-      if not os.path.exists(os.path.dirname(outfile)):
-          os.makedirs(os.path.dirname(outfile))
-          
-      fl = codecs.open(outfile, 'w', enc)
-      fl.write(string)
-      fl.close()
-      
-  except Exception, e:
-      logging.getLogger('cone.gcfml').error('Cannot write Element to file (%s). Exception: %s' % (output, e))
-      raise exceptions.ConeException('Cannot write Element to file (%s). Exception: %s' % (output, e))
+    """
+    Does post process for result from XSLT transform
+        - encoding
+        - removes extra line separators
+        - changes line separators
+    """
+    output_string = None
+    
+    try:
+        output_string = string.decode(enc)
+        if not output_string.startswith('<'):
+            output_string = '\n' + output_string
+        output_string = output_string.replace('<?xml version="1.0" encoding="UTF-16"?>', '<?xml version="1.0" encoding="UTF-16"?>\n\n')
+        output_string = output_string.replace('<?xml version="1.0" encoding="UTF-8"?>', '<?xml version="1.0" encoding="UTF-8"?>\n\n')
+        output_string = output_string.replace('\n\n','\n')
+        output_string = output_string.replace('\n', linesep)
+        output_string+= linesep
+    except Exception, e:
+        logging.getLogger('cone.gcfml').error('Cannot post process result: %s \nException: %s' % (string, e))
+        raise exceptions.ConeException('Cannot post process result: %s \nException: %s' % (string, e))
+    
+    return output_string
 
 
 
--- a/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/setup.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/setup.py	Tue Aug 10 14:29:28 2010 +0300
@@ -25,6 +25,7 @@
     name = "conegenconfmlplugin",
     version = __version__,
     packages = find_packages(exclude=["*.tests"]),
+    package_data = {'genconfmlplugin': ['xsd/*.xsd']},
     test_suite = "genconfml.tests.collect_suite",
 	install_requires = ['lxml>=2.2.2'],
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeHCRPlugin/__init__.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,16 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
--- a/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/hcr_writer.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/hcr_writer.py	Tue Aug 10 14:29:28 2010 +0300
@@ -14,13 +14,9 @@
 # Description: 
 #
 
-import logging
-import __init__
-  
 
-from struct import pack, unpack
+from struct import pack
 
-from cone.public import exceptions,plugin,utils,api
 from hcrplugin.hcrrepository import HcrRecord
 from hcrplugin.hcr_exceptions import *
 from hcrplugin.hcr_header import HcrHeader
--- a/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/hcrml_parser.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/hcrml_parser.py	Tue Aug 10 14:29:28 2010 +0300
@@ -18,29 +18,15 @@
 
 
 import re
-import os
-import sys
 import logging
-import xml.parsers.expat
-import codecs
+import pkg_resources
+
 from hcrplugin.hcr_exceptions import *
 from hcrplugin.hcrrepository import HcrRecord, HcrRepository
 from hcrplugin.hcr_writer import HcrWriter
 from hcrplugin.header_writer import *
-try:
-    from cElementTree import ElementTree
-except ImportError:
-    try:    
-        from elementtree import ElementTree
-    except ImportError:
-        try:
-            from xml.etree import cElementTree as ElementTree
-        except ImportError:
-            from xml.etree import ElementTree
 
-import __init__
-
-from cone.public import exceptions,plugin,utils,api
+from cone.public import plugin
 
 class HcrmlImpl(plugin.ImplBase):
     """
@@ -62,25 +48,20 @@
         @return: 
         """
         outputfile = self.__get_output_filename()
-        if outputfile != None:
-            # Create the path to the output file
-            output_path = os.path.dirname(outputfile)
-            if output_path != '' and not os.path.exists(output_path):
-                os.makedirs(output_path)
-        
         # For output type 'hcr', write the binary repository file
         if self.output_obj.type == 'hcr':
             self.logger.info("Generating binary repository to '%s'" % outputfile)
             writer = HcrWriter()
             repo = self.output_obj.get_hcr_repository()
             data = writer.get_repository_bindata(repo)
-            f = open(outputfile,'wb')
+            f = context.create_file(outputfile, mode='wb')
+            #f = open(outputfile,'wb')
             try:        f.write(data)
             finally:    f.close()
         elif self.output_obj.type == 'header':
             self.logger.info("Generating header file to '%s'" % outputfile)
             writer = HeaderWriter(outputfile, self.output_obj)
-            writer.write()
+            writer.write(context)
         elif self.output_obj.type == None:
             # The HCRML file contains no <output> element, so no output should
             # be generated
@@ -105,6 +86,8 @@
 
 class HcrmlReader(plugin.ReaderBase):
     NAMESPACE = 'http://www.symbianfoundation.org/xml/hcrml/1'
+    NAMESPACE_ID = 'hcrml'
+    ROOT_ELEMENT_NAME = 'hcr'
     FILE_EXTENSIONS = ['hcrml']
     
     def __init__(self, resource_ref, configuration):
@@ -123,7 +106,11 @@
         impl.output_obj = reader.read_hcrml_output()
         impl.refs = reader.refs
         return impl
-
+    
+    @classmethod
+    def get_schema_data(cls):
+        return pkg_resources.resource_string('hcrplugin', 'xsd/hcrml.xsd')
+    
     def read_hcrml_output(self, ignore_includes=False):
         output = Output()
         
--- a/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/hcrrepository.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/hcrrepository.py	Tue Aug 10 14:29:28 2010 +0300
@@ -14,10 +14,7 @@
 # Description: 
 #
 
-import logging
-import __init__
 
-from cone.public import exceptions,plugin,utils,api
 
 class HcrRepository(object):
     FLAG_READ_ONLY    = 1
--- a/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/header_writer.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/header_writer.py	Tue Aug 10 14:29:28 2010 +0300
@@ -17,11 +17,11 @@
 import os
 
 class HeaderWriter(object):
-    def __init__(self,output_file, output_obj):
+    def __init__(self, output_file, output_obj):
         self.output_obj = output_obj
         self.output_file = output_file
 
-    def write(self):
+    def write(self, context):
         header_guard = os.path.basename(self.output_file).upper()
         header_guard = header_guard.replace('/', '_').replace('\\', '_').replace('.', '_')
         lines = [
@@ -56,6 +56,6 @@
             "#endif",
         ])
         
-        f = open(self.output_file, 'wb')
-        try:        f.write(os.linesep.join(lines))
+        f = context.create_file(self.output_file, mode='wb')
+        try:        f.write('\r\n'.join(lines))
         finally:    f.close()
--- a/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/__init__.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/__init__.py	Tue Aug 10 14:29:28 2010 +0300
@@ -13,24 +13,12 @@
 #
 # Description: 
 #
+
 import sys, os, unittest
 
 # Path to the directory where this file is located
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
 
-# Import common plug-in initialization
-PLUGINS_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../../../..'))
-assert os.path.split(PLUGINS_ROOT)[1] == 'plugins'
-if PLUGINS_ROOT not in sys.path: sys.path.append(PLUGINS_ROOT)
-import plugin_utils
-
+from testautomation import plugin_utils
 plugin_utils.plugin_test_init(ROOT_PATH)
 
-def collect_suite():
-    return plugin_utils.collect_test_suite_from_dir(ROOT_PATH)
-
-def runtests():
-    unittest.TextTestRunner(verbosity=2).run(collect_suite())
-
-if __name__ == '__main__':
-    runtests()
--- a/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/generate_repo.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/generate_repo.py	Tue Aug 10 14:29:28 2010 +0300
@@ -20,7 +20,6 @@
 """
 
 import os, unittest
-import __init__
 
 from testautomation.utils import hex_to_bindata
 
--- a/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/runtests.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/runtests.py	Tue Aug 10 14:29:28 2010 +0300
@@ -14,6 +14,6 @@
 # Description: 
 #
 
-import __init__
-
-__init__.runtests()
+if __name__ == '__main__':
+    import nose
+    nose.core.run(argv=['collector','--include=unittest', '--verbosity=3'])
--- a/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/unittest_hcr_header.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/unittest_hcr_header.py	Tue Aug 10 14:29:28 2010 +0300
@@ -17,7 +17,6 @@
 import unittest
 import os, shutil
 import sys
-import __init__
 
 from testautomation.utils import hex_to_bindata
 
--- a/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/unittest_hcrml_impl.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/unittest_hcrml_impl.py	Tue Aug 10 14:29:28 2010 +0300
@@ -15,16 +15,16 @@
 #
 
 import os, unittest
-import __init__
+
 from cone.public import plugin
-from hcrplugin.hcrml_parser import HcrmlReader
 
 def impl_from_resource(resource_ref, configuration):
     """
     Read a HCRML implementation from the given resource in a configuration.
     """
-    doc_root = plugin.ReaderBase._read_xml_doc_from_resource(resource_ref, configuration)
-    return HcrmlReader.read_impl(resource_ref, configuration, doc_root)
+    impls = plugin.ImplFactory.get_impls_from_file(resource_ref, configuration)
+    assert len(impls) == 1
+    return impls[0]
 
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
 
--- a/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/unittest_hcrml_reader.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/unittest_hcrml_reader.py	Tue Aug 10 14:29:28 2010 +0300
@@ -15,22 +15,10 @@
 #
 
 import unittest
-import os, shutil
-import sys
-import __init__
-import re
-import logging
-import xml.parsers.expat
-import codecs
+import os
+
 from hcrplugin.hcr_exceptions import *
-from hcrplugin.hcrrepository import HcrRecord, HcrRepository
-from hcrplugin.hcrml_parser import *
-
-
-from testautomation.utils import hex_to_bindata
-
-
-from cone.public import api, exceptions
+from hcrplugin.hcrml_parser import HcrmlReader
 
 try:
     from cElementTree import ElementTree
@@ -43,7 +31,6 @@
         except ImportError:
             from xml.etree import ElementTree
 
-from cone.public import exceptions,plugin,utils,api
 
 
 
--- a/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/unittest_hcrml_writer.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/unittest_hcrml_writer.py	Tue Aug 10 14:29:28 2010 +0300
@@ -14,12 +14,8 @@
 # Description:
 #
 
-import os, unittest
-import __init__
+import os
 
-from hcrplugin.hcrrepository import HcrRepository, HcrRecord
-from hcrplugin.hcr_writer import HcrWriter
-from hcrplugin import hcr_exceptions
 from cone.public import api, plugin
 from testautomation.base_testcase import BaseTestCase
 
@@ -37,11 +33,11 @@
         
         prj = api.Project(api.Storage.open(project_dir))
         config = prj.get_configuration('root.confml')
+        context = plugin.GenerationContext(configuration=config, output=output_dir)
         impls = plugin.ImplFactory.get_impls_from_file(hcrml_file, config)
         self.assertEquals(len(impls), 1)
         impl = impls[0]
-        impl.set_output_root(output_dir)
-        impl.generate()
+        impl.generate(context)
         
         if expected_dir != None:
             self.assert_dir_contents_equal(expected_dir, output_dir, ['.svn'])
--- a/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/unittest_hcrrepository.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/unittest_hcrrepository.py	Tue Aug 10 14:29:28 2010 +0300
@@ -15,13 +15,9 @@
 #
 
 import unittest
-import os, shutil
-import sys
-
-import __init__
+import os
 
 from hcrplugin.hcrrepository import HcrRepository, HcrRecord
-from cone.public import api
 
 
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
--- a/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/unittest_read_write_record.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/unittest_read_write_record.py	Tue Aug 10 14:29:28 2010 +0300
@@ -42,7 +42,6 @@
 import unittest
 import os, shutil
 import sys
-import __init__
 
 from testautomation.utils import hex_to_bindata
 
--- a/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/unittest_read_write_repository.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/unittest_read_write_repository.py	Tue Aug 10 14:29:28 2010 +0300
@@ -42,7 +42,6 @@
 import unittest
 import os, shutil, random
 import sys
-import __init__
 
 ROOT_PATH = os.path.abspath(os.path.dirname(__file__))
 
--- a/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/unittest_reader.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/unittest_reader.py	Tue Aug 10 14:29:28 2010 +0300
@@ -15,7 +15,6 @@
 #
 
 import os, unittest
-import __init__
 
 from testautomation.utils import hex_to_bindata
 
--- a/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/unittest_writer.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/tests/unittest_writer.py	Tue Aug 10 14:29:28 2010 +0300
@@ -15,7 +15,6 @@
 #
 
 import os, unittest
-import __init__
 
 from hcrplugin.hcrrepository import HcrRepository, HcrRecord
 from hcrplugin.hcr_writer import HcrWriter
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeHCRPlugin/hcrplugin/xsd/hcrml.xsd	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+    targetNamespace="http://www.symbianfoundation.org/xml/hcrml/1"
+    xmlns:hcr="http://www.symbianfoundation.org/xml/hcrml/1"
+    elementFormDefault="qualified">
+ 
+    <xs:simpleType name="uidType">
+        <xs:union>
+            <xs:simpleType>
+                <xs:restriction base="xs:nonNegativeInteger"/>
+            </xs:simpleType>
+            <xs:simpleType>
+                <xs:restriction base="xs:string">
+                    <xs:pattern value="0x[0-9a-fA-F]{1,8}"/>
+                </xs:restriction>
+            </xs:simpleType>
+        </xs:union>
+    </xs:simpleType>
+    
+    <xs:simpleType name="flagValueType">
+        <xs:restriction base="xs:string">
+            <xs:pattern value="[0-1]{1}"/>
+        </xs:restriction>
+    </xs:simpleType>
+    
+    <xs:simpleType name="settingTypeType">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="int32"/>
+            <xs:enumeration value="int16"/>
+            <xs:enumeration value="int8"/>
+            <xs:enumeration value="bool"/>
+            <xs:enumeration value="uint32"/>
+            <xs:enumeration value="uint16"/>
+            <xs:enumeration value="uint8"/>
+            <xs:enumeration value="linaddr"/>
+            <xs:enumeration value="bindata"/>
+            <xs:enumeration value="text8"/>
+            <xs:enumeration value="arrayint32"/>
+            <xs:enumeration value="arrayuint32"/>
+            <xs:enumeration value="int64"/>
+            <xs:enumeration value="uint64"/>
+        </xs:restriction>
+    </xs:simpleType>
+    
+    <xs:simpleType name="outputTypeType">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="hcr"/>
+            <xs:enumeration value="header"/>
+        </xs:restriction>
+    </xs:simpleType>
+ 
+    <xs:complexType name="settingFlagsType">
+        <xs:attribute name="Uninitialised"  type="hcr:flagValueType"/>
+        <xs:attribute name="Modifiable"     type="hcr:flagValueType"/>
+        <xs:attribute name="Persistent"     type="hcr:flagValueType"/>
+    </xs:complexType>
+ 
+    <xs:complexType name="settingType">
+        <xs:sequence>
+            <xs:element name="flags" type="hcr:settingFlagsType" minOccurs="0" maxOccurs="1"/>
+        </xs:sequence>
+        <xs:attribute name="ref"        type="xs:string"            use="required"/>
+        <xs:attribute name="name"       type="xs:string"            use="required"/>
+        <xs:attribute name="type"       type="hcr:settingTypeType"  use="required"/>
+        <xs:attribute name="id"         type="hcr:uidType"          use="required"/>
+        <xs:attribute name="comment"    type="xs:string"/>
+    </xs:complexType>
+    
+    <xs:complexType name="categoryType">
+        <xs:sequence>
+            <xs:element name="setting" type="hcr:settingType" minOccurs="0" maxOccurs="unbounded"/>
+        </xs:sequence>
+        <xs:attribute name="name"   type="xs:string"    use="required"/>
+        <xs:attribute name="uid"    type="hcr:uidType"  use="required"/>
+    </xs:complexType>
+    
+    <xs:complexType name="includetype">
+        <xs:attribute name="ref" type="xs:string" use="required"/>
+    </xs:complexType>
+    
+    <xs:complexType name="outputType">
+        <xs:choice>
+            <xs:element name="category" type="hcr:categoryType" minOccurs="0" maxOccurs="unbounded"/>
+            <xs:element name="include" type="hcr:includetype" minOccurs="1" maxOccurs="unbounded"/>
+        </xs:choice>
+        <xs:attribute name="file" type="xs:string" use="required"/>
+        <xs:attribute name="type" type="hcr:outputTypeType" use="required"/>
+        <xs:attribute name="version" type="xs:nonNegativeInteger"/>
+        <xs:attribute name="readOnly" type="hcr:flagValueType"/>
+    </xs:complexType>
+    
+    <xs:complexType name="hcrRootType">
+        <xs:choice>
+            <xs:element name="output" type="hcr:outputType" minOccurs="1" maxOccurs="1"/>
+            <xs:element name="category" type="hcr:categoryType" minOccurs="0" maxOccurs="unbounded"/>
+        </xs:choice>
+    </xs:complexType>
+    
+    <xs:element name="hcr" type="hcr:hcrRootType"/>
+
+</xs:schema>
--- a/configurationengine/source/plugins/symbian/ConeHCRPlugin/setup.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeHCRPlugin/setup.py	Tue Aug 10 14:29:28 2010 +0300
@@ -22,6 +22,7 @@
     name = "conehcrplugin",
     version = __version__,
     packages = find_packages(exclude=["*.tests"]),
+    package_data = {'hcrplugin': ['xsd/*.xsd']},
     author = "",
     author_email = "",
     description = "Configuration Engine Hardware configuration repository generation",
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeImagePlugin/__init__.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,16 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
--- a/configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/__init__.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/__init__.py	Tue Aug 10 14:29:28 2010 +0300
@@ -21,9 +21,9 @@
 import sys,os
 
 try:
-  pkg_resources.require("Cone")
+    pkg_resources.require("Cone")
 except pkg_resources.DistributionNotFound:
-  ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
-  sys.path.append(ROOT_PATH)
-  sys.path.append(os.path.join(ROOT_PATH,'..'))
-  sys.path.append(os.path.join(ROOT_PATH,'../..'))
+    ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+    sys.path.append(ROOT_PATH)
+    sys.path.append(os.path.join(ROOT_PATH,'..'))
+    sys.path.append(os.path.join(ROOT_PATH,'../..'))
--- a/configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/generators.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/generators.py	Tue Aug 10 14:29:28 2010 +0300
@@ -20,13 +20,12 @@
 
 import re
 import os
-import sys
 import logging
 import subprocess
 import shutil
 
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
-from cone.public import utils, exceptions
+from cone.public import utils
 
 class InvalidInputFileException(RuntimeError):
     """
@@ -60,18 +59,18 @@
         Get the confml ref value from configuration if the outputpath is actually a ref
         """
         if self._outputpath and ConfmlRefs.is_confml_ref(self._outputpath):
-             oref = ConfmlRefs.get_confml_ref(self._outputpath)
-             opath = self.configuration.get_default_view().get_feature(oref).get_value()
-             if opath == None: 
-                 logging.getLogger('cone.imageml').warning('Output path not set.')
-                 return self._outputpath 
-                 #raise exceptions.NotBound("Output path reference has no value %s" % oref)
-             (drive,opath) = os.path.splitdrive(opath)
-             opath = utils.resourceref.norm(opath)
-             opath = utils.resourceref.remove_begin_slash(opath)
-             return opath
+            oref = ConfmlRefs.get_confml_ref(self._outputpath)
+            opath = self.configuration.get_default_view().get_feature(oref).get_value()
+            if opath == None: 
+                logging.getLogger('cone.imageml').warning('Output path not set.')
+                return self._outputpath 
+                #raise exceptions.NotBound("Output path reference has no value %s" % oref)
+            (drive,opath) = os.path.splitdrive(opath)
+            opath = utils.resourceref.norm(opath)
+            opath = utils.resourceref.remove_begin_slash(opath)
+            return opath
         else:
-             return self._outputpath
+            return self._outputpath
 
     def set_outputpath(self, value): 
         self._outputpath = value
@@ -138,6 +137,8 @@
     def __init__(self,generator):
         self._generator = generator
         self._workdir = 'conversion_workdir'
+        self._extraparams = ""
+        
 
     def execute(self):
         """ Execute this command """
@@ -203,6 +204,14 @@
     @property
     def workdir(self):
         return self._workdir
+
+    @property
+    def extraparams(self):
+        if self._generator.extraparams and self._generator.configuration:
+            dview = self._generator.configuration.get_default_view()
+            return utils.expand_refs_by_default_view(self._generator.extraparams, dview)
+        else:
+            return self._generator.extraparams or ''
     
     def _get_filtered_input_files(self):
         """
@@ -253,8 +262,10 @@
         if len(input_files) == 0: return 0
         self.create_workdir(input_files)
         
-        if not os.path.exists(os.path.dirname(self.generator.path)):
-            os.makedirs(os.path.dirname(self.generator.path))
+        opath = self.generator.path
+        odir = os.path.dirname(opath)
+        if odir and not os.path.exists(odir):
+            os.makedirs(odir)
         
         command = self.get_command(input_files)
         p = subprocess.Popen(command,
@@ -273,15 +284,20 @@
         else:
             logging.getLogger('cone.bmconv').info("Command returned with returncode %s: %s" % (p.returncode, ' '.join(command)))
         if p.returncode == 0:
-        	self.clean_workdir()
+            self.clean_workdir()
         return p.returncode 
 
     def get_command(self, input_files):
         command = [self.tool]
+        
+        """ Add extraparams """
+        if hasattr(self._generator,'extraparams'):
+            command.append(self.extraparams)
+        
         """ Add palette file """
         if hasattr(self._generator,'palette'):
             command.append('/p%s' % os.path.abspath(self.generator.palette))
-
+        
         """ Add output file """
         """ Add output file as compressed if needed """
         if self.rom:
@@ -364,7 +380,7 @@
         else:
             logging.getLogger('cone.mifconv').info("Command returned with returncode %s: %s" % (p.returncode, ' '.join(command)))
         if p.returncode == 0:
-	        self.clean_workdir()
+            self.clean_workdir()
         return p.returncode 
 
     def get_command(self, input_files):
@@ -373,6 +389,10 @@
         """ Add output file """
         command.append(os.path.normpath(self.generator.path))
         
+        """ Add extraparams """
+        if hasattr(self._generator,'extraparams'):
+            command.append(self.extraparams)
+        
         """ Add temp_path """
         command.append("/t%s" % self.temppath)
         
--- a/configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/imageml.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/imageml.py	Tue Aug 10 14:29:28 2010 +0300
@@ -17,13 +17,9 @@
 A plugin implementation for image selection from ConfigurationLayers.
 '''
 
-
-import re
 import os
-import sys
 import logging
-import shutil
-import xml.parsers.expat
+import pkg_resources
 
 try:
     from cElementTree import ElementTree
@@ -36,7 +32,7 @@
         except ImportError:
             from xml.etree import ElementTree
             
-import __init__
+
 
 from cone.public import exceptions,plugin,utils,api
 from imageplugin.generators import OutputGenerator,InputFile,InputDir,InvalidInputFileException
@@ -89,9 +85,11 @@
         ret = True
         for generator in self.generators:
             self.logger.info(generator)
-            generator.subpath =  self.output
+            generator.subpath =  os.path.join(context.output,self.output)
             try:
-                ret = generator.generate() and ret
+                ret = generator.generate(context) and ret
+                outfile = generator.get_outputpath()
+                context.add_file(outfile, implementation=self)
             except InvalidInputFileException, e:
                 self.logger.error(e)
         return ret
@@ -117,6 +115,8 @@
     Parses a single imageml implml file
     """ 
     NAMESPACE = 'http://www.s60.com/xml/imageml/1'
+    NAMESPACE_ID = 'imageml'
+    ROOT_ELEMENT_NAME = 'imageml'
     FILE_EXTENSIONS = ['imageml']
     
     INCLUDE_ATTR = ['pattern']
@@ -142,7 +142,11 @@
             generator.configuration = configuration
         
         return impl
-
+    
+    @classmethod
+    def get_schema_data(cls):
+        return pkg_resources.resource_string('imageplugin', 'xsd/imageml.xsd')
+    
     def fromstring(self, xml_as_string):
         etree = ElementTree.fromstring(xml_as_string)
         self.desc = self.parse_desc(etree)
--- a/configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/__init__.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/__init__.py	Tue Aug 10 14:29:28 2010 +0300
@@ -13,24 +13,12 @@
 #
 # Description: 
 #
+
 import sys, os, unittest
 
 # Path to the directory where this file is located
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
 
-# Import common plug-in initialization
-PLUGINS_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../../../..'))
-assert os.path.split(PLUGINS_ROOT)[1] == 'plugins'
-if PLUGINS_ROOT not in sys.path: sys.path.append(PLUGINS_ROOT)
-import plugin_utils
-
+from testautomation import plugin_utils
 plugin_utils.plugin_test_init(ROOT_PATH)
 
-def collect_suite():
-    return plugin_utils.collect_test_suite_from_dir(ROOT_PATH)
-
-def runtests():
-    unittest.TextTestRunner(verbosity=2).run(collect_suite())
-
-if __name__ == '__main__':
-    runtests()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/imageproject/variant/implml/startupmif_animation_with_version.imageml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,16 @@
+<imageml xmlns="http://www.s60.com/xml/imageml/1">
+    <output file="startup_mif.mif" tool="../bin/mifconv" extraparams="/V3">
+        <input dir="svg_files">
+            <include pattern="svg$"/>
+        </input>
+    </output>
+    <output file="startup_mif.mif" tool="../bin/mifconv" extraparams="${StartupSettings.PluginTimeout}">
+        <input dir="svg_files">
+            <include pattern="svg$"/>
+        </input>
+    </output>
+    <output file="optional1_mbm.mbm" palette='../bin/ThirdPartyBitmap.pal' tool='../bin/bmconv' extraparams="${StartupSettings.PluginTimeout}">
+        <input file="${OptionalTest.EmptyString}" depth="c24"/>
+        <input file="${OptionalTest.EmptyString}" depth="1" optional="true"/>
+    </output>
+</imageml>
\ No newline at end of file
--- a/configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/runtests.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/runtests.py	Tue Aug 10 14:29:28 2010 +0300
@@ -14,6 +14,6 @@
 # Description: 
 #
 
-import __init__
-
-__init__.runtests()
+if __name__ == '__main__':
+    import nose
+    nose.core.run(argv=['collector','--include=unittest', '--verbosity=3'])
--- a/configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/unittest_generators.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/unittest_generators.py	Tue Aug 10 14:29:28 2010 +0300
@@ -15,12 +15,10 @@
 #
 
 import unittest
-import os, shutil
-import sys
-import __init__
+import sys, os
 
-from imageplugin import imageml,generators
-from cone.public import api, exceptions, plugin
+from imageplugin import generators
+from cone.public import api, exceptions, plugin, utils
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
 
 def impl_from_resource(resource_ref, configuration):
@@ -121,6 +119,42 @@
         self.assertEquals(len(cmd), 5)
         self.assertEquals(cmd[3], '/c16')
         self.assertEquals(cmd[4], r'conversion_workdir\icon.svg')
+
+    def test_create_generator_with_extraparams(self):
+        prj = api.Project(api.Storage.open(os.path.join(ROOT_PATH,"imageproject")))
+        config = prj.get_configuration('product.confml')
+        dview = config.get_default_view()
+        impl = impl_from_resource('variant/implml/startupmif_animation_with_version.imageml', config)
+        
+        # 1st impl
+        self.assertEquals(impl.generators[0].extraparams, '/V3')
+        
+        # Assert the the extraparams is actually used in the command
+        command_obj = impl.generators[0].get_command()
+        cmd = command_obj.get_command(command_obj._get_filtered_input_files())
+        self.assertEquals(len(cmd), 6)
+        self.assertEquals(cmd[2], r'/V3')
+        
+        # 2nd impl
+        self.assertEquals(impl.generators[1].extraparams, '${StartupSettings.PluginTimeout}')
+        self.assertEquals(utils.expand_refs_by_default_view(impl.generators[1].extraparams, dview), '30000')
+        
+        # Assert the the extraparams is actually used in the command
+        command_obj = impl.generators[1].get_command()
+        cmd = command_obj.get_command(command_obj._get_filtered_input_files())
+        self.assertEquals(len(cmd), 6)
+        self.assertEquals(cmd[2], r'30000')
+        
+        # 3rd impl
+        self.assertEquals(impl.generators[2].extraparams, '${StartupSettings.PluginTimeout}')
+        self.assertEquals(utils.expand_refs_by_default_view(impl.generators[1].extraparams, dview), '30000')
+        
+        # Assert the the extraparams is actually used in the command
+        command_obj = impl.generators[2].get_command()
+        cmd = command_obj.get_command(command_obj._get_filtered_input_files())
+        self.assertEquals(len(cmd), 4)
+        self.assertEquals(cmd[1], r'30000')
+        
     
     def test_create_generator_with_invalid_output(self):
         prj = api.Project(api.Storage.open(os.path.join(ROOT_PATH,"imageproject")))
@@ -139,5 +173,12 @@
         except exceptions.NotFound:
             pass
 
+# Only run these tests on Windows
+if sys.platform != 'win32':
+    del TestGenerator
+    del TestInputFile
+    del TestInputDir
+    del TestGeneratorFromProject
+
 if __name__ == '__main__':
     unittest.main()
--- a/configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/unittest_imageml_parseimpl.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/unittest_imageml_parseimpl.py	Tue Aug 10 14:29:28 2010 +0300
@@ -15,9 +15,8 @@
 #
 
 import unittest
-import os, shutil
 import sys
-import __init__
+
 try:
     from cElementTree import ElementTree
 except ImportError:
@@ -28,14 +27,14 @@
             from xml.etree import cElementTree as ElementTree
         except ImportError:
             from xml.etree import ElementTree
-		
+
 from imageplugin import imageml
 
 
 imageml_string = \
 '''<?xml version="1.0" encoding="UTF-8"?>
 <imageml xmlns="http://www.s60.com/xml/imageml/1">
-    <output file="startup.mbm">
+    <output file="startup.mbm" extraparams="/V2">
     	<input dir="UI/Start-up Animation">
     		<include pattern="bmb$"/>
             <exclude pattern=".svn"/>
@@ -137,6 +136,7 @@
         reader = imageml.ImageImplReader()
         outputs = reader.parse_outputs(etree)
         self.assertEquals(outputs[0].outputpath,'startup.mbm')
+        self.assertEquals(outputs[0].extraparams, '/V2')
         self.assertEquals(outputs[0].inputs[0].path,'UI/Start-up Animation')
         self.assertEquals(outputs[0].inputs[0].type,'dir')
         self.assertEquals(outputs[0].inputs[0].include,['bmb$'])
@@ -169,6 +169,9 @@
         self.assertEquals(reader.outputgenerators[0].inputs[0].type,'dir')
         self.assertEquals(reader.outputgenerators[0].inputs[0].include,['${features.inputfilter}'])
 
+# Only run these tests on Windows
+if sys.platform != 'win32':
+    del TestImagemlParseimpl
 
 if __name__ == '__main__':
     unittest.main()
--- a/configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/unittest_imageml_plugin.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/tests/unittest_imageml_plugin.py	Tue Aug 10 14:29:28 2010 +0300
@@ -15,15 +15,9 @@
 #
 
 import unittest
-import os, shutil, re
-import sys
-import logging
-import shutil
-import __init__
-		
-from cone.public import exceptions,plugin,api,container
-from cone.storage import filestorage
-from imageplugin import imageml
+import sys, os, re
+
+from cone.public import plugin,api
 from testautomation.base_testcase import BaseTestCase
 
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
@@ -39,10 +33,12 @@
             
             prj = api.Project(api.Storage.open(os.path.join(ROOT_PATH,"imageproject")))
             config = prj.get_configuration('product.confml')
-            implcontainer = plugin.get_impl_set(config, 'imageml$')
-            self.assertEquals(len(implcontainer), 4)
-            implcontainer.output = output
-            implcontainer.generate()
+            context = plugin.GenerationContext(configuration=config, output=output)
+            context.filtering_disabled = True
+            
+            impl_set = plugin.get_impl_set(config, 'imageml$')
+            self.assertEquals(len(impl_set), 5)
+            impl_set.generate(context)
             
             def check_gen(p):
                 self.assert_exists_and_contains_something(os.path.join(output, p))
@@ -50,33 +46,33 @@
                 self.assertFalse(os.path.exists(os.path.join(output, p)), "'%s' exists when it should not!" % p)
             
             try:
-	            check_gen('startup.mbm')
-	            check_gen('startup_mif.mif')
-	            
-	            check_not_gen('optional1_mbm.mbm')
-	            check_gen('optional2_mbm.mbm')
-	            check_not_gen('optional3_mbm.mbm')
-	            check_not_gen('optional4_mbm.mbm')
-	            
-	            check_not_gen('optional1_mif.mif')
-	            check_gen('optional2_mif.mif')
-	            check_not_gen('optional3_mif.mif')
-	            check_not_gen('optional4_mif.mif')
-	            
-	            check_gen('resource/apps/startup.mif')
-	            
-	            check_gen('depth_from_ref_test_mbm.mbm')
-	            check_gen('depth_from_ref_test_mif.mif')
-    	    except AssertionError:
-	            if ' ' in ROOT_PATH:
-	                self.fail("Known bug (#177)")
-	            else:
-	                raise
+                check_gen('startup.mbm')
+                check_gen('startup_mif.mif')
+                
+                check_not_gen('optional1_mbm.mbm')
+                check_gen('optional2_mbm.mbm')
+                check_not_gen('optional3_mbm.mbm')
+                check_not_gen('optional4_mbm.mbm')
+                
+                check_not_gen('optional1_mif.mif')
+                check_gen('optional2_mif.mif')
+                check_not_gen('optional3_mif.mif')
+                check_not_gen('optional4_mif.mif')
+                
+                check_gen('resource/apps/startup.mif')
+                
+                check_gen('depth_from_ref_test_mbm.mbm')
+                check_gen('depth_from_ref_test_mif.mif')
+            except AssertionError, e:
+                if ' ' in ROOT_PATH:
+                    self.fail("Known bug (#177): %s" % e)
+                else:
+                    raise
         finally:
             os.chdir(orig_workdir)
     
     def _get_impl(self, filename):
-    	prj = api.Project(api.Storage.open(os.path.join(ROOT_PATH, "imageproject")))
+        prj = api.Project(api.Storage.open(os.path.join(ROOT_PATH, "imageproject")))
         config = prj.get_configuration('product.confml')
         implcontainer = plugin.get_impl_set(config, re.escape(filename) + '$')
         self.assertEquals(len(implcontainer), 1)
@@ -84,20 +80,24 @@
         
     
     def test_get_refs(self):
-    	impl = self._get_impl('startupmif_animation.imageml')
-    	self.assertEquals(impl.get_refs(), None)
-    	self.assertEquals(impl.has_ref('Foo.Bar'), None)
-    	
-    	impl = self._get_impl('optional_test.imageml')
-    	self.assertEquals(impl.get_refs(), ['OptionalTest.EmptyString',
-										    'OptionalTest.EmptyString2'])
-    	self.assertEquals(impl.has_ref('OptionalTest.EmptyString'), True)
-    	self.assertEquals(impl.has_ref('Foo.Foo'), False)
-    	
-    	impl = self._get_impl('startup_animation.imageml')
-    	self.assertEquals(impl.get_refs(), ['CVC_StartupAnimationSequence.CVC_StartupFrameLocation.localPath'])
-    	self.assertEquals(impl.has_ref('CVC_StartupAnimationSequence.CVC_StartupFrameLocation.localPath'), True)
-    	self.assertEquals(impl.has_ref('Foo.Foo'), False)
+        impl = self._get_impl('startupmif_animation.imageml')
+        self.assertEquals(impl.get_refs(), None)
+        self.assertEquals(impl.has_ref('Foo.Bar'), None)
+        
+        impl = self._get_impl('optional_test.imageml')
+        self.assertEquals(impl.get_refs(), ['OptionalTest.EmptyString',
+                                            'OptionalTest.EmptyString2'])
+        self.assertEquals(impl.has_ref('OptionalTest.EmptyString'), True)
+        self.assertEquals(impl.has_ref('Foo.Foo'), False)
+        
+        impl = self._get_impl('startup_animation.imageml')
+        self.assertEquals(impl.get_refs(), ['CVC_StartupAnimationSequence.CVC_StartupFrameLocation.localPath'])
+        self.assertEquals(impl.has_ref('CVC_StartupAnimationSequence.CVC_StartupFrameLocation.localPath'), True)
+        self.assertEquals(impl.has_ref('Foo.Foo'), False)
+
+# Only run these tests on Windows
+if sys.platform != 'win32':
+    del TestGeneratorFromProject
 
 if __name__ == '__main__':
     unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeImagePlugin/imageplugin/xsd/imageml.xsd	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema 
+	xmlns:xs="http://www.w3.org/2001/XMLSchema" 
+	targetNamespace="http://www.s60.com/xml/imageml/1" 
+	xmlns:image="http://www.s60.com/xml/imageml/1" 
+	elementFormDefault="qualified">
+
+	
+    <xs:complexType name="includeType">
+        <xs:attribute name="pattern"        type="xs:string"            use="required"/>
+    </xs:complexType>
+
+	 <xs:complexType name="excludeType">
+        <xs:attribute name="pattern"        type="xs:string"            use="required"/>
+    </xs:complexType>
+	
+    <xs:complexType name="inputType">
+        <xs:sequence>
+            <xs:element name="include" type="image:includeType" minOccurs="0" maxOccurs="unbounded"/>
+			<xs:element name="exclude" type="image:excludeType" minOccurs="0" maxOccurs="unbounded"/>
+        </xs:sequence>
+
+		<xs:attribute name="dir" type="xs:string"/>
+        <xs:attribute name="file" type="xs:string"/>
+        <xs:attribute name="depth" type="xs:string"/>
+        <xs:attribute name="optional" type="xs:string"/>
+    </xs:complexType>
+	
+	
+	
+    <xs:complexType name="outputType">
+        <xs:sequence>
+            <xs:element name="input" type="image:inputType" minOccurs="0" maxOccurs="unbounded"/>
+        </xs:sequence>
+        <xs:attribute name="file"        type="xs:string"            use="required"/>
+        <xs:attribute name="tool"       type="xs:string"/>
+		<xs:attribute name="tooldir"       type="xs:string"/>
+		<xs:attribute name="compress"       type="xs:string"/>
+		<xs:attribute name="palette"       type="xs:string"/>
+    </xs:complexType>
+
+		
+    <xs:complexType name="imagemlRootType">
+        <xs:sequence>
+            <xs:element name="output" type="image:outputType" minOccurs="0" maxOccurs="unbounded"/>
+        </xs:sequence>
+    </xs:complexType>
+    
+    <xs:element name="imageml" type="image:imagemlRootType"/>
+</xs:schema>
\ No newline at end of file
--- a/configurationengine/source/plugins/symbian/ConeImagePlugin/setup.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeImagePlugin/setup.py	Tue Aug 10 14:29:28 2010 +0300
@@ -22,6 +22,7 @@
     name = "coneimageplugin",
     version = __version__,
     packages = find_packages(exclude=["*.tests"]),
+    package_data = {'imageplugin': ['xsd/*.xsd']},
     test_suite = "imageplugin.tests.collect_suite",
 
     # metadata for upload to PyPI
--- a/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/convertproject.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/convertproject.py	Tue Aug 10 14:29:28 2010 +0300
@@ -24,6 +24,8 @@
 import xml.parsers.expat
 import shutil
 import fnmatch
+import pkg_resources
+import types
 
 try:
     from cElementTree import ElementTree
@@ -71,11 +73,11 @@
         """
         
         #Generating content
-        fullOutputPath = self.output
+        fullOutputPath = os.path.join(context.output, self.output)
         if self.project_data.has_key("path"): 
             targetPath = utils.resourceref.norm(self.project_data["path"])
             if targetPath and targetPath != "":
-                fullOutputPath = os.path.join(fullOutputPath, targetPath)             
+                fullOutputPath = os.path.join(context.output, fullOutputPath, targetPath)             
         
         fs = filestorage.FileStorage(fullOutputPath, "w")
         newProject = api.Project(fs)        
@@ -116,13 +118,14 @@
     Object presenting layer in convertprojectml file.
     """
     
-    def __init__(self, path):
+    def __init__(self, path, configuration):
         if path != None:
             self.path = path
         else:
             self.path = ""
         self.folders = []
-        self.files = []        
+        self.files = []
+        self.source_configuration = configuration        
 
     def __str__(self):
         retStr = ""
@@ -159,8 +162,24 @@
         self.files.append(file)
 
     def getProjectPath(self):
-        return self.path
+        return self.path    
 
+    def solve_ref(self, inputdata):
+        """
+        Internal function to solve whether input is ref or just normal input string. 
+        For refs actual ConfML value is resolved and returned. Non-refs are returned 
+        as such.
+        """                        
+        dview = self.source_configuration.get_default_view()
+        if inputdata and isinstance(inputdata, types.StringType):            
+            return utils.expand_refs_by_default_view(inputdata, dview)
+        elif inputdata and isinstance(inputdata, types.DictType):
+            retDict = {}
+            for key in inputdata:
+                retDict[self.solve_ref(key)] = self.solve_ref(inputdata[key])            
+            return retDict
+        else:
+            return inputdata
                 
 class ConvertProjectFolder(object):
     """
@@ -198,7 +217,11 @@
 
     def getProjectPath(self):
         return os.path.join(self.parent.getProjectPath(), self.path)
-    
+
+    def solve_ref(self, inputdata):
+        return self.parent.solve_ref(inputdata)
+
+            
 class ConvertProjectFile(object):
     """
     Object presenting file in convertprojectml file.
@@ -209,7 +232,7 @@
             self.path = path
         else:
             self.path = ""
-        if type != None:
+        if type != None and type != "none":
             self.type = type
         else:
             self.type = ""        
@@ -218,6 +241,7 @@
         self.parent = parent
         self.meta = []
         self.desc = ""
+        self.configuration_name = ""
         
     def __str__(self):
         retStr = ""
@@ -232,18 +256,23 @@
         for filter in self.filters:            
             filter.generate(project, old_structure_root, self.type)                        
 
-        if self.type == "configuration_root":
-            #Adding metadata                
-            config = project.get_configuration(utils.resourceref.norm(self.path))
+        if self.type:
+            config = project.get_configuration(utils.resourceref.norm(self.getProjectPath()))
             if self.meta:                
                 if not config.meta:
                     config.meta = []
                 for meta in self.meta:
-                    config.meta.add(meta[0], meta[1], meta[2], meta[3])                        
+                    config.meta.set_property_by_tag(self.solve_ref(meta[0]), \
+                                                    self.solve_ref(meta[1]), \
+                                                    self.solve_ref(meta[2]), \
+                                                    self.solve_ref(meta[3]))                   
             if self.desc:
                 config.desc = self.desc
                 
-            config.save()                    
+            if self.configuration_name:
+                config.set_name(self.configuration_name)
+            config.save()
+                    
         return
 
     def addFilter(self, filter):
@@ -254,9 +283,18 @@
 
     def addDescription(self, desc):
         self.desc = desc
+    
+    def addConfigurationName(self, configuration_name):
+        self.configuration_name = configuration_name
 
     def getProjectPath(self):
-        return os.path.join(self.parent.getProjectPath(), self.path)
+        if self.type == "configuration_root":
+            return self.path
+        else:
+            return os.path.join(self.parent.getProjectPath(), self.path)
+
+    def solve_ref(self, inputdata):
+        return self.parent.solve_ref(inputdata)
 
 class ConvertProjectFilter(object):
     """
@@ -274,7 +312,7 @@
         if recursive:
             self.recursive = recursive
         else:
-             self.recursive = "false"
+            self.recursive = "false"
 
     def __str__(self):
         retStr = ""
@@ -367,7 +405,9 @@
             retPath = os.path.join(project.get_storage().get_path(), self.getProjectPath())            
             startFound = 0
             
-            for item in os.path.normpath(filepath).split("\\"):
+            parts = filter(lambda p: p != '',
+                           os.path.normpath(filepath).replace('\\', '/').split('/'))
+            for item in parts:
                 if self.data.find(item) != -1:
                     startFound = 1
                 if startFound and self.data.find(item) == -1:
@@ -402,8 +442,11 @@
             filesToProcess = self.getFilesByWildcard(fullSearchPath, wildCardPart, project)
         
         #Creating rootfile.        
-        rootFilePath = os.path.join(self.getProjectPath(), self.parent.path)        
-        config = project.create_configuration(utils.resourceref.norm(rootFilePath))
+        rootFilePath = os.path.join(self.getProjectPath(), self.parent.path)
+        if project.is_configuration(utils.resourceref.norm(rootFilePath)):
+            config = project.get_configuration(utils.resourceref.norm(rootFilePath))
+        else:
+            config = project.create_configuration(utils.resourceref.norm(rootFilePath))
         
         #Adding defined includes.
         for f in filesToProcess:
@@ -435,7 +478,7 @@
         """        
         #Always in the root of the project
         configname = utils.resourceref.norm(self.parent.path)
-        if configname in project.list_configurations():
+        if project.is_configuration(utils.resourceref.norm(self.parent.path)):
             config = project.get_configuration(configname)
         else:
             config = project.create_configuration(utils.resourceref.norm(self.parent.path))
@@ -469,6 +512,10 @@
                     continue
                 else:
                     for f in files:
+                        if wildcard and wildcard[0] != "*":
+                            #Matches path part.
+                            wildcard = "*%s" % wildcard
+                        
                         if fnmatch.fnmatch(os.path.join(root, f), wildcard):
                             source = os.path.join(root, f)
                             targetDir = self.resolveTargetDir(project, source)                
@@ -502,7 +549,9 @@
 
         return pathPart, wildCardPart
 
-
+    def solve_ref(self, inputdata):
+        return self.parent.solve_ref(inputdata)   
+     
 #=================================================================
     
 class ConvertProjectReader(plugin.ReaderBase):
@@ -511,6 +560,8 @@
     """ 
     
     NAMESPACE = 'http://www.s60.com/xml/convertprojectml/1'
+    NAMESPACE_ID = 'convertprojectml'
+    ROOT_ELEMENT_NAME = 'convertprojectml'
     FILE_EXTENSIONS = ['convertprojectml']
     
     def __init__(self):
@@ -524,51 +575,50 @@
     @classmethod
     def read_impl(cls, resource_ref, configuration, etree):
         reader = ConvertProjectReader()
-        reader.from_etree(etree, configuration.get_storage().get_path())
+        reader.from_etree(etree, configuration, configuration.get_storage().get_path())
         
         impl = ConvertProjectImpl(resource_ref, configuration)
         impl.project_data   = reader.project_data
         impl.layers         = reader.layers
         return impl
     
-    def from_etree(self, etree, old_structure_root = ""):
-        self.project_data = self.parse_attributes(etree, "targetProject")        
-        self.layers = self.parse_layers(etree) 
-        for fe in self.parse_foreach(etree, old_structure_root):
-            self.layers.append(fe)
-        
-        #for l in self.layers:
-            #print l
-        return    
+    @classmethod
+    def get_schema_data(cls):
+        return pkg_resources.resource_string('projectconvertplugin', 'xsd/convertprojectml.xsd')
+    
+    def from_etree(self, etree, configuration, old_structure_root = ""):
+        self.configuration = configuration
+                
+        for element in etree:
+            if element.tag == "{http://www.s60.com/xml/convertprojectml/1}targetProject":
+                self.project_data = self.parse_attributes(etree, "targetProject")
+            elif element.tag == "{http://www.s60.com/xml/convertprojectml/1}layer":
+                self.layers.append(self.parse_layer(element))
+            elif element.tag == "{http://www.s60.com/xml/convertprojectml/1}foreach":
+                for fe in self.parse_foreach(element, old_structure_root):
+                    self.layers.append(fe)                
+        return
     
     def parse_foreach(self, etree, old_structure_root):
-        layersTmp = []
-        for fe in etree.findall("{%s}foreach" % self.namespaces[0]):
-            variable = fe.get("variable")
-            data = fe.get("data")
-            folders = [] 
-            for item in os.listdir(os.path.join(old_structure_root, data)):
-                if os.path.isdir(os.path.join(old_structure_root, data, item)) and item != '.svn':
-                    folders.append(item)
-            
-            for folder in folders:
-                mapping_data = {variable: folder}                                             
-                for layer in fe.findall("{%s}layer" % self.namespaces[0]):            
-                    layersTmp.append(self.parse_layer(layer, mapping_data))
+        layersTmp = []        
+        variable = etree.get("variable")
+        data = self.handleMapping(etree.get("data"), {})
+        folders = [] 
+        for item in os.listdir(os.path.join(old_structure_root, data)):
+            if os.path.isdir(os.path.join(old_structure_root, data, item)) and item != '.svn':
+                folders.append(item)
+        
+        for folder in folders:
+            mapping_data = {variable: folder}                                             
+            for layer in etree.findall("{%s}layer" % self.namespaces[0]):            
+                layersTmp.append(self.parse_layer(layer, mapping_data))
                                 
         return layersTmp
-    
-    def parse_layers(self,etree):
-        layersTmp = []
-        for layer in etree.findall("{%s}layer" % self.namespaces[0]):            
-            layersTmp.append(self.parse_layer(layer))
-            
-        return layersTmp
-    
+        
     def parse_layer(self, etree, mapping_data=None):        
         path = self.handleMapping(etree.get("path"), mapping_data)
         
-        layerObject = ConvertProjectLayer(path)        
+        layerObject = ConvertProjectLayer(path, self.configuration)        
         for folder in etree.findall("{%s}folder" % self.namespaces[0]):
             layerObject.addFolder(self.parse_folder(folder, layerObject, mapping_data))
 
@@ -589,6 +639,7 @@
     def parse_file(self, etree, parent, mapping_data=None):
         path = self.handleMapping(etree.get("path"), mapping_data)
         type = self.handleMapping(etree.get("type"), mapping_data)
+        configuration_name = self.handleMapping(etree.get("configuration_name"), mapping_data)
         
         fileObject = ConvertProjectFile(path, type, parent)        
         for filter in etree.findall("{%s}filter" % self.namespaces[0]):
@@ -618,7 +669,8 @@
             description = descElement.text                
                          
         fileObject.addMeta(metaArray)
-        fileObject.addDescription(description)                
+        fileObject.addDescription(description)
+        fileObject.addConfigurationName(configuration_name)
         return fileObject
 
     def parse_filter(self, etree, parent, mapping_data=None):
@@ -644,18 +696,24 @@
     
     def handleMapping(self, data, mapping):
         """
-        """
-        
+        """ 
         retStr = data
-        
-        if mapping != None and data != None:                        
-            for key in mapping.keys():
-                retStr = retStr.replace(key, mapping[key])
+        if not mapping: mapping = {}        
+        if data != None:
+            merged = dict(mapping.items() + self._get_env_variables().items())                                    
+            for key in merged.keys():
+                retStr = retStr.replace(key, merged[key])
+         
         return retStr
         
-        
-        
-        
+    def _get_env_variables(self):
+        if not hasattr(self, '_env_dict'):
+        #Making dictionary only once because of performance.
+            self._env_dict = {}
+            for var in os.environ:
+                self._env_dict["%%%s%%" % var] = os.environ[var]
+            
+        return self._env_dict 
         
         
 
--- a/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/__init__.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/__init__.py	Tue Aug 10 14:29:28 2010 +0300
@@ -13,24 +13,12 @@
 #
 # Description: 
 #
+
 import sys, os, unittest
 
 # Path to the directory where this file is located
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
 
-# Import common plug-in initialization
-PLUGINS_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../../../..'))
-assert os.path.split(PLUGINS_ROOT)[1] == 'plugins'
-if PLUGINS_ROOT not in sys.path: sys.path.append(PLUGINS_ROOT)
-import plugin_utils
-
+from testautomation import plugin_utils
 plugin_utils.plugin_test_init(ROOT_PATH)
 
-def collect_suite():
-    return plugin_utils.collect_test_suite_from_dir(ROOT_PATH)
-
-def runtests():
-    unittest.TextTestRunner(verbosity=2).run(collect_suite())
-
-if __name__ == '__main__':
-    runtests()
--- a/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/.metadata	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/.metadata	Tue Aug 10 14:29:28 2010 +0300
@@ -1,4 +1,2 @@
 <?xml version="1.0" encoding="ASCII"?>
-<metadata xmlns="http://www.nokia.com/xml/ns/confml-core/metadata-2.0">
-  <property name="cpf.rootFile" />
-</metadata>
\ No newline at end of file
+<metadata xmlns="http://www.nokia.com/xml/ns/confml-core/metadata-2.0" />
\ No newline at end of file
--- a/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/confml/family_x.confml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/confml/family_x.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -1,4 +1,4 @@
-<configuration name="family_x" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+<configuration name="family_x" version="1" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema">
   <data>
     <Feature1>
       <IntSetting>300</IntSetting>
--- a/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/product_x/confml/product_x.confml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/product_x/confml/product_x.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -1,9 +1,9 @@
-<configuration name="product_x" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+<configuration name="product_x" version="1" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema">
   <data>
     <Feature1>
       <IntSetting>500</IntSetting>
     <BooleanSetting>true</BooleanSetting>
-    <StringSetting>Product X</StringSetting>
+    <StringSetting>001.009</StringSetting>
     </Feature1>
   </data>
 </configuration>
\ No newline at end of file
--- a/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/product_x/language/Euro/confml/VariantData_product_x_Euro.confml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/product_x/language/Euro/confml/VariantData_product_x_Euro.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -1,4 +1,4 @@
-<configuration name="VariantData_product_x_Euro" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+<configuration name="VariantData_product_x_Euro" version="1" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema">
   <data>
     <Feature1>
       <StringSetting>testing</StringSetting>
--- a/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/product_x/language/French/confml/VariantData_product_x_French.confml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/product_x/language/French/confml/VariantData_product_x_French.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -1,4 +1,4 @@
-<configuration name="VariantData_product_x_French" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+<configuration name="VariantData_product_x_French" version="1" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema">
   <data>
     <Feature1>
       <StringSetting>fran&#231;ais</StringSetting>
--- a/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/product_x/language/German/confml/VariantData_product_x_German.confml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/product_x/language/German/confml/VariantData_product_x_German.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -1,4 +1,4 @@
-<configuration name="VariantData_product_x_German" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+<configuration name="VariantData_product_x_German" version="1" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema">
   <data>
     <Feature1>
       <StringSetting>deutsch</StringSetting>
--- a/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/product_x/language/Greek/confml/VariantData_product_x_Greek.confml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/product_x/language/Greek/confml/VariantData_product_x_Greek.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -1,4 +1,4 @@
-<configuration name="VariantData_product_x_Greek" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+<configuration name="VariantData_product_x_Greek" version="1" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema">
   <data>
     <Feature1>
       <StringSetting>&#949;&#955;&#955;&#951;&#957;&#953;&#954;&#942; &#947;&#955;&#974;&#963;&#963;&#945;</StringSetting>
--- a/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/test/implml/create_project.convertprojectml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/test/implml/create_project.convertprojectml	Tue Aug 10 14:29:28 2010 +0300
@@ -18,8 +18,9 @@
 			<filter action="add" data="confml_data/platform1/*.ibyml"/>
 		</folder>
 
-		<file type="layer_root" path="root.confml">
+		<file type="layer_root" path="root.confml"  configuration_name="PLATFORM1__LAYER_ROOT_FILE">
 			<filter action="include_file" data="confml/*.confml"/>
+			<desc>This is layer root file for platform 1</desc>
 		</file>
 		<file type="configuration_root" path="platform1_root.confml">
 			<filter action="include_layer" data="platforms/platform1/root.confml"/>
@@ -39,7 +40,19 @@
 		</file>				
 	</layer>
 	
-	<layer path="platforms/platform2">
+		
+	<layer path="platforms/platform1">
+		<file type="configuration_root" path="platform1_root.confml">
+			<meta xmlns:cv="http://www.nokia.com/xml/cpf-id/1">
+				<version>001</version>
+				<release>${Feature1.StringSetting}</release>
+				<cv:configuration-property name="sw_version" value="${Feature1.StringSetting}" />
+				<cv:configuration-property name="sos_version" value="123.456" />
+			</meta>
+		</file>
+	</layer>
+	
+	<layer path="%NCP_VERSION%/platform2">
 		<folder path="confml">
 			<filter action="add" data="confml_data/platform2/*.confml"/>
 			<filter action="remove" data="confml_data/platform2/platform2.confml"/>
@@ -58,7 +71,29 @@
 			<filter action="include_layer" data="platforms/platform2/root.confml"/>
 		</file>
 	</layer>
-	
+			
+	<layer path="platforms/platform3_feas_only">
+		<folder path="confml">
+			<filter action="add" data="confml_data/platform2/fea*.confml"/>
+		</folder>
+		<folder path="implml">
+			<filter action="add" data="confml_data/platform2/fea*.crml"/>
+			<filter action="add" data="confml_data/platform2/fea*.gcfml"/>
+			<filter action="add" data="confml_data/platform2/fea*.ibyml"/>
+		</folder>
+
+		<file type="layer_root" path="root.confml">
+			<filter action="include_file" data="confml/fea*.confml"/>
+		</file>
+		<file type="configuration_root" path="platform3_root.confml">
+			<filter action="include_layer" data="platforms/platform1/root.confml"/>
+			<filter action="include_layer" data="platforms/platform2/root.confml"/>
+			<filter action="include_layer" data="platforms/platform3/root.confml"/>
+		</file>
+	</layer>
+
+
+
 	<!-- ============ -->
 	<!-- Family layer -->
 	<!-- ============ -->
@@ -86,7 +121,6 @@
 		</file>
 	</layer>
 	
-	
 	<!-- ============= -->
 	<!-- Product layer -->
 	<!-- ============= -->
@@ -111,7 +145,7 @@
 	<!-- Product X language variant layers -->
 	<!-- ================================= -->
 
-	<foreach variable="{TEMPLATE}" data="variants/language/product_x">
+	<foreach variable="{TEMPLATE}" data="%VARIANTS%/language/product_x">
 		<layer path="family_x/product_x/language/{TEMPLATE}">
 			<folder path="confml">
 				<filter action="add" data="variants/language/product_x/{TEMPLATE}/*.confml"/>
@@ -124,7 +158,7 @@
 			<file type="layer_root" path="root.confml">
 				<filter action="include_file" data="confml/*.confml" remove_includes="true"/>
 			</file>
-			<file type="configuration_root" path="product_x_{TEMPLATE}_root.confml">
+			<file type="configuration_root" path="product_x_{TEMPLATE}_root.confml" configuration_name="{TEMPLATE}">
 				<filter action="include_layer" data="platforms/platform1/root.confml"/>
 				<filter action="include_layer" data="platforms/platform2/root.confml"/>
 				<filter action="include_layer" data="family_x/root.confml"/>
@@ -133,4 +167,11 @@
 			</file>
 		</layer>
 	</foreach>
+	
+	<layer path="family_x/product_x/language/Euro">
+		<file type="configuration_root" path="product_x_Euro_root.confml" configuration_name="Euro1_override_name">
+			<filter action="include_layer" data="family_x/product_x/customer/dummy/root.confml"/>
+		</file>	
+	</layer>
+	
 </convertprojectml>
\ No newline at end of file
--- a/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/test3/implml/create_project.convertprojectml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/family_x/test3/implml/create_project.convertprojectml	Tue Aug 10 14:29:28 2010 +0300
@@ -18,8 +18,9 @@
 			<filter action="add" data="confml_data/platform1/*.ibyml"/>
 		</folder>
 
-		<file type="layer_root" path="root.confml">
+		<file type="layer_root" path="root.confml"  configuration_name="PLATFORM1__LAYER_ROOT_FILE">
 			<filter action="include_file" data="confml/*.confml"/>
+			<desc>This is layer root file for platform 1</desc>
 		</file>
 		<file type="configuration_root" path="platform1_root.confml">
 			<filter action="include_layer" data="platforms/platform1/root.confml"/>
@@ -39,7 +40,19 @@
 		</file>				
 	</layer>
 	
-	<layer path="platforms/platform2">
+		
+	<layer path="platforms/platform1">
+		<file type="configuration_root" path="platform1_root.confml">
+			<meta xmlns:cv="http://www.nokia.com/xml/cpf-id/1">
+				<version>001</version>
+				<release>${Feature1.StringSetting}</release>
+				<cv:configuration-property name="sw_version" value="${Feature1.StringSetting}" />
+				<cv:configuration-property name="sos_version" value="123.456" />
+			</meta>
+		</file>
+	</layer>
+	
+	<layer path="%NCP_VERSION%/platform2">
 		<folder path="confml">
 			<filter action="add" data="confml_data/platform2/*.confml"/>
 			<filter action="remove" data="confml_data/platform2/platform2.confml"/>
@@ -58,7 +71,29 @@
 			<filter action="include_layer" data="platforms/platform2/root.confml"/>
 		</file>
 	</layer>
-	
+			
+	<layer path="platforms/platform3_feas_only">
+		<folder path="confml">
+			<filter action="add" data="confml_data/platform2/fea*.confml"/>
+		</folder>
+		<folder path="implml">
+			<filter action="add" data="confml_data/platform2/fea*.crml"/>
+			<filter action="add" data="confml_data/platform2/fea*.gcfml"/>
+			<filter action="add" data="confml_data/platform2/fea*.ibyml"/>
+		</folder>
+
+		<file type="layer_root" path="root.confml">
+			<filter action="include_file" data="confml/fea*.confml"/>
+		</file>
+		<file type="configuration_root" path="platform3_root.confml">
+			<filter action="include_layer" data="platforms/platform1/root.confml"/>
+			<filter action="include_layer" data="platforms/platform2/root.confml"/>
+			<filter action="include_layer" data="platforms/platform3/root.confml"/>
+		</file>
+	</layer>
+
+
+
 	<!-- ============ -->
 	<!-- Family layer -->
 	<!-- ============ -->
@@ -86,7 +121,6 @@
 		</file>
 	</layer>
 	
-	
 	<!-- ============= -->
 	<!-- Product layer -->
 	<!-- ============= -->
@@ -111,7 +145,7 @@
 	<!-- Product X language variant layers -->
 	<!-- ================================= -->
 
-	<foreach variable="{TEMPLATE}" data="variants/language/product_x">
+	<foreach variable="{TEMPLATE}" data="%VARIANTS%/language/product_x">
 		<layer path="family_x/product_x/language/{TEMPLATE}">
 			<folder path="confml">
 				<filter action="add" data="variants/language/product_x/{TEMPLATE}/*.confml"/>
@@ -124,7 +158,7 @@
 			<file type="layer_root" path="root.confml">
 				<filter action="include_file" data="confml/*.confml" remove_includes="true"/>
 			</file>
-			<file type="configuration_root" path="product_x_{TEMPLATE}_root.confml">
+			<file type="configuration_root" path="product_x_{TEMPLATE}_root.confml" configuration_name="{TEMPLATE}">
 				<filter action="include_layer" data="platforms/platform1/root.confml"/>
 				<filter action="include_layer" data="platforms/platform2/root.confml"/>
 				<filter action="include_layer" data="family_x/root.confml"/>
@@ -133,4 +167,11 @@
 			</file>
 		</layer>
 	</foreach>
+	
+	<layer path="family_x/product_x/language/Euro">
+		<file type="configuration_root" path="product_x_Euro_root.confml" configuration_name="Euro1_override_name">
+			<filter action="include_layer" data="family_x/product_x/customer/dummy/root.confml"/>
+		</file>	
+	</layer>
+	
 </convertprojectml>
\ No newline at end of file
--- a/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/platform1_root.confml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/platform1_root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -2,11 +2,13 @@
   <xi:include href="platforms/platform1/root.confml" />
 <meta xmlns:cv="http://www.nokia.com/xml/cpf-id/1">
     <cv:configuration-property name="platform_name" value="plat1" />
-  <version>Version1</version>
+  <version>001</version>
   <platform>Platform1</platform>
   <date>Date1</date>
-  <release>Release1</release>
+  <release>001.009</release>
   <editor>Editor1</editor>
+  <cv:configuration-property name="sw_version" value="001.009" />
+  <cv:configuration-property name="sos_version" value="123.456" />
   </meta>
 <desc>Description1</desc>
 </configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/platform3_root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,5 @@
+<configuration name="platform3_root_confml" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+  <xi:include href="platforms/platform1/root.confml" />
+<xi:include href="platforms/platform2/root.confml" />
+<xi:include href="platforms/platform3/root.confml" />
+</configuration>
\ No newline at end of file
--- a/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/platforms/platform1/root.confml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/platforms/platform1/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -1,4 +1,5 @@
-<configuration name="platforms__platform1__root_confml" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+<configuration name="PLATFORM1__LAYER_ROOT_FILE" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema">
   <xi:include href="confml/bitmask_test.confml" />
 <xi:include href="confml/feature1.confml" />
+<desc>This is layer root file for platform 1</desc>
 </configuration>
\ No newline at end of file
Binary file configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/platforms/platform3_feas_only/confml/feature2.confml has changed
Binary file configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/platforms/platform3_feas_only/implml/feature2_ABCD0000.crml has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/platforms/platform3_feas_only/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,3 @@
+<configuration name="platforms__platform3_feas_only__root_confml" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+  <xi:include href="confml/feature2.confml" />
+</configuration>
\ No newline at end of file
--- a/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/product_x_Euro_root.confml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/product_x_Euro_root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -1,7 +1,8 @@
-<configuration name="product_x_Euro_root_confml" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+<configuration name="Euro1_override_name" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema">
   <xi:include href="platforms/platform1/root.confml" />
 <xi:include href="platforms/platform2/root.confml" />
 <xi:include href="family_x/root.confml" />
 <xi:include href="family_x/product_x/root.confml" />
 <xi:include href="family_x/product_x/language/Euro/root.confml" />
+<xi:include href="family_x/product_x/customer/dummy/root.confml" />
 </configuration>
\ No newline at end of file
--- a/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/product_x_French_root.confml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/product_x_French_root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -1,4 +1,4 @@
-<configuration name="product_x_French_root_confml" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+<configuration name="French" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema">
   <xi:include href="platforms/platform1/root.confml" />
 <xi:include href="platforms/platform2/root.confml" />
 <xi:include href="family_x/root.confml" />
--- a/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/product_x_German_root.confml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/product_x_German_root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -1,4 +1,4 @@
-<configuration name="product_x_German_root_confml" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+<configuration name="German" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema">
   <xi:include href="platforms/platform1/root.confml" />
 <xi:include href="platforms/platform2/root.confml" />
 <xi:include href="family_x/root.confml" />
--- a/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/product_x_Greek_root.confml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/expected/new_project/product_x_Greek_root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -1,4 +1,4 @@
-<configuration name="product_x_Greek_root_confml" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+<configuration name="Greek" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema">
   <xi:include href="platforms/platform1/root.confml" />
 <xi:include href="platforms/platform2/root.confml" />
 <xi:include href="family_x/root.confml" />
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/confml_data/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="ASCII"?>
+<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2 http://www.w3.org/2001/XInclude http://www.s60.com/xml/confml/1#//include">
+  <xi:include href="platform1/feature1.confml"/>
+</confml:configuration>
\ No newline at end of file
--- a/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/convert.confml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/convert.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -1,4 +1,6 @@
 <?xml version="1.0" encoding="ASCII"?>
 <confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2 http://www.w3.org/2001/XInclude http://www.s60.com/xml/confml/1#//include">
+	<xi:include href="confml_data/root.confml"/>
+	<xi:include href="family_x/product_x/root.confml"/>
 	<xi:include href="convertpluginlayer/root.confml"/>
 </confml:configuration>
\ No newline at end of file
--- a/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/convertpluginlayer/implml/create_project.convertprojectml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/convertpluginlayer/implml/create_project.convertprojectml	Tue Aug 10 14:29:28 2010 +0300
@@ -18,8 +18,9 @@
 			<filter action="add" data="confml_data/platform1/*.ibyml"/>
 		</folder>
 
-		<file type="layer_root" path="root.confml">
+		<file type="layer_root" path="root.confml"  configuration_name="PLATFORM1__LAYER_ROOT_FILE">
 			<filter action="include_file" data="confml/*.confml"/>
+			<desc>This is layer root file for platform 1</desc>
 		</file>
 		<file type="configuration_root" path="platform1_root.confml">
 			<filter action="include_layer" data="platforms/platform1/root.confml"/>
@@ -39,7 +40,19 @@
 		</file>				
 	</layer>
 	
-	<layer path="platforms/platform2">
+		
+	<layer path="platforms/platform1">
+		<file type="configuration_root" path="platform1_root.confml">
+			<meta xmlns:cv="http://www.nokia.com/xml/cpf-id/1">
+				<version>001</version>
+				<release>${Feature1.StringSetting}</release>
+				<cv:configuration-property name="sw_version" value="${Feature1.StringSetting}" />
+				<cv:configuration-property name="sos_version" value="123.456" />
+			</meta>
+		</file>
+	</layer>
+	
+	<layer path="%NCP_VERSION%/platform2">
 		<folder path="confml">
 			<filter action="add" data="confml_data/platform2/*.confml"/>
 			<filter action="remove" data="confml_data/platform2/platform2.confml"/>
@@ -58,7 +71,29 @@
 			<filter action="include_layer" data="platforms/platform2/root.confml"/>
 		</file>
 	</layer>
-	
+			
+	<layer path="platforms/platform3_feas_only">
+		<folder path="confml">
+			<filter action="add" data="confml_data/platform2/fea*.confml"/>
+		</folder>
+		<folder path="implml">
+			<filter action="add" data="confml_data/platform2/fea*.crml"/>
+			<filter action="add" data="confml_data/platform2/fea*.gcfml"/>
+			<filter action="add" data="confml_data/platform2/fea*.ibyml"/>
+		</folder>
+
+		<file type="layer_root" path="root.confml">
+			<filter action="include_file" data="confml/fea*.confml"/>
+		</file>
+		<file type="configuration_root" path="platform3_root.confml">
+			<filter action="include_layer" data="platforms/platform1/root.confml"/>
+			<filter action="include_layer" data="platforms/platform2/root.confml"/>
+			<filter action="include_layer" data="platforms/platform3/root.confml"/>
+		</file>
+	</layer>
+
+
+
 	<!-- ============ -->
 	<!-- Family layer -->
 	<!-- ============ -->
@@ -86,7 +121,6 @@
 		</file>
 	</layer>
 	
-	
 	<!-- ============= -->
 	<!-- Product layer -->
 	<!-- ============= -->
@@ -111,7 +145,7 @@
 	<!-- Product X language variant layers -->
 	<!-- ================================= -->
 
-	<foreach variable="{TEMPLATE}" data="variants/language/product_x">
+	<foreach variable="{TEMPLATE}" data="%VARIANTS%/language/product_x">
 		<layer path="family_x/product_x/language/{TEMPLATE}">
 			<folder path="confml">
 				<filter action="add" data="variants/language/product_x/{TEMPLATE}/*.confml"/>
@@ -124,7 +158,7 @@
 			<file type="layer_root" path="root.confml">
 				<filter action="include_file" data="confml/*.confml" remove_includes="true"/>
 			</file>
-			<file type="configuration_root" path="product_x_{TEMPLATE}_root.confml">
+			<file type="configuration_root" path="product_x_{TEMPLATE}_root.confml" configuration_name="{TEMPLATE}">
 				<filter action="include_layer" data="platforms/platform1/root.confml"/>
 				<filter action="include_layer" data="platforms/platform2/root.confml"/>
 				<filter action="include_layer" data="family_x/root.confml"/>
@@ -133,4 +167,11 @@
 			</file>
 		</layer>
 	</foreach>
+	
+	<layer path="family_x/product_x/language/Euro">
+		<file type="configuration_root" path="product_x_Euro_root.confml" configuration_name="Euro1_override_name">
+			<filter action="include_layer" data="family_x/product_x/customer/dummy/root.confml"/>
+		</file>	
+	</layer>
+	
 </convertprojectml>
\ No newline at end of file
Binary file configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/family_x/product_x/product_x.confml has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/old_structure/epoc32/rom/config/family_x/product_x/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="ASCII"?>
+<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2 http://www.w3.org/2001/XInclude http://www.s60.com/xml/confml/1#//include">
+  <xi:include href="product_x.confml"/>
+</confml:configuration>
\ No newline at end of file
--- a/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/project/assets/s60/implml/file1.convertprojectml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/project/assets/s60/implml/file1.convertprojectml	Tue Aug 10 14:29:28 2010 +0300
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <convertprojectml xmlns="http://www.s60.com/xml/convertprojectml/1">
 	
-	<targetProject path="/epoc32/rom" name="config_project"/>
+	<targetProject path="/epoc32/rom/config_project"/>
 
 	<layer path="platforms/s60">
 		<folder path="confml/components">
@@ -41,14 +41,13 @@
 	</layer>
 
 	<layer path="ncp53/victoria/language/{TEMPLATE}">
-		<rule type="folders" data="variants/language/victoria/*.*"/>		
 		<folder path="confml">
 			<filter action="add" data="variants/language/victoria/{TEMPLATE}/*.confml"/>
 		</folder>
 		<file type="layer_root" path="root.confml">
 			<filter action="include_file" data="*.confml"/>
 		</file>
-		<file type="configuration_root" name="{TEMPLATE}_root.confml">
+		<file type="configuration_root" path="{TEMPLATE}_root.confml">
 			<filter action="include_layer" data="s60"/>
 			<filter action="include_layer" data="customsw"/>
 			<filter action="include_layer" data="ncp53"/>
--- a/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/runtests.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/runtests.py	Tue Aug 10 14:29:28 2010 +0300
@@ -14,6 +14,6 @@
 # Description: 
 #
 
-import __init__
-
-__init__.runtests()
\ No newline at end of file
+if __name__ == '__main__':
+    import nose
+    nose.core.run(argv=['collector','--include=unittest', '--verbosity=3'])
--- a/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/unittest_convertprojectml_plugin.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/tests/unittest_convertprojectml_plugin.py	Tue Aug 10 14:29:28 2010 +0300
@@ -16,11 +16,9 @@
 
 import unittest, os, shutil
 
-import __init__	
 from projectconvertplugin  import convertproject
-from cone.public import exceptions,plugin,api
+from cone.public import plugin,api
 from cone.storage import filestorage
-from cone.confml import implml
 from testautomation.base_testcase import BaseTestCase
 
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
@@ -43,6 +41,8 @@
         self.assertTrue(isinstance(impl, convertproject.ConvertProjectImpl))
         
     def test_generate(self):
+        os.environ['ncp_version'] = 'platforms'
+        os.environ['variants'] = 'variants'        
         output_dir = os.path.join(temp_dir, "new_project")
         if os.path.exists(output_dir):
             shutil.rmtree(output_dir)
@@ -52,12 +52,14 @@
         fs = filestorage.FileStorage(oldPath)
         p = api.Project(fs)
         config = p.get_configuration('convert.confml')
+        context = plugin.GenerationContext(configuration=config,
+                                           output=output_dir)
         impls = plugin.get_impl_set(config,'\.convertprojectml$')
-        impls.output = output_dir
-        impls.generate()
+        context.filtering_disabled = True
+        impls.generate(context)
         
         self.assert_dir_contents_equal(expected_dir, output_dir, ['.svn'])
 
         
 if __name__ == '__main__':
-  unittest.main()
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/xsd/convertprojectml.xsd	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema 
+    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
+    targetNamespace="http://www.s60.com/xml/convertprojectml/1" 
+    xmlns:cpml="http://www.s60.com/xml/convertprojectml/1" 
+    elementFormDefault="qualified">
+    
+    
+    <xs:complexType name="metaType">
+        <xs:sequence>
+            <xs:any minOccurs="0" maxOccurs="unbounded" processContents="skip"/>
+        </xs:sequence>
+    </xs:complexType>
+    
+    <xs:complexType name="filterType">
+        <xs:attribute name="action" type="xs:string" use="required"/>
+        <xs:attribute name="data" type="xs:string" use="required"/>
+        <xs:attribute name="remove_includes" type="xs:string"/>
+        <xs:attribute name="recursive" type="xs:string"/>
+    </xs:complexType>
+    
+    <xs:complexType name="fileType">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+            <xs:element name="filter" type="cpml:filterType"/>
+            <xs:element name="meta" type="cpml:metaType"/>
+            <xs:element name="desc" type="xs:string"/>
+        </xs:choice>
+        <xs:attribute name="type" type="xs:string"/>
+        <xs:attribute name="path" type="xs:string"/>
+    </xs:complexType>
+    
+    <xs:complexType name="folderType">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+            <xs:element name="filter" type="cpml:filterType"/>
+        </xs:choice>
+        <xs:attribute name="path" type="xs:string"/>
+    </xs:complexType>
+    
+    <xs:complexType name="layerType">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+            <xs:element name="folder" type="cpml:folderType"/>
+            <xs:element name="file" type="cpml:fileType"/>
+        </xs:choice>
+        <xs:attribute name="path" type="xs:string"/>
+    </xs:complexType>
+    
+    <xs:complexType name="foreachType">
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+            <xs:element name="layer" type="cpml:layerType"/>
+        </xs:choice>
+        <xs:attribute name="variable" type="xs:string" use="required"/>
+        <xs:attribute name="data" type="xs:string" use="required"/>
+    </xs:complexType>
+    
+    <xs:complexType name="targetProjectType">
+        <xs:attribute name="path" type="xs:string"/>
+    </xs:complexType>
+    
+    <xs:element name="convertprojectml">
+        <xs:complexType>
+            <xs:sequence>
+                <xs:element name="targetProject" type="cpml:targetProjectType" minOccurs="0" maxOccurs="1"/>
+                <xs:choice minOccurs="0" maxOccurs="unbounded">
+                    <xs:element name="layer" type="cpml:layerType"/>
+                    <xs:element name="foreach" type="cpml:foreachType"/>
+                </xs:choice>
+            </xs:sequence>
+        </xs:complexType>
+    </xs:element>
+    
+</xs:schema>
\ No newline at end of file
--- a/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/setup.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/setup.py	Tue Aug 10 14:29:28 2010 +0300
@@ -22,6 +22,7 @@
     name = "projectconvertplugin",
     version = __version__,
     packages = find_packages(exclude=["*.tests"]),
+    package_data = {'projectconvertplugin': ['xsd/*.xsd']},
     test_suite = "projectconvertplugin.tests.collect_suite",
 
     # metadata for upload to PyPI
--- a/configurationengine/source/plugins/symbian/ConeThemePlugin/setup.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/setup.py	Tue Aug 10 14:29:28 2010 +0300
@@ -22,6 +22,7 @@
     name = "conethemeplugin",
     version = __version__,
     packages = find_packages(exclude=["*.tests"]),
+    package_data = {'themeplugin': ['xsd/*.xsd']},
 
     # metadata for upload to PyPI
     author = "",
--- a/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/maketheme.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/maketheme.py	Tue Aug 10 14:29:28 2010 +0300
@@ -21,6 +21,7 @@
 import xml.parsers.expat
 import unzip
 import shutil
+import pkg_resources
 
 try:
     from cElementTree import ElementTree
@@ -84,13 +85,13 @@
         plugin.ImplBase.__init__(self,ref,configuration)
         self.logger = logging.getLogger('cone.thememl')
         
-    def build(self):
+    def build(self, context):
         """
         Building process of themes
         """
         # Get absolute path so that copying works correctly
         # despite working directory changing
-        abs_output = os.path.abspath(os.path.join(self.output, "content"))
+        abs_output = os.path.abspath(os.path.join(context.output, self.output, "content"))
         
         # get *.tpf files from the configuration
         list_tpf = self.list_tpf_files(self.list_active_theme, self.list_theme_dir)
@@ -172,8 +173,15 @@
         """
         Generate the given implementation.
         """
-        self.parse_impl()
-        self.build()
+        # Make sure autoconfig is the last layer, since theme conversion
+        # may change the values of some settings
+        autoconfig = plugin.get_autoconfig(self.configuration)
+        
+        self.build(context)
+        
+        # Add changed refs if necessary
+        if context:
+            context.add_changed_refs(autoconfig.list_leaf_datas())
         
         return 
     
@@ -191,24 +199,6 @@
         Otherwise return False.
         """
         return None
-
-    def parse_impl(self):
-        if self.configuration:
-            resource =self.configuration.get_resource(self.ref)
-            reader = ThemeImplReader()
-            try:
-                self.logger.info('Parses %s' % self.ref)
-                reader.fromstring(resource.read())
-                self.carbide = reader.carbide
-            except (SyntaxError),e:
-                logging.getLogger('cone.thememl(%s)' % resource.get_path()).error('Invalid xml in layer root file. Exception: %s' % (e))
-                raise exceptions.ParseError('Invalid xml in layer root file (%s). Exception: %s' % (resource.get_path(),e))
-            self.list_theme_dir=reader.list_theme_dir
-            self.list_active_theme=reader.list_active_theme
-            self.theme_version = reader.theme_version
-            resource.close()
-
-        return 
     
     def list_output_files(self):
         """
@@ -223,6 +213,8 @@
     Parses a single thememl file
     """ 
     NAMESPACE = 'http://www.s60.com/xml/thememl/1'
+    NAMESPACE_ID = 'thememl'
+    ROOT_ELEMENT_NAME = 'thememl'
     FILE_EXTENSIONS = ['thememl']
     
     def __init__(self):
@@ -242,8 +234,13 @@
         impl.list_theme_dir     = reader.list_theme_dir
         impl.list_active_theme  = reader.list_active_theme
         impl.theme_version      = reader.theme_version
+        impl.carbide            = reader.carbide
         return impl
     
+    @classmethod
+    def get_schema_data(cls):
+        return pkg_resources.resource_string('themeplugin', 'xsd/thememl.xsd')
+    
     def fromstring(self, xml_as_string):
         etree = ElementTree.fromstring(xml_as_string)
         self.parse_thememl(etree)
--- a/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/__init__.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/__init__.py	Tue Aug 10 14:29:28 2010 +0300
@@ -13,24 +13,12 @@
 #
 # Description: 
 #
+
 import sys, os, unittest
 
 # Path to the directory where this file is located
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
 
-# Import common plug-in initialization
-PLUGINS_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../../../..'))
-assert os.path.split(PLUGINS_ROOT)[1] == 'plugins'
-if PLUGINS_ROOT not in sys.path: sys.path.append(PLUGINS_ROOT)
-import plugin_utils
-
+from testautomation import plugin_utils
 plugin_utils.plugin_test_init(ROOT_PATH)
 
-def collect_suite():
-    return plugin_utils.collect_test_suite_from_dir(ROOT_PATH)
-
-def runtests():
-    unittest.TextTestRunner(verbosity=2).run(collect_suite())
-
-if __name__ == '__main__':
-    runtests()
--- a/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/test_pkg/themepackage2.pkg	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/e75/test_pkg/themepackage2.pkg	Tue Aug 10 14:29:28 2010 +0300
@@ -50,10 +50,6 @@
 ;
 ; Files to install
 ;
-IF PACKAGE(0X102032BE) ; CHECK FOR S60 3.1 STUB SIS
-"themepackage.mbm" - "!:\resource\skins\f99553e36ea1a92f\themepackage.mbm"
-"themepackage.mif" - "!:\resource\skins\f99553e36ea1a92f\themepackage.mif"
-ELSE
 "themepackage.mbm" - "!:\private\10207114\import\f99553e36ea1a92f\themepackage.mbm"
 "themepackage.mif" - "!:\private\10207114\import\f99553e36ea1a92f\themepackage.mif"
 ENDIF
--- a/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/runtests.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/runtests.py	Tue Aug 10 14:29:28 2010 +0300
@@ -15,6 +15,6 @@
 #
 
 
-import __init__
-
-__init__.runtests()
+if __name__ == '__main__':
+    import nose
+    nose.core.run(argv=['collector','--include=unittest', '--verbosity=3'])
--- a/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/unittest_theme_container.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/unittest_theme_container.py	Tue Aug 10 14:29:28 2010 +0300
@@ -14,15 +14,10 @@
 # Description: 
 #
 
-import unittest, os, shutil
+import unittest, sys, os
 
-import __init__    
-from cone.public import exceptions,plugin,api
-from cone.storage import filestorage
-from cone.confml import implml
-from themeplugin import theme_function
+from cone.public import api
 from themeplugin.theme_container import ThemeContainer
-from cone.storage.filestorage import FileStorage
 
 from unittest_theme_plugin import impl_from_resource
 
@@ -44,7 +39,6 @@
         impl = impl_from_resource("variant/implml/theme.thememl", config);
         list_tpf = impl.list_tpf_files(impl.list_active_theme, impl.list_theme_dir)
         
-        list_theme=[]
         container = ThemeContainer(list_tpf,impl.configuration)
         container.create_themes()
         self.assertEquals(len(container.list_theme),2)
@@ -74,7 +68,9 @@
         self.assertEquals(theme.get_setting_uids(), ["KCRUidPersonalisation.KPslnActiveSkinUid"])
         self.assertEquals(theme.get_uid(), "0x101FD60A")
 
-         
+# Only run these tests on Windows
+if sys.platform != 'win32':
+    del TestThemePlugin
         
 if __name__ == '__main__':
-  unittest.main()
+    unittest.main()
--- a/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/unittest_theme_function.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/unittest_theme_function.py	Tue Aug 10 14:29:28 2010 +0300
@@ -14,15 +14,9 @@
 # Description: 
 #
 
-import unittest, os, shutil
+import unittest, os, sys
 
-import __init__    
-from cone.public import exceptions,plugin,api
-from cone.storage import filestorage
-from cone.confml import implml
-from themeplugin import maketheme
 from themeplugin import theme_function
-from cone.storage.filestorage import FileStorage
 
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
 
@@ -36,8 +30,8 @@
         pass
         
     def test_convert_hexa_to_decimal(self):
-       decimal = theme_function.convert_hexa_to_decimal("a5d5f19d6e6097b8")
-       self.assertEquals(decimal,"-1512705635 1851824056")
+        decimal = theme_function.convert_hexa_to_decimal("a5d5f19d6e6097b8")
+        self.assertEquals(decimal,"-1512705635 1851824056")
        
     def test_find_text_in_string(self):
         row_in_pkg_file = "\"themepackage.mbm\" - \"!:\\resource\\skins\\99d49b086e6097b8\\themepackage.mbm\""
@@ -53,6 +47,9 @@
         PID = theme_function.find_text_in_file(os.path.join(ROOT_PATH,"e75\\test_pkg\\themepackage.pkg"),start_text, end_text)
         self.assertEquals(PID,"99d49b086e6097b8")
 
+# Only run these tests on Windows
+if sys.platform != 'win32':
+    del TestThemePlugin
         
 if __name__ == '__main__':
-  unittest.main()
+    unittest.main()
--- a/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/unittest_theme_plugin.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/unittest_theme_plugin.py	Tue Aug 10 14:29:28 2010 +0300
@@ -14,21 +14,16 @@
 # Description: 
 #
 
-import unittest, os, shutil
+import unittest, os, sys
 
-import __init__	
-from cone.public import exceptions,plugin,api
-from cone.storage import filestorage
-from cone.confml import implml
-from themeplugin import maketheme
-from themeplugin import theme_function
-from cone.storage.filestorage import FileStorage
+from cone.public import plugin,api
 
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
 
 def impl_from_resource(resource_ref, configuration):
-    doc_root = plugin.ReaderBase._read_xml_doc_from_resource(resource_ref, configuration)
-    return maketheme.ThemeImplReader.read_impl(resource_ref, configuration, doc_root)
+    impls = plugin.ImplFactory.get_impls_from_file(resource_ref, configuration)
+    assert len(impls) == 1
+    return impls[0]
 
 class TestThemePlugin(unittest.TestCase):    
     def setUp(self):
@@ -43,8 +38,6 @@
         project = api.Project(api.Storage.open(os.path.join(ROOT_PATH,"e75")))
         config = project.get_configuration("root_variant.confml")
         impl = impl_from_resource("variant/implml/theme.thememl", config);
-        t1 = impl.list_theme_dir
-        t2 = impl.list_active_theme
         list_tpf_files = impl.list_tpf_files(impl.list_active_theme,impl.list_theme_dir)
         self.assertEquals(sorted(list_tpf_files),
                           sorted(['variant/content/UI/Themes/Armi.tpf', 's60/content/UI/Armi2.tpf']))
@@ -70,7 +63,9 @@
         list_tpf_files = impl.find_tpf_files(tpf_paths)
         self.assertEquals(sorted(list_tpf_files), sorted(['variant/content/UI/Themes/Armi.tpf', 's60/content/UI/Armi2.tpf']))
 
-         
+# Only run these tests on Windows
+if sys.platform != 'win32':
+    del TestThemePlugin
         
 if __name__ == '__main__':
-  unittest.main()
+    unittest.main()
--- a/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/unittest_theme_resource.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/tests/unittest_theme_resource.py	Tue Aug 10 14:29:28 2010 +0300
@@ -14,14 +14,9 @@
 # Description: 
 #
 
-import unittest, os, shutil
+import unittest, os, sys
 
-import __init__    
-from cone.public import exceptions,plugin,api
-from cone.storage import filestorage
-from cone.confml import implml
 from themeplugin import theme_resource
-from cone.storage.filestorage import FileStorage
 
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
 
@@ -50,6 +45,9 @@
         else:
             self.assertFalse()
 
+# Only run these tests on Windows
+if sys.platform != 'win32':
+    del TestThemePlugin
         
 if __name__ == '__main__':
-  unittest.main()
+    unittest.main()
--- a/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/theme_container.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/theme_container.py	Tue Aug 10 14:29:28 2010 +0300
@@ -104,8 +104,6 @@
         
         for theme in self.list_theme:
             
-            # Make sure autoconfig is the last layer
-            plugin.get_autoconfig(self.configuration)
 
             default_view = self.configuration.get_default_view()
             
--- a/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/theme_resource.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/theme_resource.py	Tue Aug 10 14:29:28 2010 +0300
@@ -15,7 +15,7 @@
 #
 
 from shutil import copy
-import os
+import os, re
 
 class ThemeResource:   
     """
@@ -34,37 +34,23 @@
         The class ThemeResource contains a name of theme resource 
         and a path where this resource will be copied in the output directory
         """
-        pkg_file=file(file_path,'r')
-        is_found_else=False
-        row = ""
+        
+        resource_pattern = re.compile(r'"(.*)"\s+-\s+"!:\\(.*)"')
         # for every row in pkg file
-        for row in pkg_file:
-            #if it finds tag "ELSE" then it begins load the records about the theme resources
-            if row.startswith("ELSE"):
-                is_found_else = True
-              
-            if(is_found_else):
-                parts_of_row = row.split("\"")
-                #the loading record has to have 5 parts separated "\"
-                if len(parts_of_row) == 5:
-                    #gets the path of the theme resource
-                    path = parts_of_row[3]
-                    #removes these chars "!:\" from the path of theme resource
-                    path = self.modify_resource_path(path)
-                    #parts_of_row[1 is the filename of the theme resource
-                    resource = Resource(parts_of_row[1], path)
-                    self.list_resource.append(resource)
-   
-        pkg_file.close()  
+        for row in open(file_path, 'r'):
+            mo = resource_pattern.match(row)
+            if mo:
+                resource = Resource(mo.group(1), os.path.split(mo.group(2))[0])
+                self.list_resource.append(resource)
     
     def copy_files_from_theme(self, source_path, output_path):
         """
         copies theme resources from  source directory to theirs target paths 
         """
         for resource in self.list_resource:
-           source_file = os.path.join(source_path, resource.get_filename())
-           target_dir =  os.path.join(output_path, resource.get_path())
-           self.copy_files(source_file, target_dir)          
+            source_file = os.path.join(source_path, resource.get_filename())
+            target_dir =  os.path.join(output_path, resource.get_path())
+            self.copy_files(source_file, target_dir)          
         
     def copy_files(self, source_path, target_path):
         """
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/ConeThemePlugin/themeplugin/xsd/thememl.xsd	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema 
+	xmlns:xs="http://www.w3.org/2001/XMLSchema" 
+	targetNamespace="http://www.s60.com/xml/thememl/1" 
+	xmlns:theme="http://www.s60.com/xml/thememl/1" 
+	elementFormDefault="qualified">
+	
+    <xs:complexType name="activeThemeType">
+        <xs:sequence>
+            <xs:element name="refSetting" type="xs:string" minOccurs="1" maxOccurs="1"/>
+			<xs:element name="platformUID" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+        </xs:sequence>  
+        <xs:attribute name="uid" type="xs:string" use="required"/>
+    </xs:complexType>
+
+	<xs:complexType name="thememlRootType">
+        <xs:sequence>
+            <xs:element name="carbideuiPath" type="xs:string"/>
+            <xs:choice minOccurs="0" maxOccurs="unbounded">
+                <xs:element name="activeTheme" type="theme:activeThemeType"/>
+                <xs:element name="themeDir" type="xs:string"/>
+            </xs:choice>
+        </xs:sequence>
+    </xs:complexType>
+
+	<xs:element name="thememl" type="theme:thememlRootType"/>
+
+</xs:schema>
\ No newline at end of file
--- a/configurationengine/source/plugins/symbian/integration-test/__init__.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/integration-test/__init__.py	Tue Aug 10 14:29:28 2010 +0300
@@ -14,24 +14,4 @@
 # Description: 
 #
 
-import unittest, os, sys
 
-ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
-PLUGIN_SOURCE_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '../..'))
-assert os.path.split(PLUGIN_SOURCE_ROOT)[1] == 'plugins'
-
-# Import plugin_utils from the plug-in sources root
-if PLUGIN_SOURCE_ROOT not in sys.path: sys.path.append(PLUGIN_SOURCE_ROOT)
-import plugin_utils
-
-# Run integration test initialization
-plugin_utils.integration_test_init(ROOT_PATH)
-
-def collect_suite():
-    return plugin_utils.collect_test_suite_from_dir(ROOT_PATH)
-
-def runtests():
-    unittest.TextTestRunner(verbosity=2).run(collect_suite())
-
-if __name__ == '__main__':
-    runtests()
--- a/configurationengine/source/plugins/symbian/integration-test/runtests.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/integration-test/runtests.py	Tue Aug 10 14:29:28 2010 +0300
@@ -14,6 +14,6 @@
 # Description: 
 #
 
-import __init__
-
-__init__.runtests()
+if __name__ == '__main__':
+    import nose
+    nose.core.run(argv=['collector','--include=unittest', '--verbosity=3'])
\ No newline at end of file
--- a/configurationengine/source/plugins/symbian/integration-test/testdata/crml_dc_expected/crml_dc.html	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/crml_dc_expected/crml_dc.html	Tue Aug 10 14:29:28 2010 +0300
@@ -110,7 +110,28 @@
     .currentValue {
         background-color: #e8f2fe;
     }
+
+.fltrow{ /* filter grid row appearance */
+    height:20px;
+    background-color:#f4f4f4;
+}
+.btnflt{ /* button appearance */
+    font-size:11px;
+    margin:0 2px 0 2px; padding:0 1px 0 1px;
+    text-decoration:none; color: #fff;
+    background-color:#666;
+}
+.flt{ /* filter (input) appearance */
+    background-color:#f4f4f4; border:1px inset #ccc; 
+    margin:0; width:100%;
+}
+.flt_s{ /* small filter (input) appearance */
+    background-color:#f4f4f4; border:1px inset #ccc; 
+    margin:0; width:80%;
+}
+
 </style>
+<script language="javascript" type="text/javascript" src="http://www.javascriptkit.com/script/script2/tablefilter.js"></script>
 <title>Compare data - ConE</title>
 
 </head>
@@ -119,7 +140,7 @@
 
     <h1>CRML Data Compatibility Report</h1><br>
     
-    <table class="report">
+    <table class="report" id="cdc_report">
       <tr>
         <td>Source:</td>
         <td>root.confml</td>
@@ -129,12 +150,18 @@
         <td>this is ignored\comp_project_2;root.confml</td>
       </tr>
     </table>
+    <script language="javascript" type="text/javascript">
+//<![CDATA[
+    setFilterGrid("cdc_report");
+//]]>
+</script>
+    
     
     <br/>
     
     <h2>Modified keys/files:</h2>
     
-    <table class="report">
+    <table class="report" id="mk_report">
     <tr>
         <th>File</th>
         <th>Repository UID</th>
@@ -668,11 +695,17 @@
                 </tr>
             
     </table>
+    <script language="javascript" type="text/javascript">
+//<![CDATA[
+    setFilterGrid("mk_report");
+//]]>
+</script>
+    
     
     
     <h2>Added keys/files:</h2>
     
-    <table class="report">
+    <table class="report" id="ak_report">
     <tr>
         <th>File</th>
         <th>Repository UID</th>
@@ -725,11 +758,16 @@
             </tr>
         
     </table>
+    <script language="javascript" type="text/javascript">
+//<![CDATA[
+    setFilterGrid("ak_report");
+//]]>
+</script>
     
     
     <h2>Removed keys/files:</h2>
     
-    <table class="report">
+    <table class="report" id="rk_report">
     <tr>
         <th>File</th>
         <th>Repository UID</th>
@@ -782,11 +820,16 @@
             </tr>
         
     </table>
+    <script language="javascript" type="text/javascript">
+//<![CDATA[
+    setFilterGrid("rk_report");
+//]]>
+</script>
     
     
     <h2>Duplicate repositories:</h2>
     
-    <table class="report">
+    <table class="report" id="dr_report">
     <tr>
         <th>Repository UID</th>
         <th>Files in source</th>
@@ -804,6 +847,12 @@
             </tr>
         
     </table>
+    <script language="javascript" type="text/javascript">
+//<![CDATA[
+    setFilterGrid("dr_report");
+//]]>
+</script>
+    
 </div>
 <div id="footer"></div>
 </body>
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/deltacenrep/deltacenrep_expected/deltacenreps/00000002.txt has changed
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/deltacenrep/deltacenrep_expected/deltacenreps/00000003.txt has changed
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/deltacenrep/deltacenrep_expected/deltacenreps/00000005.txt has changed
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/deltacenrep/deltacenrep_expected/deltacenreps/00000006.txt has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/deltacenrep/deltacenrep_expected/include/deltacenreps.iby	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,11 @@
+
+#ifndef __DELTA_CENREPS_IBY
+#define __DELTA_CENREPS_IBY
+
+data = X:\ignored\output\deltacenreps\00000002.txt			private\10202BE9\00000002.txt exattrib=U
+data = X:\ignored\output\deltacenreps\00000003.txt			private\10202BE9\00000003.txt exattrib=U
+data = X:\ignored\output\deltacenreps\00000005.txt			private\10202BE9\00000005.txt exattrib=U
+data = X:\ignored\output\deltacenreps\00000006.txt			private\10202BE9\00000006.txt exattrib=U
+
+
+#endif // __DELTA_CENREPS_IBY
\ No newline at end of file
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/deltacenrep/normalcenrep_expected/content/private/10202BE9/00000002.txt has changed
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/deltacenrep/normalcenrep_expected/content/private/10202BE9/00000003.txt has changed
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/deltacenrep/normalcenrep_expected/content/private/10202BE9/00000005.txt has changed
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/deltacenrep/normalcenrep_expected/content/private/10202BE9/00000006.txt has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/deltacenrep/project/Layer1/confml/bitmask_test.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,260 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/1" name="Bitmask test" version="1">
+  <feature ref="BitmaskTest" name="Bitmask test">
+    <desc>Feature with bitmask flags</desc>
+    <setting ref="Bit0" name="Bit 0" type="boolean">
+      <desc>A boolean setting for bit 0</desc>
+    </setting>
+    <setting ref="Bit1" name="Bit 1" type="boolean">
+      <desc>A boolean setting for bit 1</desc>
+    </setting>
+    <setting ref="Bit2" name="Bit 2" type="boolean">
+      <desc>A boolean setting for bit 2</desc>
+    </setting>
+    <setting ref="Bit3" name="Bit 3" type="boolean">
+      <desc>A boolean setting for bit 3</desc>
+    </setting>
+    <setting ref="Bit4" name="Bit 4" type="boolean">
+      <desc>A boolean setting for bit 4</desc>
+    </setting>
+    <setting ref="Bit5" name="Bit 5" type="boolean">
+      <desc>A boolean setting for bit 5</desc>
+    </setting>
+    
+    <setting ref="InvertedMaskBit1" name="Inverted mask, Bit 1" type="boolean"/>
+    <setting ref="InvertedMaskBit2" name="Inverted mask, Bit 2" type="boolean"/>
+    <setting ref="InvertedMaskBit3" name="Inverted mask, Bit 3" type="boolean"/>
+    <setting ref="InvertedMaskBit4" name="Inverted mask, Bit 4" type="boolean"/>
+    
+    <setting ref="Int32Bit1" name="Int32, Bit 1" type="boolean"/>
+    <setting ref="Int32Bit2" name="Int32, Bit 2" type="boolean"/>
+    <setting ref="Int32Bit3" name="Int32, Bit 3" type="boolean"/>
+    <setting ref="Int32Bit4" name="Int32, Bit 4" type="boolean"/>
+    <setting ref="Int32Bit5" name="Int32, Bit 5" type="boolean"/>
+    <setting ref="Int32Bit6" name="Int32, Bit 6" type="boolean"/>
+    <setting ref="Int32Bit7" name="Int32, Bit 7" type="boolean"/>
+    <setting ref="Int32Bit8" name="Int32, Bit 8" type="boolean"/>
+    <setting ref="Int32Bit9" name="Int32, Bit 9" type="boolean"/>
+    <setting ref="Int32Bit10" name="Int32, Bit 10" type="boolean"/>
+    <setting ref="Int32Bit11" name="Int32, Bit 11" type="boolean"/>
+    <setting ref="Int32Bit12" name="Int32, Bit 12" type="boolean"/>
+    <setting ref="Int32Bit13" name="Int32, Bit 13" type="boolean"/>
+    <setting ref="Int32Bit14" name="Int32, Bit 14" type="boolean"/>
+    <setting ref="Int32Bit15" name="Int32, Bit 15" type="boolean"/>
+    <setting ref="Int32Bit16" name="Int32, Bit 16" type="boolean"/>
+    <setting ref="Int32Bit17" name="Int32, Bit 17" type="boolean"/>
+    <setting ref="Int32Bit18" name="Int32, Bit 18" type="boolean"/>
+    <setting ref="Int32Bit19" name="Int32, Bit 19" type="boolean"/>
+    <setting ref="Int32Bit20" name="Int32, Bit 20" type="boolean"/>
+    <setting ref="Int32Bit21" name="Int32, Bit 21" type="boolean"/>
+    <setting ref="Int32Bit22" name="Int32, Bit 22" type="boolean"/>
+    <setting ref="Int32Bit23" name="Int32, Bit 23" type="boolean"/>
+    <setting ref="Int32Bit24" name="Int32, Bit 24" type="boolean"/>
+    <setting ref="Int32Bit25" name="Int32, Bit 25" type="boolean"/>
+    <setting ref="Int32Bit26" name="Int32, Bit 26" type="boolean"/>
+    <setting ref="Int32Bit27" name="Int32, Bit 27" type="boolean"/>
+    <setting ref="Int32Bit28" name="Int32, Bit 28" type="boolean"/>
+    <setting ref="Int32Bit29" name="Int32, Bit 29" type="boolean"/>
+    <setting ref="Int32Bit30" name="Int32, Bit 30" type="boolean"/>
+    <setting ref="Int32Bit31" name="Int32, Bit 31" type="boolean"/>
+    <setting ref="Int32Bit32" name="Int32, Bit 32" type="boolean"/>
+    
+    <setting ref="SparseInt32Bit1" name="Sparse Int32, Bit 1" type="boolean"/>
+    <setting ref="SparseInt32Bit7" name="Sparse Int32, Bit 7" type="boolean"/>
+    <setting ref="SparseInt32Bit18" name="Sparse Int32, Bit 18" type="boolean"/>
+    <setting ref="SparseInt32Bit24" name="Sparse Int32, Bit 24" type="boolean"/>
+    <setting ref="SparseInt32Bit31" name="Sparse Int32, Bit 31" type="boolean"/>
+
+    <setting ref="BinaryBit1" name="Binary, Bit 1" type="boolean"/>
+    <setting ref="BinaryBit10" name="Binary, Bit 10" type="boolean"/>
+    <setting ref="BinaryBit20" name="Binary, Bit 20" type="boolean"/>
+    <setting ref="BinaryBit30" name="Binary, Bit 30" type="boolean"/>
+    <setting ref="BinaryBit40" name="Binary, Bit 40" type="boolean"/>
+    <setting ref="BinaryBit50" name="Binary, Bit 50" type="boolean"/>
+    <setting ref="BinaryBit60" name="Binary, Bit 60" type="boolean"/>
+    <setting ref="BinaryBit70" name="Binary, Bit 70" type="boolean"/>
+    <setting ref="BinaryBit80" name="Binary, Bit 80" type="boolean"/>
+    <setting ref="BinaryBit90" name="Binary, Bit 90" type="boolean"/>
+    <setting ref="BinaryBit100" name="Binary, Bit 100" type="boolean"/>
+    
+    <setting ref="BinaryMask2Bit1" name="Binary mask 2, Bit 1" type="boolean"/>
+    <setting ref="BinaryMask2Bit2" name="Binary mask 2, Bit 2" type="boolean"/>
+    <setting ref="BinaryMask2Bit3" name="Binary mask 2, Bit 3" type="boolean"/>
+    <setting ref="BinaryMask2Bit4" name="Binary mask 2, Bit 4" type="boolean"/>
+    <setting ref="BinaryMask2Bit5" name="Binary mask 2, Bit 5" type="boolean"/>
+    <setting ref="BinaryMask2Bit6" name="Binary mask 2, Bit 6" type="boolean"/>
+    <setting ref="BinaryMask2Bit7" name="Binary mask 2, Bit 7" type="boolean"/>
+    <setting ref="BinaryMask2Bit8" name="Binary mask 2, Bit 8" type="boolean"/>
+    <setting ref="BinaryMask2Bit9" name="Binary mask 2, Bit 9" type="boolean"/>
+    <setting ref="BinaryMask2Bit10" name="Binary mask 2, Bit 10" type="boolean"/>
+    <setting ref="BinaryMask2Bit11" name="Binary mask 2, Bit 11" type="boolean"/>
+    <setting ref="BinaryMask2Bit12" name="Binary mask 2, Bit 12" type="boolean"/>
+    <setting ref="BinaryMask2Bit13" name="Binary mask 2, Bit 13" type="boolean"/>
+    <setting ref="BinaryMask2Bit14" name="Binary mask 2, Bit 14" type="boolean"/>
+    <setting ref="BinaryMask2Bit15" name="Binary mask 2, Bit 15" type="boolean"/>
+    <setting ref="BinaryMask2Bit16" name="Binary mask 2, Bit 16" type="boolean"/>
+    <setting ref="BinaryMask2Bit17" name="Binary mask 2, Bit 17" type="boolean"/>
+    
+    <setting ref="BinaryMask3Bit1" name="Binary mask 3, Bit 1" type="boolean"/>
+    <setting ref="BinaryMask3Bit2" name="Binary mask 3, Bit 2" type="boolean"/>
+    <setting ref="BinaryMask3Bit3" name="Binary mask 3, Bit 3" type="boolean"/>
+    <setting ref="BinaryMask3Bit4" name="Binary mask 3, Bit 4" type="boolean"/>
+    <setting ref="BinaryMask3Bit5" name="Binary mask 3, Bit 5" type="boolean"/>
+    <setting ref="BinaryMask3Bit6" name="Binary mask 3, Bit 6" type="boolean"/>
+    <setting ref="BinaryMask3Bit7" name="Binary mask 3, Bit 7" type="boolean"/>
+    <setting ref="BinaryMask3Bit8" name="Binary mask 3, Bit 8" type="boolean"/>
+    <setting ref="BinaryMask3Bit9" name="Binary mask 3, Bit 9" type="boolean"/>
+    <setting ref="BinaryMask3Bit10" name="Binary mask 3, Bit 10" type="boolean"/>
+    <setting ref="BinaryMask3Bit11" name="Binary mask 3, Bit 11" type="boolean"/>
+    <setting ref="BinaryMask3Bit12" name="Binary mask 3, Bit 12" type="boolean"/>
+    <setting ref="BinaryMask3Bit13" name="Binary mask 3, Bit 13" type="boolean"/>
+    <setting ref="BinaryMask3Bit14" name="Binary mask 3, Bit 14" type="boolean"/>
+    <setting ref="BinaryMask3Bit15" name="Binary mask 3, Bit 15" type="boolean"/>
+    <setting ref="BinaryMask3Bit16" name="Binary mask 3, Bit 16" type="boolean"/>
+    <setting ref="BinaryMask3Bit17" name="Binary mask 3, Bit 17" type="boolean"/>
+    
+    <setting ref="BinaryMask4Bit1" name="Binary mask 4, Bit 1" type="boolean"/>
+    <setting ref="BinaryMask4Bit2" name="Binary mask 4, Bit 2" type="boolean"/>
+    <setting ref="BinaryMask4Bit3" name="Binary mask 4, Bit 3" type="boolean"/>
+    <setting ref="BinaryMask4Bit4" name="Binary mask 4, Bit 4" type="boolean"/>
+    <setting ref="BinaryMask4Bit5" name="Binary mask 4, Bit 5" type="boolean"/>
+    <setting ref="BinaryMask4Bit6" name="Binary mask 4, Bit 6" type="boolean"/>
+    <setting ref="BinaryMask4Bit7" name="Binary mask 4, Bit 7" type="boolean"/>
+    <setting ref="BinaryMask4Bit8" name="Binary mask 4, Bit 8" type="boolean"/>
+    <setting ref="BinaryMask4Bit9" name="Binary mask 4, Bit 9" type="boolean"/>
+    <setting ref="BinaryMask4Bit10" name="Binary mask 4, Bit 10" type="boolean"/>
+    <setting ref="BinaryMask4Bit11" name="Binary mask 4, Bit 11" type="boolean"/>
+    <setting ref="BinaryMask4Bit12" name="Binary mask 4, Bit 12" type="boolean"/>
+    <setting ref="BinaryMask4Bit13" name="Binary mask 4, Bit 13" type="boolean"/>
+    <setting ref="BinaryMask4Bit14" name="Binary mask 4, Bit 14" type="boolean"/>
+    <setting ref="BinaryMask4Bit15" name="Binary mask 4, Bit 15" type="boolean"/>
+    <setting ref="BinaryMask4Bit16" name="Binary mask 4, Bit 16" type="boolean"/>
+    <setting ref="BinaryMask4Bit17" name="Binary mask 4, Bit 17" type="boolean"/>
+    
+    <setting ref="BinaryMask5Bit1" name="Binary mask 5, Bit 1" type="boolean"/>
+    
+  </feature>
+  <data>
+    <BitmaskTest>
+      <Bit0>true</Bit0>
+      <Bit1>false</Bit1>
+      <Bit2>true</Bit2>
+      <Bit3>false</Bit3>
+      <Bit4>true</Bit4>
+      <Bit5>false</Bit5>
+      
+      <InvertedMaskBit1>false</InvertedMaskBit1>
+      <InvertedMaskBit2>true</InvertedMaskBit2>
+      <InvertedMaskBit3>false</InvertedMaskBit3>
+      <InvertedMaskBit4>true</InvertedMaskBit4>
+      
+      <Int32Bit1>false</Int32Bit1>
+      <Int32Bit2>true</Int32Bit2>
+      <Int32Bit3>true</Int32Bit3>
+      <Int32Bit4>false</Int32Bit4>
+      <Int32Bit5>true</Int32Bit5>
+      <Int32Bit6>false</Int32Bit6>
+      <Int32Bit7>true</Int32Bit7>
+      <Int32Bit8>false</Int32Bit8>
+      <Int32Bit9>true</Int32Bit9>
+      <Int32Bit10>true</Int32Bit10>
+      <Int32Bit11>1</Int32Bit11>
+      <Int32Bit12>0</Int32Bit12>
+      <Int32Bit13>1</Int32Bit13>
+      <Int32Bit14>0</Int32Bit14>
+      <Int32Bit15>1</Int32Bit15>
+      <Int32Bit16>1</Int32Bit16>
+      <Int32Bit17>0</Int32Bit17>
+      <Int32Bit18>1</Int32Bit18>
+      <Int32Bit19>0</Int32Bit19>
+      <Int32Bit20>1</Int32Bit20>
+      <Int32Bit21>1</Int32Bit21>
+      <Int32Bit22>0</Int32Bit22>
+      <Int32Bit23>1</Int32Bit23>
+      <Int32Bit24>0</Int32Bit24>
+      <Int32Bit25>1</Int32Bit25>
+      <Int32Bit26>1</Int32Bit26>
+      <Int32Bit27>0</Int32Bit27>
+      <Int32Bit28>1</Int32Bit28>
+      <Int32Bit29>0</Int32Bit29>
+      <Int32Bit30>1</Int32Bit30>
+      <Int32Bit31>1</Int32Bit31>
+      <Int32Bit32>0</Int32Bit32>
+      
+      <SparseInt32Bit1>1</SparseInt32Bit1>
+      <SparseInt32Bit7>true</SparseInt32Bit7>
+      <SparseInt32Bit18>1</SparseInt32Bit18>
+      <SparseInt32Bit24>true</SparseInt32Bit24>
+      <SparseInt32Bit31>1</SparseInt32Bit31>
+      
+      <BinaryBit1>true</BinaryBit1>
+      <BinaryBit10>1</BinaryBit10>
+      <BinaryBit20>false</BinaryBit20>
+      <BinaryBit30>true</BinaryBit30>
+      <BinaryBit40>0</BinaryBit40>
+      <BinaryBit50>true</BinaryBit50>
+      <BinaryBit60>1</BinaryBit60>
+      <BinaryBit70>true</BinaryBit70>
+      <BinaryBit80>1</BinaryBit80>
+      <BinaryBit90>true</BinaryBit90>
+      <BinaryBit100>1</BinaryBit100>
+      
+      <BinaryMask2Bit1>0</BinaryMask2Bit1>
+      <BinaryMask2Bit2>0</BinaryMask2Bit2>
+      <BinaryMask2Bit3>0</BinaryMask2Bit3>
+      <BinaryMask2Bit4>0</BinaryMask2Bit4>
+      <BinaryMask2Bit5>0</BinaryMask2Bit5>
+      <BinaryMask2Bit6>0</BinaryMask2Bit6>
+      <BinaryMask2Bit7>0</BinaryMask2Bit7>
+      <BinaryMask2Bit8>0</BinaryMask2Bit8>
+      <BinaryMask2Bit9>0</BinaryMask2Bit9>
+      <BinaryMask2Bit10>0</BinaryMask2Bit10>
+      <BinaryMask2Bit11>0</BinaryMask2Bit11>
+      <BinaryMask2Bit12>0</BinaryMask2Bit12>
+      <BinaryMask2Bit13>0</BinaryMask2Bit13>
+      <BinaryMask2Bit14>0</BinaryMask2Bit14>
+      <BinaryMask2Bit15>0</BinaryMask2Bit15>
+      <BinaryMask2Bit16>1</BinaryMask2Bit16>
+      <BinaryMask2Bit17>0</BinaryMask2Bit17>
+      
+      <BinaryMask3Bit1>0</BinaryMask3Bit1>
+      <BinaryMask3Bit2>0</BinaryMask3Bit2>
+      <BinaryMask3Bit3>0</BinaryMask3Bit3>
+      <BinaryMask3Bit4>1</BinaryMask3Bit4>
+      <BinaryMask3Bit5>0</BinaryMask3Bit5>
+      <BinaryMask3Bit6>0</BinaryMask3Bit6>
+      <BinaryMask3Bit7>0</BinaryMask3Bit7>
+      <BinaryMask3Bit8>1</BinaryMask3Bit8>
+      <BinaryMask3Bit9>0</BinaryMask3Bit9>
+      <BinaryMask3Bit10>0</BinaryMask3Bit10>
+      <BinaryMask3Bit11>0</BinaryMask3Bit11>
+      <BinaryMask3Bit12>0</BinaryMask3Bit12>
+      <BinaryMask3Bit13>0</BinaryMask3Bit13>
+      <BinaryMask3Bit14>0</BinaryMask3Bit14>
+      <BinaryMask3Bit15>0</BinaryMask3Bit15>
+      <BinaryMask3Bit16>0</BinaryMask3Bit16>
+      <BinaryMask3Bit17>0</BinaryMask3Bit17>
+      
+      <BinaryMask4Bit1>0</BinaryMask4Bit1>
+      <BinaryMask4Bit2>0</BinaryMask4Bit2>
+      <BinaryMask4Bit3>0</BinaryMask4Bit3>
+      <BinaryMask4Bit4>1</BinaryMask4Bit4>
+      <BinaryMask4Bit5>0</BinaryMask4Bit5>
+      <BinaryMask4Bit6>0</BinaryMask4Bit6>
+      <BinaryMask4Bit7>0</BinaryMask4Bit7>
+      <BinaryMask4Bit8>1</BinaryMask4Bit8>
+      <BinaryMask4Bit9>0</BinaryMask4Bit9>
+      <BinaryMask4Bit10>0</BinaryMask4Bit10>
+      <BinaryMask4Bit11>0</BinaryMask4Bit11>
+      <BinaryMask4Bit12>0</BinaryMask4Bit12>
+      <BinaryMask4Bit13>0</BinaryMask4Bit13>
+      <BinaryMask4Bit14>0</BinaryMask4Bit14>
+      <BinaryMask4Bit15>0</BinaryMask4Bit15>
+      <BinaryMask4Bit16>1</BinaryMask4Bit16>
+      <BinaryMask4Bit17>1</BinaryMask4Bit17>
+      
+      <BinaryMask5Bit1>0</BinaryMask5Bit1>
+
+    </BitmaskTest>
+  </data>
+</configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/deltacenrep/project/Layer1/confml/crml_ints.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/1" name="CrmlInts" version="1">
+  <feature ref="CrmlInts" name="Settings with CRML int implementations">
+    <setting ref="IntSetting" name="Int setting" type="int"/>
+    <setting ref="SelectionSetting" name="Selection setting" type="selection">
+      <option name="Option0" value="0"/>
+      <option name="Option1" value="1"/>
+      <option name="Option2" value="2"/>
+      <option name="Option3" value="3"/>
+      <option name="Option4" value="4"/>
+    </setting>
+    <setting ref="IntSettingHex" name="Int setting (hex value)" type="int"/>
+  </feature>
+  <data>
+    <CrmlInts>
+      <IntSetting>10</IntSetting>
+      <SelectionSetting>1</SelectionSetting>
+      <IntSettingHex>0xA</IntSettingHex>
+    </CrmlInts>
+  </data>
+</configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/deltacenrep/project/Layer1/confml/crml_reals.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/1" name="CrmlReals" version="1">
+  <feature ref="CrmlReals" name="Settings with CRML real implementations">
+    <setting ref="RealSetting" name="Real setting" type="real"/>
+    <setting ref="RealSetting2" name="Real setting 2" type="real"/>
+    <setting ref="RealSetting3" name="Real setting 3" type="real"/>
+    <setting ref="SelectionSetting" name="Selection setting" type="selection">
+      <desc>A selection setting</desc>
+      <option name="Option0" value="0.5"/>
+      <option name="Option1" value="1.5"/>
+      <option name="Option2" value="2.5"/>
+      <option name="Option3" value="3.5"/>
+      <option name="Option4" value="4.5"/>
+    </setting>
+  </feature>
+  <data>
+    <CrmlReals>
+      <RealSetting>1.2345</RealSetting>
+      <RealSetting2>0.0000</RealSetting2>
+      <RealSetting3>0</RealSetting3>
+      <SelectionSetting>1.5</SelectionSetting>
+    </CrmlReals>
+  </data>
+</configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/deltacenrep/project/Layer1/confml/feature1.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/1" name="Feature 1" version="1">
+  <feature ref="Feature1" name="Feature 1">
+    <desc>Feature with all setting types</desc>
+    <setting ref="FolderSetting" name="Folder setting" type="folder">
+      <desc>A folder setting</desc>
+    </setting>
+    <setting ref="RealSetting" name="Real setting" type="real">
+      <desc>A real setting</desc>
+    </setting>
+    <setting ref="FileSetting" name="File setting" type="file">
+      <desc>A file setting</desc>
+    </setting>
+    <setting ref="IntSetting" name="Int setting" type="int">
+      <desc>An int setting</desc>
+    </setting>
+    <setting ref="StringSetting" name="String setting" type="string">
+      <desc>A string setting</desc>
+    </setting>
+    <setting ref="BooleanSetting" name="Boolean setting" type="boolean">
+      <desc>A boolean setting</desc>
+    </setting>
+    <setting ref="SelectionSetting" name="Selection setting" type="selection">
+      <desc>A selection setting</desc>
+      <option name="Option0" value="0"/>
+      <option name="Option1" value="1"/>
+      <option name="Option2" value="2"/>
+      <option name="Option3" value="3"/>
+      <option name="Option4" value="4"/>
+    </setting>
+    <setting ref="SequenceSetting" name="Sequence setting" type="sequence">
+      <desc>A sequence setting</desc>
+      <setting ref="FolderSubSetting" name="Folder sub-setting" type="folder">
+        <desc>A folder sub-setting</desc>
+      </setting>
+      <setting ref="RealSubSetting" name="Real sub-setting" type="real">
+        <desc>A real sub-setting</desc>
+      </setting>
+      <setting ref="FileSubSetting" name="File sub-setting" type="file">
+        <desc>A file sub-setting</desc>
+      </setting>
+      <setting ref="IntSubSetting" name="Int sub-setting" type="int">
+        <desc>An int sub-setting</desc>
+      </setting>
+      <setting ref="StringSubSetting" name="String sub-setting" type="string">
+        <desc>A string sub-setting</desc>
+      </setting>
+      <setting ref="BooleanSubSetting" name="Boolean sub-setting" type="boolean">
+        <desc>A boolean sub-setting</desc>
+      </setting>
+      <setting ref="SelectionSubSetting" name="Selection sub-setting" type="selection">
+        <desc>A selection sub-setting</desc>
+        <option name="Op0" value="0"/>
+        <option name="Op1" value="1"/>
+        <option name="Op2" value="2"/>
+        <option name="Op3" value="3"/>
+        <option name="Op4" value="4"/>
+      </setting>
+    </setting>
+  </feature>
+  <data>
+    <Feature1>
+      <FolderSetting>default_folder</FolderSetting>
+      <RealSetting>3.14</RealSetting>
+      <FileSetting>default_file.txt</FileSetting>
+      <IntSetting>10</IntSetting>
+      <StringSetting>default string</StringSetting>
+      <BooleanSetting>true</BooleanSetting>
+      <SelectionSetting>1</SelectionSetting>
+      <SequenceSetting template="true">
+        <FolderSubSetting>seq/default_folder</FolderSubSetting>
+        <RealSubSetting>1.0</RealSubSetting>
+        <FileSubSetting>seq/default_file.txt</FileSubSetting>
+        <IntSubSetting>1</IntSubSetting>
+        <StringSubSetting>template</StringSubSetting>
+        <BooleanSubSetting>false</BooleanSubSetting>
+        <SelectionSubSetting>0</SelectionSubSetting>
+      </SequenceSetting>
+      <SequenceSetting>
+        <FolderSubSetting>seq/def1_folder</FolderSubSetting>
+        <RealSubSetting>1.25</RealSubSetting>
+        <FileSubSetting>seq/def1_file.txt</FileSubSetting>
+        <IntSubSetting>128</IntSubSetting>
+        <StringSubSetting>def1</StringSubSetting>
+        <BooleanSubSetting>false</BooleanSubSetting>
+        <SelectionSubSetting>1</SelectionSubSetting>
+      </SequenceSetting>
+      <SequenceSetting>
+        <FolderSubSetting>seq/def2_folder</FolderSubSetting>
+        <RealSubSetting>1.5</RealSubSetting>
+        <FileSubSetting>seq/def2_file.txt</FileSubSetting>
+        <IntSubSetting>256</IntSubSetting>
+        <StringSubSetting>def2</StringSubSetting>
+        <BooleanSubSetting>false</BooleanSubSetting>
+        <SelectionSubSetting>1</SelectionSubSetting>
+      </SequenceSetting>
+    </Feature1>
+  </data>
+</configuration>
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/deltacenrep/project/Layer1/confml/feature2.confml has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/deltacenrep/project/Layer1/implml/00000001_feature1.crml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<repository xmlns="http://www.s60.com/xml/cenrep/1" uidName="Feature1_1" uidValue="0x00000001" owner="0x12341000">
+  <access type="R" capabilities="AlwaysPass"/>
+  <access type="W" capabilities="AlwaysPass"/>
+  <key ref="Feature1/IntSetting" name="Int setting" int="0x00000001" type="int" readOnly="false" backup="true">
+    <access type="R" capabilities="AlwaysPass"/>
+  </key>
+  <key ref="Feature1/RealSetting" name="Real setting" int="0x00000002" type="real" readOnly="false" backup="true">
+    <access type="W" capabilities="WriteDeviceData"/>
+  </key>
+  <key ref="Feature1/SelectionSetting" name="Selection setting" int="0x00000003" type="int" readOnly="false">
+    <access type="R" capabilities="AlwaysPass"/>
+    <access type="W" capabilities="WriteDeviceData"/>
+  </key>
+  <key ref="Feature1/BooleanSetting" name="Selection setting" int="0x00000004" type="int" readOnly="false">
+    <access type="R" capabilities="AlwaysPass"/>
+    <access type="W" capabilities="WriteDeviceData"/>
+  </key>
+  
+  <key ref="Feature1/StringSetting" name="String setting" int="0x00000005" type="string" readOnly="false">
+    <access type="R" capabilities="AlwaysPass"/>
+    <access type="W" capabilities="WriteDeviceData"/>
+  </key>
+</repository>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/deltacenrep/project/Layer1/implml/00000002_feature2.crml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<repository xmlns="http://www.s60.com/xml/cenrep/1" uidName="Feature2" uidValue="0x00000002" owner="0xABCD0000">
+  <access type="R" capabilities="AlwaysPass"/>
+  <access type="W" capabilities="AlwaysPass"/>
+  
+  <keyRange ref="Feature2/SequenceSetting" name="Sequence setting"
+    firstInt="0x01000000" lastInt="0x01ffffff"
+	countInt="0x01000001" indexBits="0x00ff0000" firstIndex="2">
+    <access type="R" capabilities="AlwaysPass"/>
+	<access type="W" capabilities="WriteDeviceData"/>
+	<key int="0x00000001" type="int" ref="IntSubSetting"/>
+	<key int="0x00000002" type="string" ref="StringSubSetting"/>
+  </keyRange>
+  
+  <key ref="Feature2/IntSetting" name="Int setting" int="0x00000003" type="int" readOnly="false">
+    <access type="R" capabilities="AlwaysPass"/>
+    <access type="W" capabilities="WriteDeviceData"/>
+  </key>
+</repository>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/deltacenrep/project/Layer1/implml/00000003_bitmask_test.crml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,153 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<repository xmlns="http://www.s60.com/xml/cenrep/1" uidName="BitmaskTest" uidValue="0x00000003">
+  <access type="R" capabilities="AlwaysPass"/>
+  <access type="W" capabilities="AlwaysPass"/>
+
+  <key name="Bitmask" type="int" int="0x00000001" readOnly="true">
+    <access type="R" capabilities="AlwaysPass"/>
+    <bit ref="BitmaskTest/Bit0">1</bit>
+    <bit ref="BitmaskTest/Bit1">2</bit>
+    <bit ref="BitmaskTest/Bit2">3</bit>
+    <bit ref="BitmaskTest/Bit3">4</bit>
+    <bit ref="BitmaskTest/Bit4">5</bit>
+    <bit ref="BitmaskTest/Bit5">6</bit>
+  </key>
+  
+  <!--
+  This doesn't work in CT2, so not used in ConE plug-in tests for now
+  
+  <key name="InvertedMask" type="int" int="0x00000002" readOnly="true">
+    <bit ref="BitmaskTest/InvertedMaskBit1" value="false">1</bit>
+    <bit ref="BitmaskTest/InvertedMaskBit2" value="false">2</bit>
+    <bit ref="BitmaskTest/InvertedMaskBit3" value="false">3</bit>
+    <bit ref="BitmaskTest/InvertedMaskBit4" value="false">4</bit>
+  </key>
+  -->
+
+  <key name="Int32Mask" type="int" int="0x00000003" readOnly="true">
+    <bit ref="BitmaskTest/Int32Bit1">1</bit>
+    <bit ref="BitmaskTest/Int32Bit2">2</bit>
+    <bit ref="BitmaskTest/Int32Bit3">3</bit>
+    <bit ref="BitmaskTest/Int32Bit4">4</bit>
+    <bit ref="BitmaskTest/Int32Bit5">5</bit>
+    <bit ref="BitmaskTest/Int32Bit6">6</bit>
+    <bit ref="BitmaskTest/Int32Bit7">7</bit>
+    <bit ref="BitmaskTest/Int32Bit8">8</bit>
+    <bit ref="BitmaskTest/Int32Bit9">9</bit>
+    <bit ref="BitmaskTest/Int32Bit10">10</bit>
+    <bit ref="BitmaskTest/Int32Bit11">11</bit>
+    <bit ref="BitmaskTest/Int32Bit12">12</bit>
+    <bit ref="BitmaskTest/Int32Bit13">13</bit>
+    <bit ref="BitmaskTest/Int32Bit14">14</bit>
+    <bit ref="BitmaskTest/Int32Bit15">15</bit>
+    <bit ref="BitmaskTest/Int32Bit16">16</bit>
+    <bit ref="BitmaskTest/Int32Bit17">17</bit>
+    <bit ref="BitmaskTest/Int32Bit18">18</bit>
+    <bit ref="BitmaskTest/Int32Bit19">19</bit>
+    <bit ref="BitmaskTest/Int32Bit20">20</bit>
+    <bit ref="BitmaskTest/Int32Bit21">21</bit>
+    <bit ref="BitmaskTest/Int32Bit22">22</bit>
+    <bit ref="BitmaskTest/Int32Bit23">23</bit>
+    <bit ref="BitmaskTest/Int32Bit24">24</bit>
+    <bit ref="BitmaskTest/Int32Bit25">25</bit>
+    <bit ref="BitmaskTest/Int32Bit26">26</bit>
+    <bit ref="BitmaskTest/Int32Bit27">27</bit>
+    <bit ref="BitmaskTest/Int32Bit28">28</bit>
+    <bit ref="BitmaskTest/Int32Bit29">29</bit>
+    <bit ref="BitmaskTest/Int32Bit30">30</bit>
+    <bit ref="BitmaskTest/Int32Bit31">31</bit>
+    <bit ref="BitmaskTest/Int32Bit32">32</bit>
+  </key>
+  
+  
+  <key name="SparseInt32Bitmask" type="int" int="0x00000004" readOnly="true">
+    <bit ref="BitmaskTest/SparseInt32Bit1">1</bit>
+    <bit ref="BitmaskTest/SparseInt32Bit7">7</bit>
+    <bit ref="BitmaskTest/SparseInt32Bit18">18</bit>
+    <bit ref="BitmaskTest/SparseInt32Bit24">24</bit>
+    <bit ref="BitmaskTest/SparseInt32Bit31">31</bit>
+  </key>
+  
+  <!--
+  This doesn't work in CT2, so not used in ConE plug-in tests for now
+  
+  <key name="BinaryMask" type="binary" int="0x00000005" readOnly="true">
+    <bit ref="BitmaskTest/BinaryBit1">1</bit>
+    <bit ref="BitmaskTest/BinaryBit10">10</bit>
+    <bit ref="BitmaskTest/BinaryBit20">20</bit>
+    <bit ref="BitmaskTest/BinaryBit30">30</bit>
+    <bit ref="BitmaskTest/BinaryBit40">40</bit>
+    <bit ref="BitmaskTest/BinaryBit50">50</bit>
+    <bit ref="BitmaskTest/BinaryBit60">60</bit>
+    <bit ref="BitmaskTest/BinaryBit70">70</bit>
+    <bit ref="BitmaskTest/BinaryBit80">80</bit>
+    <bit ref="BitmaskTest/BinaryBit90">90</bit>
+    <bit ref="BitmaskTest/BinaryBit100">100</bit>
+  </key>
+  -->
+  
+  <key name="BinaryMask2" type="binary" int="0x06000000" readOnly="true">
+    <bit ref="BitmaskTest/BinaryMask2Bit1">1</bit>
+    <bit ref="BitmaskTest/BinaryMask2Bit2">2</bit>
+    <bit ref="BitmaskTest/BinaryMask2Bit3">3</bit>
+    <bit ref="BitmaskTest/BinaryMask2Bit4">4</bit>
+    <bit ref="BitmaskTest/BinaryMask2Bit5">5</bit>
+    <bit ref="BitmaskTest/BinaryMask2Bit6">6</bit>
+    <bit ref="BitmaskTest/BinaryMask2Bit7">7</bit>
+    <bit ref="BitmaskTest/BinaryMask2Bit8">8</bit>
+    <bit ref="BitmaskTest/BinaryMask2Bit9">9</bit>
+    <bit ref="BitmaskTest/BinaryMask2Bit10">10</bit>
+    <bit ref="BitmaskTest/BinaryMask2Bit11">11</bit>
+    <bit ref="BitmaskTest/BinaryMask2Bit12">12</bit>
+    <bit ref="BitmaskTest/BinaryMask2Bit13">13</bit>
+    <bit ref="BitmaskTest/BinaryMask2Bit14">14</bit>
+    <bit ref="BitmaskTest/BinaryMask2Bit15">15</bit>
+    <bit ref="BitmaskTest/BinaryMask2Bit16">16</bit>
+    <bit ref="BitmaskTest/BinaryMask2Bit17">17</bit>
+  </key>
+  
+  <key name="BinaryMask3" type="binary" int="0x07000000" readOnly="true">
+    <bit ref="BitmaskTest/BinaryMask3Bit1">1</bit>
+    <bit ref="BitmaskTest/BinaryMask3Bit2">2</bit>
+    <bit ref="BitmaskTest/BinaryMask3Bit3">3</bit>
+    <bit ref="BitmaskTest/BinaryMask3Bit4">4</bit>
+    <bit ref="BitmaskTest/BinaryMask3Bit5">5</bit>
+    <bit ref="BitmaskTest/BinaryMask3Bit6">6</bit>
+    <bit ref="BitmaskTest/BinaryMask3Bit7">7</bit>
+    <bit ref="BitmaskTest/BinaryMask3Bit8">8</bit>
+    <bit ref="BitmaskTest/BinaryMask3Bit9">9</bit>
+    <bit ref="BitmaskTest/BinaryMask3Bit10">10</bit>
+    <bit ref="BitmaskTest/BinaryMask3Bit11">11</bit>
+    <bit ref="BitmaskTest/BinaryMask3Bit12">12</bit>
+    <bit ref="BitmaskTest/BinaryMask3Bit13">13</bit>
+    <bit ref="BitmaskTest/BinaryMask3Bit14">14</bit>
+    <bit ref="BitmaskTest/BinaryMask3Bit15">15</bit>
+    <bit ref="BitmaskTest/BinaryMask3Bit16">16</bit>
+    <bit ref="BitmaskTest/BinaryMask3Bit17">17</bit>
+  </key>
+  
+  <key name="BinaryMask4" type="binary" int="0x08000000" readOnly="true">
+    <bit ref="BitmaskTest/BinaryMask4Bit1">1</bit>
+    <bit ref="BitmaskTest/BinaryMask4Bit2">2</bit>
+    <bit ref="BitmaskTest/BinaryMask4Bit3">3</bit>
+    <bit ref="BitmaskTest/BinaryMask4Bit4">4</bit>
+    <bit ref="BitmaskTest/BinaryMask4Bit5">5</bit>
+    <bit ref="BitmaskTest/BinaryMask4Bit6">6</bit>
+    <bit ref="BitmaskTest/BinaryMask4Bit7">7</bit>
+    <bit ref="BitmaskTest/BinaryMask4Bit8">8</bit>
+    <bit ref="BitmaskTest/BinaryMask4Bit9">9</bit>
+    <bit ref="BitmaskTest/BinaryMask4Bit10">10</bit>
+    <bit ref="BitmaskTest/BinaryMask4Bit11">11</bit>
+    <bit ref="BitmaskTest/BinaryMask4Bit12">12</bit>
+    <bit ref="BitmaskTest/BinaryMask4Bit13">13</bit>
+    <bit ref="BitmaskTest/BinaryMask4Bit14">14</bit>
+    <bit ref="BitmaskTest/BinaryMask4Bit15">15</bit>
+    <bit ref="BitmaskTest/BinaryMask4Bit16">16</bit>
+    <bit ref="BitmaskTest/BinaryMask4Bit17">17</bit>
+  </key>
+  
+  <key name="BinaryMask5" type="binary" int="0x09000000" readOnly="true">
+    <bit ref="BitmaskTest/BinaryMask5Bit1">1</bit>
+  </key>
+  
+</repository>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/deltacenrep/project/Layer1/implml/00000005_crml_ints.crml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<repository xmlns="http://www.s60.com/xml/cenrep/1" uidName="CrmlInts" uidValue="0x00000005" owner="0x12341000">
+  <access type="R" capabilities="AlwaysPass"/>
+  <access type="W" capabilities="AlwaysPass"/>
+  <key ref="CrmlInts/IntSetting" name="Int setting" int="0x00000001" type="int" readOnly="false" backup="true"/>
+  <key ref="CrmlInts/SelectionSetting" name="Selection setting" int="0x00000002" type="int" readOnly="false"/>
+  <key ref="CrmlInts/IntSettingHex" name="Int setting hex" int="0x00000003" type="int" readOnly="false"/>
+</repository>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/deltacenrep/project/Layer1/implml/00000006_crml_reals.crml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<repository xmlns="http://www.s60.com/xml/cenrep/1" uidName="CrmlReals" uidValue="0x00000006" owner="0x12341000">
+  <access type="R" capabilities="AlwaysPass"/>
+  <access type="W" capabilities="AlwaysPass"/>
+  <key ref="CrmlReals/RealSetting" name="Real setting" int="0x00000001" type="real" readOnly="false" backup="true"/>
+  <key ref="CrmlReals/SelectionSetting" name="Selection setting" int="0x00000002" type="real" readOnly="false"/>
+  <key ref="CrmlReals/RealSetting2" name="Real setting 2" int="0x00000003" type="real" readOnly="false" backup="true"/>
+  <key ref="CrmlReals/RealSetting3" name="Real setting 3" int="0x00000004" type="real" readOnly="false" backup="true"/>
+</repository>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/deltacenrep/project/Layer1/implml/deltacenrep_iby.implml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<container xmlns="http://www.symbianfoundation.org/xml/implml/1">
+    <tag name="crml" value="deltacenrep"/>
+    <tag name="target" value="rofs2"/>
+    <tag name="target" value="rofs3"/>
+    <phase name="post"/>
+    <settingRefsOverride refsIrrelevant="true"/>
+    
+    <templateml xmlns="http://www.s60.com/xml/templateml/1">
+        <output dir="include" file="deltacenreps.iby" encoding="UTF-8">
+<template>
+#ifndef __DELTA_CENREPS_IBY
+#define __DELTA_CENREPS_IBY
+
+{% for output in gen_context.get_output(implml_type='crml') -%}
+data = {{output.abspath}}			private\10202BE9\{{output.filename}} exattrib=U
+{% endfor %}
+
+#endif // __DELTA_CENREPS_IBY
+</template>
+        </output>
+    </templateml>
+</container>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/deltacenrep/project/Layer1/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<confml:configuration xmlns:confml="http://www.s60.com/xml/confml/1" xmlns:xi="http://www.w3.org/2001/XInclude" name="Layer 1">
+  <xi:include href="confml/bitmask_test.confml#/"/>
+  <xi:include href="confml/feature1.confml#/"/>
+  <xi:include href="confml/feature2.confml#/"/>
+  <xi:include href="confml/crml_ints.confml#/"/>
+  <xi:include href="confml/crml_reals.confml#/"/>
+</confml:configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/deltacenrep/project/Layer2/confml/data.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/1" name="data" version="1">
+    <data>
+        <CrmlInts>
+            <IntSetting>50</IntSetting>
+            <IntSettingHex>0xB</IntSettingHex>
+        </CrmlInts>
+        <CrmlReals>
+            <RealSetting>50.5</RealSetting>
+            <RealSetting3>11.1</RealSetting3>
+        </CrmlReals>
+        
+        <Feature2>
+            <SequenceSetting>
+                <IntSubSetting>1001</IntSubSetting>
+                <StringSubSetting>test 1</StringSubSetting>
+            </SequenceSetting>
+            <SequenceSetting>
+                <IntSubSetting>1002</IntSubSetting>
+                <StringSubSetting>test 2</StringSubSetting>
+            </SequenceSetting>
+        </Feature2>
+        <BitmaskTest>
+            <Int32Bit5>true</Int32Bit5>
+            <Int32Bit6>true</Int32Bit6>
+        </BitmaskTest>
+    </data>
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/deltacenrep/project/Layer2/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<confml:configuration xmlns:confml="http://www.s60.com/xml/confml/1" xmlns:xi="http://www.w3.org/2001/XInclude" name="Layer 1">
+  <xi:include href="confml/data.confml#/"/>
+</confml:configuration>
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/deltacenrep/project/root.confml has changed
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_last_layer/content/animations/anim1.mbm has changed
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_last_layer/content/animations/anim2.mif has changed
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_last_layer/content/data/sequence_setting_test.txt has changed
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_last_layer/content/data/sounds/test.mp3 has changed
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_last_layer/content/private/10202BE9/10000000.txt has changed
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_last_layer/content/private/10202BE9/12341001.txt has changed
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_last_layer/content/private/10202BE9/12341002.txt has changed
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_last_layer/content/private/10202BE9/20000000.txt has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_last_layer/content/private/10207114/import/12340001/themepackage.mbm	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,1 @@
+xyz
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_last_layer/content/private/10207114/import/12340001/themepackage.mif	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,1 @@
+zyx
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_last_layer/content/private/10207114/import/12340001/themepackage.skn	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,1 @@
+foo
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_last_layer/content/private/10207114/import/12340002/themepackage.mbm	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,1 @@
+xyz
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_last_layer/content/private/10207114/import/12340002/themepackage.mif	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,1 @@
+zyx
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_last_layer/content/private/10207114/import/12340002/themepackage.skn	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,1 @@
+foo
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_last_layer/content/resource/skins/12340001/themepackage.mbm	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,1 @@
+xyz
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_last_layer/content/resource/skins/12340001/themepackage.mif	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,1 @@
+zyx
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_last_layer/content/resource/skins/12340002/themepackage.mbm	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,1 @@
+xyz
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_last_layer/content/resource/skins/12340002/themepackage.mif	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,1 @@
+zyx
\ No newline at end of file
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_last_layer/content/sound_folder/test2.mp3 has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_last_layer/hcr_test.h	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,12 @@
+#ifndef HCR_TEST_H
+#define HCR_TEST_H
+
+#include <hcr.h>
+
+const HCR::TCategoryUid KTestCategory = 0xABCDDCBA;
+
+const HCR::TElementId KInt32Setting = 0x00000000;
+const HCR::TElementId KBoolSetting  = 0x00000001;
+const HCR::TElementId KTextSetting  = 0x00000002;
+
+#endif
\ No newline at end of file
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_rofs2/content/data/sequence_setting_test.txt has changed
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_rofs2/content/private/100059C9/cenrep_rfs.txt has changed
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_rofs2/content/private/10202BE9/10000000.txt has changed
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_rofs2/content/private/10202BE9/12341000.txt has changed
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_rofs2/content/private/10202BE9/12341001.txt has changed
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_rofs2/content/private/10202BE9/12341002.txt has changed
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_rofs2/content/private/10202BE9/12341003.txt has changed
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_rofs2/content/private/10202BE9/20000000.txt has changed
Binary file configurationengine/source/plugins/symbian/integration-test/testdata/generate/expected_rofs2/content/private/10202BE9/ABCD0000.txt has changed
--- a/configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/custom/implml/configure_bitmask.ruleml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/custom/implml/configure_bitmask.ruleml	Tue Aug 10 14:29:28 2010 +0300
@@ -1,12 +1,12 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<ruleml xmlns="http://www.s60.com/xml/ruleml/1">
+<ruleml xmlns="http://www.s60.com/xml/ruleml/3">
 <rule>
-CustomConfSettings.ConfigureBitmask configures
-  BitmaskTest.Bit0 = '0' and
-  BitmaskTest.Bit1 = '1' and
-  BitmaskTest.Bit2 = '0' and
-  BitmaskTest.Bit3 = '1' and
-  BitmaskTest.Bit4 = '0' and
-  BitmaskTest.Bit5 = '1'
+${CustomConfSettings.ConfigureBitmask} configures
+  ${BitmaskTest.Bit0} = '0' and
+  ${BitmaskTest.Bit1} = '1' and
+  ${BitmaskTest.Bit2} = '0' and
+  ${BitmaskTest.Bit3} = '1' and
+  ${BitmaskTest.Bit4} = '0' and
+  ${BitmaskTest.Bit5} = '1'
 </rule>
 </ruleml>
\ No newline at end of file
--- a/configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/custom/implml/sound.implml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/custom/implml/sound.implml	Tue Aug 10 14:29:28 2010 +0300
@@ -3,8 +3,8 @@
     
     <container>
         <phase name="pre"/>
-        <ruleml xmlns="http://www.s60.com/xml/ruleml/1">
-            <rule>CustomConfSettings.SoundFile.localPath configures SoundFileTest.SoundFilePath = SoundFileTest.SoundFilePath filenamejoin CustomConfSettings.SoundFile.localPath</rule>
+        <ruleml xmlns="http://www.s60.com/xml/ruleml/3">
+            <rule>${CustomConfSettings.SoundFile.localPath} configures ${SoundFileTest.SoundFilePath} = ${SoundFileTest.SoundFilePath} filenamejoin ${CustomConfSettings.SoundFile.localPath}</rule>
         </ruleml>
     </container>
     
--- a/configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/custom/implml/unicode_rule_test.ruleml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/integration-test/testdata/generate/project/custom/implml/unicode_rule_test.ruleml	Tue Aug 10 14:29:28 2010 +0300
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<ruleml xmlns="http://www.s60.com/xml/ruleml/1">
-  <rule>True configures Feature1.StringSetting = Feature1.StringSetting + " " + BasicSettingTypesTest.StringSetting + u" カタカナ"</rule>
+<ruleml xmlns="http://www.s60.com/xml/ruleml/3">
+  <rule>True configures ${Feature1.StringSetting} = ${Feature1.StringSetting} + " " + ${BasicSettingTypesTest.StringSetting} + u" カタカナ"</rule>
 </ruleml>
\ No newline at end of file
--- a/configurationengine/source/plugins/symbian/integration-test/unittest_crml_dc.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/integration-test/unittest_crml_dc.py	Tue Aug 10 14:29:28 2010 +0300
@@ -18,7 +18,7 @@
 # @author Teemu Rytkonen
 
 import sys, os, shutil, unittest
-import __init__
+
 from testautomation.base_testcase import BaseTestCase
 
 ROOT_PATH = os.path.abspath(os.path.dirname(__file__))
@@ -27,7 +27,7 @@
 if sys.platform == "win32":
     CONE_SCRIPT = "cone.cmd"
 else:
-    CONE_SCRIPT = "cone.sh"
+    CONE_SCRIPT = "cone"
 
 def get_cmd(action='compare'):
     """Return the command used to run the ConE sub-action"""
--- a/configurationengine/source/plugins/symbian/integration-test/unittest_generate.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/integration-test/unittest_generate.py	Tue Aug 10 14:29:28 2010 +0300
@@ -16,7 +16,7 @@
 #
 
 import sys, os, shutil, unittest
-import __init__
+
 from testautomation.base_testcase import BaseTestCase
 from testautomation import zip_dir
 
@@ -25,7 +25,7 @@
 if sys.platform == "win32":
     CONE_SCRIPT = "cone.cmd"
 else:
-    CONE_SCRIPT = "cone.sh"
+    CONE_SCRIPT = "cone"
 
 def get_cmd(action='generate'):
     """Return the command used to run the ConE sub-action"""
@@ -71,7 +71,21 @@
     def test_generate_all_impls_on_last_layer_on_file_storage(self):
         project_dir = os.path.join(ROOT_PATH, "testdata/generate/project")
         self.assert_exists_and_contains_something(project_dir)
-        self._run_test_generate_all_impls_on_last_layer('temp/gen_ll1', project_dir)
+        self._run_test_generate_all_impls_on_last_layer(
+            workdir = 'temp/gen_ll1',
+            project = project_dir,
+            expected = os.path.join(ROOT_PATH, 'testdata/generate/expected_last_layer'),
+            args = '--layer -1',
+            linux_ignores = ['anim1.mbm', 'anim2.mif', '20000000.txt', '10207114',  'themepackage.mbm', 'themepackage.mif', '12340001', '12340002'])
+    
+    def test_generate_all_impls_target_rofs2_file_storage(self):
+        project_dir = os.path.join(ROOT_PATH, "testdata/generate/project")
+        self.assert_exists_and_contains_something(project_dir)
+        self._run_test_generate_all_impls_on_last_layer(
+            workdir = 'temp/gen_ll_rofs2',
+            project = project_dir,
+            expected = os.path.join(ROOT_PATH, 'testdata/generate/expected_rofs2'),
+            args = '--all-layers --impl-tag target:rofs2')
     
     def test_generate_all_impls_on_last_layer_on_zip_storage(self):
         project_dir = os.path.join(ROOT_PATH, "testdata/generate/project")
@@ -82,9 +96,14 @@
         zip_dir.zip_dir(project_dir, project_zip, [zip_dir.SVN_IGNORE_PATTERN])
         self.assert_exists_and_contains_something(project_zip)
         
-        self._run_test_generate_all_impls_on_last_layer('temp/gen_ll2', project_zip)
+        self._run_test_generate_all_impls_on_last_layer(
+            workdir = 'temp/gen_ll2',
+            project = project_zip,
+            expected = os.path.join(ROOT_PATH, 'testdata/generate/expected_last_layer'),
+            args = '--layer -1',
+            linux_ignores = ['anim1.mbm', 'anim2.mif', '20000000.txt', '10207114', 'themepackage.mbm', 'themepackage.mif', '12340001', '12340002' ])
     
-    def _run_test_generate_all_impls_on_last_layer(self, workdir, project):
+    def _run_test_generate_all_impls_on_last_layer(self, workdir, project, expected, args='', linux_ignores=[]):
         # Create a temp workdir and go there to run the test
         orig_workdir = os.getcwd()
         workdir = self._prepare_workdir(workdir)
@@ -92,62 +111,57 @@
         
         try:
             # Run the generation command
-            cmd = '%s -p "%s" --output output --layer -1 --add-setting-file imaker_variantdir.cfg' % (get_cmd(), project)
+            cmd = '%s -p "%s" --output output --add-setting-file imaker_variantdir.cfg %s' % (get_cmd(), project, args)
             self.run_command(cmd)
             
-            # Check that all expected output files are generated
-            def check(path):
-                self.assert_exists_and_contains_something("output/" + path)
-            
-            try:
-                check("content/animations/anim1.mbm")
-                check("content/animations/anim2.mif")
-            except AssertionError:
-                if ' ' in ROOT_PATH:
-                    self.fail("Known bug (#177)")
-                else:
-                    raise
-            
-            check("content/data/sounds/test.mp3")
-            check("content/data/sequence_setting_test.txt")
-            check("content/private/10202BE9/10000000.txt")
-            check("content/private/10202BE9/12341001.txt")
-            check("content/private/10202BE9/12341002.txt")
-            check("content/private/10202BE9/20000000.txt")
-            check("content/sound_folder/test2.mp3")
-            check("hcr_test.h")
-            check("content/private/10207114/import/12340001/themepackage.mbm")
-            check("content/private/10207114/import/12340001/themepackage.mif")
-            check("content/private/10207114/import/12340001/themepackage.skn")
+            self.assert_dir_contents_equal('output', expected, ['.svn'] + linux_ignores)
+        finally:
+            os.chdir(orig_workdir)
+
+class TestDeltaCenrepGeneration(BaseTestCase):
+    
+    def test_generate_deltacenreps(self):
+        self._run_test_generation(
+            workdir      = 'temp/deltacenrep/deltacenrep',
+            expected_dir = 'testdata/deltacenrep/deltacenrep_expected',
+            tag_args     = '--impl-tag target:rofs3 --impl-tag crml:deltacenrep')
+    
+    def test_generate_normal_cenreps_from_deltacenrep_project(self):
+        self._run_test_generation(
+            workdir      = 'temp/deltacenrep/normalcenrep',
+            expected_dir = 'testdata/deltacenrep/normalcenrep_expected',
+            tag_args     = '--impl-tag target:rofs3')
+    
+    def _run_test_generation(self, workdir, expected_dir, tag_args):
+        PROJECT_DIR = os.path.join(ROOT_PATH, 'testdata/deltacenrep/project')
+        EXPECTED_DIR = os.path.join(ROOT_PATH, expected_dir)
+        
+        # Create a temp workdir and go there to run the test
+        orig_workdir = os.getcwd()
+        workdir = os.path.join(ROOT_PATH, workdir)
+        self.recreate_dir(workdir)
+        os.chdir(workdir)
+        
+        try:
+            # Run the generation command
+            cmd = '%(cmd)s -p "%(project)s" --output output --layer -1 '\
+                  '--add-setting-file imaker_variantdir.cfg %(args)s'\
+                  % {'cmd'      : get_cmd(),
+                     'project'  : PROJECT_DIR,
+                     'args'     : tag_args}
+            self.run_command(cmd)
+            OUTPUT_DIR = os.path.abspath('output')
             
-            # Check that files that should not have been generated are not
-            def check_not_gen(path):
-                self.assertFalse(os.path.exists("output/" + path),
-                                 "'%s' was generated when it should not have been!" % path)
-            check_not_gen("content/private/10202BE9/ABCD0000.txt")
-            check_not_gen("content/private/10202BE9/12341000.txt")
+            # Assert that the CenRep files are equal
+            self.assert_dir_contents_equal(OUTPUT_DIR, EXPECTED_DIR, ignore=['.svn', 'include'])
             
-            # Check that the data has been generated correctly
-            self.assert_file_contains(
-                "output/content/private/10202BE9/12341002.txt",
-                "0x1 int 42 0 cap_rd=alwayspass cap_wr=WriteDeviceData",
-                encoding='utf-16')
-            self.assert_file_contains(
-                "output/content/private/10202BE9/10000000.txt",
-                r'0x1 string "Z:\\data\\sounds\\test.mp3" 0 cap_rd=alwayspass cap_wr=WriteDeviceData',
-                encoding='utf-16')
-            self.assert_file_contains(
-                "output/content/private/10202BE9/12341001.txt",
-                u'0x1 string "default string カタカナ <&> カタカナ" 0 cap_rd=alwayspass cap_wr=WriteDeviceData',
-                encoding='utf-16')
-            self.assert_file_contains(
-                "output/content/private/10202BE9/20000000.txt",
-                ['0x11 string "305397761" 0',
-                 '0x12 string "305397761" 0',
-                 '0x13 string "305397761" 0',
-                 '0x21 string "305397762" 0',
-                 '0x22 string "305397762" 0'],
-                encoding='utf-16')
+            # If generating delta CenReps, check also the iby file
+            OUTPUT_IBY = os.path.join(OUTPUT_DIR, 'include/deltacenreps.iby')
+            EXPECTED_IBY = os.path.join(EXPECTED_DIR, 'include/deltacenreps.iby')
+            if os.path.exists(EXPECTED_IBY):
+                self.assert_file_contents_equal(OUTPUT_IBY, EXPECTED_IBY,
+                    ignore_patterns = [r'(\w:)?[\\/].*output[\\/]deltacenreps[\\/]'],
+                    ignore_endline_style = True)
         finally:
             os.chdir(orig_workdir)
 
--- a/configurationengine/source/plugins/symbian/runtests.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/plugins/symbian/runtests.py	Tue Aug 10 14:29:28 2010 +0300
@@ -14,19 +14,6 @@
 # Description:
 #
 
-import sys, os, re, unittest
-
-ROOT_PATH = os.path.abspath(os.path.dirname(__file__))
-
-PLUGINS_ROOT = os.path.normpath(os.path.join(ROOT_PATH, '..'))
-assert os.path.split(PLUGINS_ROOT)[1] == 'plugins'
-if PLUGINS_ROOT not in sys.path: sys.path.append(PLUGINS_ROOT)
-import plugin_utils
-
-if __name__ == "__main__":
-    # Collect a list of plug-in source paths and plug-in module names
-    paths_and_modnames = plugin_utils.find_plugin_sources(ROOT_PATH)
-    # Create a test suite from them
-    suite = plugin_utils.collect_suite_from_source_list(paths_and_modnames)
-    # Run the suite
-    unittest.TextTestRunner(verbosity=2).run(suite)
+if __name__ == '__main__':
+    import nose
+    nose.core.run(argv=['collector','--include=unittest', '--verbosity=3'])
\ No newline at end of file
--- a/configurationengine/source/runtests.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/runtests.py	Tue Aug 10 14:29:28 2010 +0300
@@ -15,144 +15,16 @@
 # Script for running all ConE unit tests (cone, plug-ins and scripts).
 #
 
-import os, sys, re, imp
-import unittest
-
-# Path to the directory where this file is located
-ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
-
-# For module 'testautomation'
-sys.path.append(os.path.join(ROOT_PATH, 'testautomation'))
-
-from testautomation import testcli
-import cone
-import cone.public.plugin
-
-def _load_module(path):
-    if not path.endswith('.py'):
-        raise ValueError("Given parameter ('%s') is not a .py file" % path)
-    
-    dir = os.path.dirname(path)
-    sys.path.insert(0, dir)
-    try:
-        modname = path.replace('.', '_')
-        return imp.load_source(modname, path)
-    finally:
-        del sys.path[0]
-        # Since the module name __init__ is needed in many places,
-        # but its contents may differ, remove it from sys.modules
-        # in order to force reloading every time
-        if '__init__' in sys.modules:
-            del sys.modules['__init__']
-
-def _collect_unittest_suite_from_file(file_path):
-    suite = unittest.TestSuite()
-    module = _load_module(file_path)
-    suite.addTests(unittest.TestLoader().loadTestsFromModule(module))
-    return suite
-
-
-def _find_unittest_files(path, recursive=True):
-    """
-    Find all unittest_*.py files under the given directory.
-    """
-    pattern = re.compile(r'^unittest_.*\.py$')
-    unittest_files = []
-    if recursive:
-        for root, dirs, files in os.walk(path, topdown=True):
-            for filename in files:
-                if pattern.match(filename) != None:
-                    filepath = os.path.abspath(os.path.join(root, filename))
-                    unittest_files.append(filepath)
-    else:
-        for filename in os.listdir(path):
-            if pattern.match(filename) != None:
-                filepath = os.path.abspath(os.path.join(path, filename))
-                unittest_files.append(filepath)
-    
-    return unittest_files
-
-def _collect_unittest_suite_from_path(path, recursive=True):
-    """
-    Collect a test suite containing all test cases loaded from
-    unittest_*.py files in the given directory.
-    """
-    path = os.path.abspath(path)
-    
-    # Collect the list of .py files containing unit tests
-    unittest_files = _find_unittest_files(path, recursive)
-    
-    # Load the files as modules and load tests from them
-    suite = unittest.TestSuite()
-    for file in unittest_files:
-        module = _load_module(file)
-        suite.addTests(unittest.TestLoader().loadTestsFromModule(module))
-    return suite
-
-def _collect_suite():
-    def get_suite(path):
-        return _collect_unittest_suite_from_path(os.path.join(ROOT_PATH, path))
-    def get_suite_from_file(file_path):
-        return _collect_unittest_suite_from_file(os.path.join(ROOT_PATH, file_path))
-    
-    suite = unittest.TestSuite()
-    suite.addTests(get_suite('cone'))
-    suite.addTests(get_suite('scripts/tests'))
-    suite.addTests(get_suite('plugins'))
-    suite.addTests(get_suite('testautomation'))
-    
-    # Tests can also be loaded from a file:
-    #suite.addTests(get_suite_from_file('cone/public/tests/unittest_rules_on_configuration.py'))
-    
-    
-    # Force-reload all ConE plug-in reader classes, since the __init__.py
-    # files in the imported test cases have added plug-in sources to sys.path
-    cone.public.plugin.ImplFactory.force_reload_reader_classes()
-    
-    return suite
-
-def _run_without_nose():
-    suite = _collect_suite()
-    unittest.TextTestRunner(verbosity=2).run(suite)
-
-def _run_with_nose():
-    # Call plugin_utils.init_all() so that all plug-ins are loaded
-    # (otherwise script tests, plug-in unit tests and plug-in integration
-    # tests would not work)
-    PLUGIN_SOURCE_ROOT = os.path.normpath(os.path.join(ROOT_PATH, 'plugins'))
-    assert os.path.isdir(PLUGIN_SOURCE_ROOT)
-    sys.path.append(PLUGIN_SOURCE_ROOT)
-    import plugin_utils
-    plugin_utils.init_all()
-    
-    # Find all unittest_*.py files
-    test_files = []
-    def add_tests(path):
-        test_files.extend(_find_unittest_files(os.path.join(ROOT_PATH, path)))
-    add_tests('cone')
-    add_tests('scripts/tests')
-    add_tests('plugins')
-    add_tests('testautomation')
-    
-    
-    # Configure nose
+if __name__ == '__main__':
     import nose
-    plugins = nose.plugins.manager.DefaultPluginManager()
-    conf = nose.config.Config(plugins=plugins, testNames=test_files)
-    
-    # Run the tests
-    args = ['--verbosity=3',
-            '--with-xunit',
-            '--xunit-file=cone-alltests.xml',
-            #'--collect-only',
-            ]
-    nose.run(config=conf, argv=[sys.argv[0]] + args)
-
-def main():
-    if '--with-nose' in sys.argv:
-        _run_with_nose()
-    else:
-        _run_without_nose()
-
-if __name__ == '__main__':
-    main()
+    nose.run(argv=['collector',
+                    'cone',
+                    'scripts',
+                    'plugins/common',
+                    'plugins/example',
+                    'plugins/symbian',
+                    'testautomation/testautomation',
+                    '--include=unittest', 
+                    '--with-xunit',
+                    '--xunit-file=cone-alltests.xml',
+                    '--verbosity=3'])
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/__init__.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,18 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+
+
--- a/configurationengine/source/scripts/compare_api_report_template.html	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/compare_api_report_template.html	Tue Aug 10 14:29:28 2010 +0300
@@ -8,7 +8,7 @@
                        'desc':'Description',
                        } %}
     
-    <table class="report">
+    <table class="report" id="report_data">
     <tr>
         <th class="featureName" colspan="{{ columns|length }}">{{ data.sourcedata.name }}</th>
         <th class="featureName">&nbsp;</th>
@@ -89,4 +89,9 @@
     
     
     </table>
+    <script language="javascript" type="text/javascript">
+//<![CDATA[
+    setFilterGrid("report_data");
+//]]>
+</script>
 {% endblock %}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/compare_ci_report_template.html	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,76 @@
+{% extends "cone_base.html" %}
+{% block title %}Compare API{% endblock %}
+{% block content %}
+    <h1>Configuration API compare</h1><br>
+    {% set columns = {
+                       'type':'Type',
+                       'options':'Option',
+                       } %}
+    
+    <table class="report" id="report_data">
+    <tr>
+        <th class="featureName">Reference</th>
+        <th class="featureName">Source confml</th>
+        <th class="featureName">Target confml</th>
+        <th class="featureName">Source element</th>
+        <th class="featureName">Problem</th>
+        <th class="featureName">Target element</th>
+    </tr>
+    {#- ----------------------------------------- -#}
+    {#- Report features that are only on one side -#}
+    {#- ----------------------------------------- -#}
+    
+    {%- for fqr in data.sourcedata.features -%}
+       {%- if fqr not in data.targetdata.features -%}
+       <!-- report all rows that are missing from target -->
+           <tr>
+           <td bgcolor="pink">Missing {{fqr}}</td>
+           <td><a href="{{ data.sourcedata.features[fqr].get_configuration_path() }}">{{ data.sourcedata.features[fqr].get_configuration_path() }}</a></td>
+           <td>&nbsp;</td>
+           <td>&nbsp;</td>
+           <td bgcolor="gainsboro">Missing feature</td>
+           <td>&nbsp;</td>
+           </tr>
+       {% endif -%}
+    {%- endfor -%}
+    
+    {#- --------------------------------#}
+    {#- Report differences in features -#}
+    {#- --------------------------------#}
+    {%- for fqr in data.sourcedata.features -%}
+       {%- if fqr in data.targetdata.features and not data.sourcedata.features[fqr]._compare(data.targetdata.features[fqr], columns.keys()) -%}
+           {%- if data.sourcedata.features[fqr]['type'] == 'int' and
+                  data.targetdata.features[fqr]['type'] == None %}
+           {% else %}
+               <!-- report all rows that have some column different  -->
+               <tr>
+               <td>Difference with {{fqr}}</td>
+               <td><a href="{{ data.sourcedata.features[fqr].get_configuration_path() }}">{{ data.sourcedata.features[fqr].get_configuration_path() }}</a></td>
+               <td><a href="{{ data.targetdata.features[fqr].get_configuration_path() }}">{{ data.targetdata.features[fqr].get_configuration_path() }}</a></td>
+               {%- if data.sourcedata.features[fqr]['type'] != data.targetdata.features[fqr]['type'] %}
+                 <td bgcolor="gainsboro">{{data.sourcedata.features[fqr]['type']}}</td>
+                 <td bgcolor="gainsboro">Type difference</td>
+                 <td bgcolor="gainsboro">{{data.targetdata.features[fqr]['type']}}</td>
+               {% elif data.sourcedata.features[fqr]['options'] != data.targetdata.features[fqr]['options'] %}
+                  <td bgcolor="gainsboro">{% for option in data.sourcedata.features[fqr]['options'].values() -%}
+                  Option {%- if option.map %} map=option.map{% else %} name={{ option.name }}, value={{ option.value}}{% endif %}<br>
+                  {%- endfor %}</td>
+                  <td bgcolor="gainsboro">Options difference</td>
+                  <td bgcolor="gainsboro">{% for option in data.targetdata.features[fqr]['options'].values() -%}
+                  Option {%- if option.map %} map=option.map{% else %} name={{ option.name }}, value={{ option.value}}{% endif %}<br>
+                  {%- endfor %}</td>
+               {% else %}
+                 <td>&nbsp;</td>
+               {%- endif -%}
+               </tr>
+           {%- endif -%}
+       {% endif -%}
+    {%- endfor -%}
+    
+    </table>
+    <script language="javascript" type="text/javascript">
+//<![CDATA[
+    setFilterGrid("report_data");
+//]]>
+</script>
+{% endblock %}
--- a/configurationengine/source/scripts/compare_data_report_template.html	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/compare_data_report_template.html	Tue Aug 10 14:29:28 2010 +0300
@@ -3,7 +3,7 @@
 {% block content %}
     <h1>Configuration data comparison</h1><br>
     
-    <table class="report">
+    <table class="report" id="comp">
       <tr>
         <td>Source:</td>
         <td>{{ data.sourcedata.name }}</td>
@@ -13,10 +13,15 @@
         <td>{{ data.targetdata.name }}</td>
       </tr>
     </table>
+    <script language="javascript" type="text/javascript">
+//<![CDATA[
+    setFilterGrid("comp");
+//]]>
+</script>
     
     <br/>
     
-    <table class="report">
+    <table class="report" id="report_data">
     <tr>
         <th class="featureName">Full reference</th>
         <th class="featureName">Name</th>
@@ -35,4 +40,9 @@
     {%- endfor -%}
 
     </table>
+    <script language="javascript" type="text/javascript">
+//<![CDATA[
+    setFilterGrid("report_data");
+//]]>
+</script>
 {% endblock %}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/cone.ini	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,40 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+[actions]
+configuration_actions        = configuration
+project_actions              = project
+extension_actions            = extension
+
+[configuration]
+# a list of cone commands
+validate    = conesub_validate
+generate    = conesub_generate
+compare     = conesub_compare
+fix         = conesub_fix
+report      = conesub_report
+update      = conesub_update
+
+[project]
+# a list of cone commands
+info        = conesub_info
+export      = conesub_export
+merge       = conesub_merge
+
+[extension]
+initvariant = conesub_initvariant
+packvariant = conesub_packvariant
+rootflatten = configroot2flat
--- a/configurationengine/source/scripts/cone_base.html	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/cone_base.html	Tue Aug 10 14:29:28 2010 +0300
@@ -110,7 +110,28 @@
     .currentValue {
         background-color: #e8f2fe;
     }
+
+.fltrow{ /* filter grid row appearance */
+    height:20px;
+    background-color:#f4f4f4;
+}
+.btnflt{ /* button appearance */
+    font-size:11px;
+    margin:0 2px 0 2px; padding:0 1px 0 1px;
+    text-decoration:none; color: #fff;
+    background-color:#666;
+}
+.flt{ /* filter (input) appearance */
+    background-color:#f4f4f4; border:1px inset #ccc; 
+    margin:0; width:100%;
+}
+.flt_s{ /* small filter (input) appearance */
+    background-color:#f4f4f4; border:1px inset #ccc; 
+    margin:0; width:80%;
+}
+
 </style>
+<script language="javascript" type="text/javascript" src="http://www.javascriptkit.com/script/script2/tablefilter.js"></script>
 <title>{% block title %}{% endblock %} - ConE</title>
 {% endblock head %}
 </head>
--- a/configurationengine/source/scripts/cone_common.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/cone_common.py	Tue Aug 10 14:29:28 2010 +0300
@@ -33,11 +33,11 @@
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
 
 try:
-    from cone.public import api, settings
+    from cone.public import api, settings, utils
 except ImportError:
     sys.path.append(os.path.join(ROOT_PATH))
     sys.path.append(os.path.join(ROOT_PATH,'..'))
-    from cone.public import api, settings
+    from cone.public import api, settings, utils
 
 # Common command line options used by all sub-actions
 COMMON_OPTIONS = [
@@ -69,7 +69,7 @@
                                     DEBUG         5""",
           metavar="LEVEL",
           default="3"),
-    
+
     Option("--log-file",
            dest="log_file",
            action="store",
@@ -90,7 +90,8 @@
            action="store",
            type="string",
            help="Username for webstorage operations. Not needed for filestorage or cpf storage. If the username \
-           is not given, the tool will use the loggged in username.",
+           is not given, the tool will use the logged in username. "\
+           "Example: cone export -p webstorage_url -r . -c sample.confml --username=admin --password=abc123.",
            metavar="USERNAME"),
 
     Option("--password",
@@ -98,7 +99,7 @@
            action="store",
            type="string",
            help="Password for webstorage operations. Not needed for filestorage or cpf storage. If the password \
-           is not given, the tool will prompt for password if needed.",
+           is not given, the tool will prompt for password if needed. ",
            metavar="PASSWORD"),
 ]
 
@@ -156,6 +157,14 @@
 
 def open_log(verbose, log_file, log_conf_file=os.path.join(ROOT_PATH, 'logging.ini')):
     try:
+        # Convert the reference to the log file as a absolute path so that it would work in all scenarios
+        log_file = repr(os.path.abspath(log_file))
+        
+        if log_file.startswith("'"):
+            log_file = log_file.replace("'", '', 1)
+        if log_file.endswith("'"):
+            log_file = log_file.replace("'",'', 1)
+
         log_dir = os.path.dirname(log_file)
         if log_dir != '' and not os.path.exists(log_dir):
             os.makedirs(log_dir)
@@ -259,7 +268,7 @@
     
     # Handle configurations specified with --configuration first
     for config in configs:
-        if config not in configs_in_project:
+        if not project.get_storage().is_resource(utils.resourceref.norm(config)):
             raise ConfigurationNotFoundError("No such configuration: %s" % config)
         if config not in config_list:
             config_list.append(config)
@@ -280,4 +289,4 @@
                     if config not in config_list:
                         config_list.append(config)
     
-    return config_list
+    return config_list
\ No newline at end of file
--- a/configurationengine/source/scripts/cone_defaults.cfg	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/cone_defaults.cfg	Tue Aug 10 14:29:28 2010 +0300
@@ -1,3 +1,4 @@
+#
 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
 # All rights reserved.
 # This component and the accompanying materials are made available
@@ -10,13 +11,14 @@
 #
 # Contributors:
 #
-# Description: 
+# Description:
+#
 
 [DEFAULT]
 # Settings for cone implmentation plugins 
 # default path setting for all plugins 
 # output path is a concatenation of output_root, output_subdir and plugin_output
-output_root=output
+output_root=
 output_subdir=
 plugin_output=
 output=%(output_root)s/%(output_subdir)s/%(plugin_output)s
--- a/configurationengine/source/scripts/cone_subaction.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/cone_subaction.py	Tue Aug 10 14:29:28 2010 +0300
@@ -19,8 +19,46 @@
 import fnmatch 
 import re
 import logging
+import ConfigParser
 
 
+def get_cfg_files(paths, filename):
+    """ Find out the cone subscripts that are present in the"""
+    files = []
+    for path in paths:
+        cfgfile = os.path.join(path, filename)
+        if os.path.exists(cfgfile):
+            files.append(cfgfile)
+    return files
+
+def get_config(cfgfiles):
+    config = ConfigParser.ConfigParser()
+    config.read(cfgfiles)
+    return config
+
+def get_actions(cfgfiles):
+    """ Find out the cone subscripts that are present in the"""
+    subacts = ActionContainer()
+    config = get_config(cfgfiles)
+    actions_section = 'actions'
+    if not config.has_section(actions_section):
+        raise Exception('The cone.ini does not have any %s section.' % actions_section)
+    for (name, section) in config.items(actions_section):
+        subacts += get_subactions_from_configs(cfgfiles, section)     
+    return subacts
+
+def get_subactions_from_configs(cfgfiles, section):
+    """ Find out the cone subscripts that are present in the"""
+    subacts = ActionContainer()
+    config = get_config(cfgfiles)
+    paths = [os.path.dirname(cfgfile) for cfgfile in cfgfiles]
+    if not config.has_section(section):
+        raise Exception('The cone.ini does not have any %s section.' % section)
+    for (commandname, path) in config.items(section):
+        subacts.append(ConeAction(commandname, path, type=section, paths=paths))
+    
+    return subacts
+
 def get_subactions(path,pattern):
     """ Find out the cone subscripts that are present in the ROOT_PATH """
     subacts = ActionContainer()
@@ -42,24 +80,70 @@
     elif level == 5 : return logging.DEBUG
     else : return logging.NOTSET
 
-class ActionContainer(object):
-    def __init__(self):
-        self._actions = {}
+class ActionContainer(list):
+    pass
 
-    def __len__(self):
-        return len(self._actions)
-
+#    def __init__(self):
+#        self._actions = {}
+#
+#    def __len__(self):
+#        return len(self._actions)
+#
     def __getitem__(self, key):
-        return self._actions[key]
+        for item in self:
+            if item.name == key:
+                return item
+        raise KeyError('Key %s not found in %s'  % (key, self))
+#
+#    def __setitem__( self, key, value):
+#        self._actions[key] = value
+#
+#    def __delitem__( self, key):
+#        del self._actions[key]
+#
+#    def __iter__( self):
+#        return self._actions.__iter__()
 
-    def __setitem__( self, key, value):
-        self._actions[key] = value
+class ConeAction(object):
+    def __init__(self, name, path, **kwargs):
+        self.name = name
+        self.path = path
+        self.type = kwargs.get('type', '')
+        self.paths = kwargs.get('paths', [])
+        self._module = None
+
+    @property
+    def module_name(self):
+        return os.path.basename(self.path)
 
-    def __delitem__( self, key):
-        del self._actions[key]
+    @property
+    def module_path(self):
+        return os.path.dirname(self.path)
 
-    def __iter__( self):
-        return self._actions.__iter__()
+    @property
+    def module(self):
+        if not self._module:
+            paths = [os.path.join(pth, self.module_path) for pth in self.paths]
+            paths.append(self.module_path)
+            sys.path += paths
+            try:
+                self._module  = __import__(self.module_name)
+            finally:
+                del sys.path[-len(paths):]
+        return self._module
+    
+    def short_help(self):
+        if hasattr(self.module, 'short_help'):
+            return self.module.short_help
+        elif hasattr(self.module, 'main'):
+            helpstr = self.module.main.__doc__ or '<None>'
+            return helpstr.replace('\n', '').strip(' ')[:50]
+        else:
+            return 'Not a valid module!!'
+        
+    def run(self):
+        self.module.main()
+
 
 class SubAction(object):
     def __init__(self, scriptname, pattern):
--- a/configurationengine/source/scripts/cone_tool.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/cone_tool.py	Tue Aug 10 14:29:28 2010 +0300
@@ -42,35 +42,86 @@
 
 import cone
 import cone_subaction
-from cone.public import settings
+import cone_common
+from cone.public import settings, utils
 
-CONE_SCRIPT_PATTERN = 'conesub_*.py'
-ROOT_PATH           = os.path.dirname(os.path.abspath(__file__))
-SUBS                = cone_subaction.get_subactions(ROOT_PATH, CONE_SCRIPT_PATTERN)
-ACTIONS             = [sub for sub in SUBS]
 logger              = logging.getLogger('cone')
 VERSION             = cone.__version__
 if cone._svnrevision not in ("", "exported"):
     VERSION += " (SVN %s)" % cone._svnrevision
-CONE_USAGE          = "%prog [action] [options]."
-CONE_ACTIONS        = '\n'
-for act in ACTIONS:
-     CONE_ACTIONS += '    %s\n' % act
-CONE_ACTION_HELP    = "Available actions %s\nUse %%prog [action] -h to get action specific help." % CONE_ACTIONS
+
+
+def format_actions(actions, filter=None):
+    action_names = []
+    for act in actions:
+        if not filter or filter(act):
+            action_names.append(act.name)
+    
+    action_names.sort()
+    ret = ''
+    for act in action_names:
+        help =  actions[act].short_help()
+        ret += '    %s : %s\n' % (act, help)
+    return ret
+
+def get_cone_configs(paths):
+    static_paths =  [os.path.expanduser('~'),
+                     os.getcwd()]
+    all_paths = [ROOT_PATH]
+    all_paths += static_paths
+    all_paths += paths
+    
+    configs = cone_subaction.get_cfg_files(all_paths, 'cone.ini')
+    return configs
+
+def get_actions(configs):
+    return cone_subaction.get_actions(configs)
+
+
+def get_help(actions):
+    helpstr = \
+"""
+Use %%prog [action] -h to get action specific help.
+
+Available actions 
+Main actions for one or more configurations. 
+%s
+
+Actions related to the configuration project maintenance. 
+%s
+
+extensions:
+%s
+""" % (format_actions(actions, lambda x: x.type=='configuration'),
+       format_actions(actions, lambda x: x.type=='project'),
+       format_actions(actions, lambda x: x.type=='extension'))
+    return helpstr
 
 def main():
-    parser = OptionParser(usage="%s\n\n%s" % (CONE_USAGE,CONE_ACTION_HELP),
-                          version="%%prog %s" % VERSION,
-                          prog="ConE")
+    # Get the operating system name to pass it on the the cmdsplit..
+    os_name = os.name
+    if os.getenv('CONE_CMDARG'):
+        sys.argv = [sys.argv[0]]
+        sys.argv += utils.cmdsplit(os.getenv('CONE_CMDARG'), os_name)
+    if os.getenv('CONE_CMD_APPEND'):
+        sys.argv.append( utils.cmdsplit(os.getenv('CONE_CMD_APPEND'), os_name) )
+
+    CONE_USAGE = "%prog [action] [options]."
+    configs = get_cone_configs([])
+    actions = get_actions(configs)
     
     # Set the path for cone .cfg files to the same directory as this script
     settings.SettingsFactory.configpath = ROOT_PATH
     
     try:
         action = sys.argv[1]
-        subaction = SUBS[action]
+        subaction = actions[action]
         print "Running action %s" % subaction.name
     except (IndexError, KeyError):
+        CONE_ACTION_HELP = get_help(actions)
+        parser = OptionParser(usage="%s\n\n%s" % (CONE_USAGE,CONE_ACTION_HELP),
+                              version="%%prog %s" % VERSION,
+                              prog="ConE")
         (options, args) = parser.parse_args()
         parser.error("Action must be given! See --help.")
     
--- a/configurationengine/source/scripts/conesub_compare.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/conesub_compare.py	Tue Aug 10 14:29:28 2010 +0300
@@ -25,7 +25,7 @@
 
 from cone.public import api, plugin, utils, exceptions
 from time import gmtime, strftime
-import report_util
+from cone.report import report_util
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
 
 VERSION = '1.0'
@@ -38,6 +38,11 @@
         'api_comparison.html',
         'Report changes in feature definitions'),
                        
+    'ci': report_util.ReportShortcut(
+        os.path.join(ROOT_PATH, 'compare_ci_report_template.html'),
+        'ci_comparison.html',
+        'Report changes in CustomisationInterface definitions'),
+
     'data': report_util.ReportShortcut(
         os.path.join(ROOT_PATH, 'compare_data_report_template.html'),
         'data_comparison.html',
@@ -56,6 +61,7 @@
 DEFAULT_SHORTCUT = 'data'
 
 def main():
+    """ Compare two configurations """
     shortcut_container = report_util.ReportShortcutContainer(REPORT_SHORTCUTS,
                                                              DEFAULT_SHORTCUT)
     
--- a/configurationengine/source/scripts/conesub_export.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/conesub_export.py	Tue Aug 10 14:29:28 2010 +0300
@@ -18,18 +18,23 @@
 import fnmatch
 import logging
 from optparse import OptionParser, OptionGroup
-
 import cone_common
 from cone.public import api, plugin, utils, exceptions
 
 
 VERSION     = '1.0'
 DEFAULT_EXT = '.cpf'
+CONE_SCRIPT_PATTERN = 'conesub_*.py'
+ROOT_PATH = os.path.abspath(os.path.dirname(__file__))
 
 logger    = logging.getLogger('cone')
 DATA_NAME = 'confml/data.confml'
 
+class  ExportFailedException(Exception):
+    pass    
+
 def main():
+    """ Export configurations. """
     parser = OptionParser(version="%%prog %s" % VERSION)
     
     parser.add_options(cone_common.COMMON_OPTIONS)
@@ -108,11 +113,31 @@
                    metavar="CONFIG",
                    default=None)
 
+    group.add_option("--run-action",
+                   dest="action",
+                   action="append",
+                   type="string",
+                   help="Adds a execution of extra step that can manipulate the configuration before it is exported to external storage. "\
+                        "The --run-action operation can be used several times in a single command and it "\
+                        "will execute the actions in given order."\
+                        "Example --run-action=fix, which would execute fix action during export.",
+                   metavar="PLUGIN",
+                   default=None)
+
     group.add_option("--exclude-folders",
                         dest="exclude_empty_folders",
                         action="store_true",
                         help="Excludes empty folders from export",
                         default=False)
+
+    group.add_option("--exclude-content-filter",
+                        dest="exclude_content_filter",
+                        help="Filters out files and folders from content folder which matches with "\
+                             "the given regular expression. Matching is case-insensitive. "\
+                             "Example --exclude-content-filter=\".*\.sisx|.*\.sis|.*\.wgz|.*wgt\" "\
+                             "Filters out all files with extension sis, sisx, wgz or wgt.",
+                        default=None)
+
     
     parser.add_option_group(group)
     (options, args) = parser.parse_args()
@@ -131,8 +156,17 @@
     if options.export_dir and os.path.isfile(options.export_dir):
         parser.error("Given export directory '%s' is a file")
     
+    try:
+        run_export(options)
+    except ExportFailedException, e:
+        parser.error(str(e))
+
+    
+    
+def run_export(options):
     # Open the project and find out the active configuration
-    project = api.Project(api.Storage.open(options.project, "r"))
+    storage = api.Storage.open(options.project, "r", username=options.username, password=options.password)
+    project = api.Project(storage)
     try:
         active_root = project.get_storage().get_active_configuration()
     except AttributeError:
@@ -148,12 +182,12 @@
                 config_wildcards = options.config_wildcards,
                 config_regexes   = options.config_regexes)
         except cone_common.ConfigurationNotFoundError, e:
-            parser.error(str(e))
+            raise ExportFailedException(str(e))
     
     # Use the active configuration if no configurations are specifically given
     if len(config_list) == 0:
         if active_root is None:
-            parser.error("No configurations given and the project does not have an active root")
+            raise ExportFailedException("No configurations given and the project does not have an active root")
         else:
             logger.info('No configurations given! Using active root configuration %s' % active_root)
             config_list = [active_root]
@@ -165,16 +199,20 @@
                        export_format = options.export_format or 'cpf',
                        configs       = config_list,
                        added_layers  = options.added,
-                       empty_folders = not options.exclude_empty_folders)
+                       empty_folders = not options.exclude_empty_folders,
+                       exclude_filters       = {"content": options.exclude_content_filter},
+                       options               = options)
     else:
         _export_to_storage(project                 = project,
                            remote_project_location = options.remote,
                            configs                 = config_list,
                            added_layers            = options.added,
-                           empty_folders           = not options.exclude_empty_folders)
+                           empty_folders           = not options.exclude_empty_folders,
+                           exclude_filters         = {"content": options.exclude_content_filter},
+                           options                 = options)
     
 
-def _export_to_storage(project, remote_project_location, configs, added_layers, empty_folders):
+def _export_to_storage(project, remote_project_location, configs, added_layers, empty_folders, exclude_filters, options):
     assert len(configs) > 0
     
     # If the remote storage is not given, determine it automatically based
@@ -185,12 +223,24 @@
         logger.info('No remote storage given! Using source configuration name %s' % remotename)
         remote_project_location = remotename
     
-    remote_project = api.Project(api.Storage.open(remote_project_location, "w"))
+    remote_project = api.Project(api.Storage.open(remote_project_location, "w", username=options.username, password=options.password))
     for config_path in configs:
         config = project.get_configuration(config_path)
+        # immediate solution to run fixes during export
+        if options.action:
+            from cone.action import loader
+            for action_name in options.action:
+                try:
+                    action_class = loader.get_class(action_name)
+                    action = action_class(configuration=config,
+                                          project=project)
+                    action.run()
+                except Exception,e:
+                    logger.warning('Running plugin %s threw an exception: %s' % (action_name, e))
         project.export_configuration(config,
                                      remote_project.storage,
-                                     empty_folders = empty_folders)
+                                     empty_folders = empty_folders,
+                                     exclude_filters = exclude_filters)
         print "Export %s to %s done!" % (config_path, remote_project_location)
     
     # Setting first as active configuration if there are more than one configuration defined.
@@ -204,9 +254,9 @@
     remote_project.save()
     remote_project.close()
     
-    _add_layers(project, remote_project_location, added_layers, empty_folders)
+    _add_layers(project, remote_project_location, added_layers, empty_folders, exclude_filters, options)
     
-def _add_layers(source_project, remote_project_location, added_configs, empty_folders):
+def _add_layers(source_project, remote_project_location, added_configs, empty_folders, exclude_filters, options):
     """
     Add new configuration layers from source_project into 
     """
@@ -227,7 +277,8 @@
                     existing_config = source_project.get_configuration(added_config_name)
                     source_project.export_configuration(existing_config,
                                                         target_project.storage,
-                                                        empty_folders = empty_folders)
+                                                        empty_folders = empty_folders,
+                                                        exclude_filters = exclude_filters)
                 else:
                     # The given configuration does not exist in the source project,
                     # create a new empty layer
@@ -241,7 +292,7 @@
     target_project.save()
     target_project.close()
 
-def _export_to_dir(project, export_dir, export_format, configs, added_layers, empty_folders):
+def _export_to_dir(project, export_dir, export_format, configs, added_layers, empty_folders, exclude_filters, options):
     if not os.path.exists(export_dir):
         os.makedirs(export_dir)
     
@@ -253,7 +304,7 @@
             remote_name += '/'
         
         remote_name = os.path.join(export_dir, remote_name)
-        _export_to_storage(project, remote_name, [config], added_layers, empty_folders)
+        _export_to_storage(project, remote_name, [config], added_layers, empty_folders, exclude_filters, options)
 
 if __name__ == "__main__":
     main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/conesub_fix.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,100 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+import os
+import logging
+from optparse import OptionParser, OptionGroup
+import cone_common
+from cone.public import api, exceptions
+from cone.action import fix
+from cone.validation import confmlvalidation
+
+ROOT_PATH = os.path.abspath(os.path.dirname(__file__))
+
+VERSION     = '1.0'
+
+logger    = logging.getLogger('cone')
+
+def main():
+    """ Run automatic fixes for configurations. """
+    parser = OptionParser(version="ConE validate %s" % VERSION)
+    
+    parser.add_options(cone_common.COMMON_OPTIONS)
+    
+    parser.add_option("-c", "--configuration",
+                        dest="configuration",
+                        help="Defines the name of the configuration for the action",
+                        metavar="CONFIG")
+
+    parser.add_option("-p", "--project",
+                       dest="project",
+                       default=".",
+                       help="defines the location of current project. Default is the "\
+                            "current working directory.",
+                       metavar="STORAGE")
+    
+    group = OptionGroup(parser, 'Fix options',
+                        'The fix action is intended for performing fixes on a     '\
+                        'configuration.                                           ')
+
+    group.add_option("--print-available-fixes",
+                     action="store_true",
+                     help="Print all configuration fixer objects available.",
+                     default=False)
+
+    group.add_option("--exclude-filter",
+                     action="append",
+                     help="Exclude problems by given filter. "\
+                          "Examples: --exclude-filter=schema, --exclude-filter=schema.implml, --exclude-filter=schema.confml, --exclude-filter=schema.implml.ruleml",
+                     default=None)
+
+    group.add_option("--include-filter",
+                     action="append",
+                     help="Include problems by given filter."\
+                          "Examples: --include-filter=schema.implml, --include-filter=schema.implml.ruleml",
+                     default=None)
+
+    parser.add_option_group(group)
+    (options, _) = parser.parse_args()
+    
+    cone_common.handle_common_options(options)
+    
+
+    if options.print_available_fixes:
+        print "Available fixers:"
+        for fix_class in confmlvalidation.get_fixer_classes():
+            print "%s: %s" % (fix_class, fix_class.__doc__)
+        return 0
+    else:
+        if not options.configuration:
+            parser.error("A configuration must be given! Use -c / --configuration option.")
+        action = fix.ConeFixAction(include_filter=options.include_filter or [],
+                               exclude_filter=options.exclude_filter or [],
+                               username=options.username,
+                               password=options.password,
+                               project_name=options.project,
+                               configuration_name=options.configuration)
+        
+        status = action.run()
+        if status:
+            action.save()
+            action.close()
+            
+        return status
+    
+
+if __name__ == "__main__":
+    main()
--- a/configurationengine/source/scripts/conesub_generate.cfg	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/conesub_generate.cfg	Tue Aug 10 14:29:28 2010 +0300
@@ -1,3 +1,4 @@
+#
 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
 # All rights reserved.
 # This component and the accompanying materials are made available
@@ -10,7 +11,8 @@
 #
 # Contributors:
 #
-# Description: 
+# Description:
+#
 
 # conesub_generate action specific configuration. The configuration option names 
 # are the same what are documented in the command line help.
--- a/configurationengine/source/scripts/conesub_generate.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/conesub_generate.py	Tue Aug 10 14:29:28 2010 +0300
@@ -14,21 +14,23 @@
 # Description: 
 #
 
-import os
-import sys
+import os, re, fnmatch
 import logging
 from optparse import OptionParser, OptionGroup
 import cone_common
 import time
-from os import path 
+from distutils.dir_util import mkpath, DistutilsFileError
 from cone.public import api, plugin, utils, exceptions
-import generation_report
+from cone.report import generation_report
+from cone.confml import persistentconfml
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
 
 VERSION = '1.0'
 
+log = logging.getLogger('cone')
 
-def main():    
+def main():
+    """ Generate a configuration. """
     parser = OptionParser(version="%%prog %s" % VERSION)
     
     parser.add_options(cone_common.COMMON_OPTIONS)
@@ -54,23 +56,6 @@
                    metavar="FOLDER",\
                    default="output")
 
-    gen_group.add_option("-l", "--layer",\
-                   dest="layers",\
-                   type="int",
-                   action="append",
-                   help="define layers of the configuration that are included to the output. "\
-                        "The layer operation can be used several times in a single command."\
-                        "Example -l -1 --layer=-2, which would append a layers -1 and -2 to the layers => layers = -1,-2",
-                   metavar="LAYER",\
-                   default=None)
-    
-    gen_group.add_option("--all-layers",
-                   dest="all_layers",
-                   action="store_true",
-                   help="Include all layers in generation. This switch overrides all other layer "\
-                        "configurations (iMaker API and using the --layer parameter)",
-                   default=False)
-
     gen_group.add_option("-i", "--impl",\
                    dest="impls",\
                    action="append",
@@ -132,6 +117,16 @@
                    metavar="FILE",\
                    default=None)
 
+    gen_group.add_option("--report-option",\
+                   action="append",
+                   help="Specifies the report verbose options, that defines "\
+                        "what data is included to the report. The option can be "\
+                        "used multiple times."\
+                        "choises=[default|all]"\
+                        "Example --report-option=all",
+                   metavar="OPTION",\
+                   default=[])
+
     gen_group.add_option("-t", "--template",\
                    dest="template",\
                    action="store",
@@ -161,15 +156,66 @@
                         "Example -o my_generate_settings.cfg.",
                    metavar="FILE",\
                    default=None)
+    gen_group.add_option("--dump-autodata",\
+                   dest="dump_autodata",\
+                   action="store",
+                   type="string",
+                   metavar="FILE",
+                   help="Specifies a confml file for storing autodata.confml permanently.",
+                   default=None)
+    gen_group.add_option("-w", "--what",\
+                   dest="what",\
+                   action="store",
+                   type="string",
+                   metavar="FILE",
+                   help="List output files to a txt file",
+                   default=None)
     
-    layers = None
-    current = None
-    remote = None
+    lf_group = OptionGroup(parser, 'Layer filtering options',
+                    'Layer filtering options define configuration layers to be used for filtering '\
+                    'the implementations that are used to generate output. Filtering by a layer means that '\
+                    'only implementations that generate their output based on settings changed on that layer '\
+                    'are included in the generation.')
+    
+    lf_group.add_option("-l", "--layer",\
+                   dest="layers",\
+                   type="int",
+                   action="append",
+                   help="Define a layer by giving its index in the root configuration. "\
+                        "0 is first, 1 the second, -1 the last, -2 the second to last and so on. "\
+                        "The layer operation can be used several times in a single command. "\
+                        "Example -l -1 --layer=-2, which would append a layers -1 and -2 to the layers => layers = -1,-2",
+                   metavar="LAYER",\
+                   default=None)
+    
+    lf_group.add_option("--layer-regex",
+                   dest="layer_regexes",
+                   action="append",
+                   help="Define a regular expression for including layers into the generation process, "\
+                        "e.g. --layer-regex layer[0-9]/root.confml. The pattern is matched against the layer root "\
+                        "path, which could be e.g. 'assets/layer1/root.confml'.",
+                   metavar="REGEX",)
+    
+    lf_group.add_option("--layer-wildcard",
+                   dest="layer_wildcards",
+                   action="append",
+                   help="Define a wildcard for including layers into the generation process, e.g "\
+                        "--layer-wildcard layer*",
+                   metavar="WILDCARD",)
+    
+    lf_group.add_option("--all-layers",
+                   dest="all_layers",
+                   action="store_true",
+                   help="Include all layers in generation. This switch overrides all other layer "\
+                        "configurations (iMaker API and using the --layer, --layer-regex and --layer-wildcard parameters)",
+                   default=False)
+    
     
     start_time = time.time()
     
     parser.add_option_group(gen_group)
-    (options, args) = parser.parse_args()
+    parser.add_option_group(lf_group)
+    (options, _) = parser.parse_args()
 
     settinglist = [os.path.join(ROOT_PATH,'conesub_generate.cfg')]
     if options.settings:
@@ -201,29 +247,13 @@
             logging.getLogger('cone').info('Adding configuration %s' % configname) 
             config.include_configuration(utils.resourceref.norm(configname))
     
-    # Get defs from configuration         
+    # Get implementation filters from configuration
     try:
-        layer_str_list = (config.get_default_view().get_feature('imakerapi.cone_layers').get_value() or '').split(',')
-        # Make sure that empty layers definitions are ignored
-        layer_str_list = utils.distinct_array(layer_str_list)
-        if '' in layer_str_list:
-            layer_str_list.remove('')
-        # converting layrs identifiers from strings to int
-        layerdefs = []
-        for layerstr in layer_str_list:
-            try:
-                layerdefs.append(int(layerstr))
-            except ValueError, e:
-                logging.getLogger('cone').error('Invalid layer filter %s' % layerstr)
         implfilters = (config.get_default_view().get_feature('imakerapi.cone_impls').get_value() or '').split(',')
     except exceptions.NotFound:
-        layerdefs = []
         implfilters = []
-        pass
-
+    
     # Get filters from command line if they exist => cmd overrides configuration
-    if options.layers:
-        layerdefs = options.layers
     if options.impls:
         implfilters = options.impls
     if options.tags and len(options.tags) > 0:
@@ -241,38 +271,45 @@
     if options.tags_policy:
         tags_policy = options.tags_policy[0]
     
-    # Finally, --all-layers overrides all other layer settings
-    if options.all_layers:
-        layerdefs = []
+    
+    layerdefs = _get_included_layers(config, options, parser)
+    filter_by_refs = _filter_by_refs(config, options, parser)
     
-    logging.getLogger('cone').info('Layer filter %s' % layerdefs)
+    if layerdefs:
+        logging.getLogger('cone').info('Included layers:\n%s' % '\n'.join(layerdefs))
+    else:
+        logging.getLogger('cone').info('Including all layers')
     
-    # Add reffilters only if the given layerids are somehow reasonable    
+    dview = config.get_default_view()
+    # Add data references if included layers are defined
     if len(layerdefs) > 0:
         # get the data references from given layers
         logging.getLogger('cone').info('Getting layer specific data reference from %s' % layerdefs)
         reffilters = []
-        for layerid in utils.distinct_array(layerdefs): 
-            logging.getLogger('cone').info('Searching layer %s' % layerid)            
-            layer = config.get_configuration_by_index(layerid)
+        for layer_path in utils.distinct_array(layerdefs):
+            logging.getLogger('cone').info('Searching layer %s' % layer_path)
+            layer = config.get_configuration(layer_path)
             refs = _get_new_refs(reffilters, layer.list_leaf_datas())
-            logging.getLogger('cone').info("Refs from layer '%s'\n%s" % (layer.get_path(), '\n'.join(refs)))
+            # reduce the refs of sequences to single reference of the sequence feature
+            layerrefs = set() 
+            for fea in dview.get_features(refs):
+                layerrefs.add(fea.fqr)
+                if fea.is_sequence():
+                    layerrefs.add(fea.get_sequence_parent().fqr)
+            
+            refs = sorted(list(layerrefs))
+            #logging.getLogger('cone').info("Refs from layer '%s'\n%s" % (layer.get_path(), '\n'.join(refs)))
             reffilters += refs
-    
-
-    if options.overrides:
-        config.add_configuration(api.Configuration('tempdata.confml'))
-        for override in options.overrides:
-            (ref,value) = override.split('=',1) 
-            config.get_default_view().get_feature(ref).set_value(value)
-            
+          
     # Make sure that the output folder exists
     if not os.path.exists(options.output):
         os.makedirs(options.output)
-
+        
     impls = plugin.filtered_impl_set(config,implfilters)
     impls.output = options.output
     
+    log.info("Parsed %s implementation(s)" % len(impls))
+    
     logging.getLogger('cone').info("Supported implementation file extensions: %r" % plugin.get_supported_file_extensions())
     
 #    logging.getLogger('cone').debug('Loaded implementations:')
@@ -284,102 +321,97 @@
     
     # Create temporary variables
     temp_feature_refs = impls.create_temp_features(config)
+    
     if reffilters is not None:
         reffilters.extend(temp_feature_refs)
         logging.getLogger('cone').info('Refs from temporary variables:\n%s' % '\n'.join(temp_feature_refs))
     
+    # Set overrides only after temp variables are created, so that
+    # they can also be modified from the command line
+    if options.overrides:
+        # Make sure that the last layer is the autodata layer
+        plugin.get_autoconfig(config)
+        for override in options.overrides:
+            (ref,value) = override.split('=',1)
+            config.get_default_view().get_feature(ref).set_value(value)
     
     
     # ---------------
     # Generate output
     # ---------------
     
-    rule_exec_results = []
-    
-    # Create an implementation container with all the relevant implementations
-    all_impls = impls.filter_implementations(tags=impltags, policy=tags_policy)
-    
-    # Implementations taking part in output generation
-    gen_impls = plugin.ImplSet()
-    context = plugin.GenerationContext()
-    context.configuration = config
-    log = logging.getLogger('cone')
-    for phase in plugin.ImplSet.INVOCATION_PHASES:
-        phase_impls = all_impls.filter_implementations(phase=phase)
-        log.info("Generating phase '%s', %d implementation(s)" % (phase, len(phase_impls)))
-        
+    context = plugin.GenerationContext(configuration = config,
+                                       tags = impltags or {},
+                                       tags_policy = tags_policy,
+                                       output = options.output,
+                                       impl_set = impls,
+                                       temp_features = temp_feature_refs,
+                                       filter_by_refs = filter_by_refs)
+    context.changed_refs = reffilters
+    context.output = options.output
+
+    impls.output = options.output
+    for phase in impls.INVOCATION_PHASES:
+        log.info("Generating phase '%s'" % phase)
         context.phase = phase
-        # No use going any further if there are no implementations
-        # for the phase at all
-        if len(phase_impls) == 0:
-            continue
-        
-        # Load and execute rules for this phase
-        # -------------------------------------
-#        relation_container = phase_impls.get_relation_container()
-#        log.info("%d rule(s) for phase '%s'" % (relation_container.get_relation_count(), phase))
-#        if relation_container.get_relation_count() > 0:
-#            log.info("Executing rules...")
-#            results = relation_container.execute()
-#            log.info("Got %d execution result(s)" % len(results))
-#            rule_exec_results.extend(results)
-        
-        
-        # Create an implementation container for the phase with
-        # the new reffilters and generate output with it
-        # -----------------------------------------------------
-        impls = phase_impls.filter_implementations(refs=reffilters)
-        log.info("%d implementation(s) after filtering for phase '%s'" % (len(impls), phase))
-        if len(impls) > 0:
-            if impltags != None:
-                context.tags = impltags
-                context.tags_policy = tags_policy
-            impls.output = options.output
-            log.info("Generating output...")
-            impls.generate(context)
-            impls.post_generate(context)
-            
-            # Add new refs after generation
-#            if reffilters != None and len(reffilters) > 0:
-#                layer = config.get_configuration_by_index(-1)
-#                new_refs = _get_new_refs(reffilters, layer.list_leaf_datas())
-#                log.info('Added %d ref(s) after generation:\n%s' % (len(new_refs), '\n'.join(new_refs)))
-#                reffilters += new_refs
-            
-        # Add new references after each phase execution
-        # ---------------------------------------
-        if reffilters != None and len(reffilters) > 0:
-            layer = config.get_configuration_by_index(-1)
-            new_refs = _get_new_refs(reffilters, layer.list_leaf_datas())
-            log.info('Added %d ref(s) after phase %s execution:\n%s' % (len(new_refs), phase, '\n'.join(new_refs)))
-            reffilters += new_refs
-        
-        # Add the implementations to the set of implementations participating
-        # in output generation (used in the report)
-        for impl in impls:
-            for actual_impl in impl.get_all_implementations():
-                logging.getLogger('cone').info('Adding impl %s' % impl)
-                gen_impls.add(actual_impl)
+        impls.generate(context)
+        impls.post_generate(context)
+     
+    if options.what:
+        log.info("Write output files to '%s'" % options.what)
+        output_files = []
+        for op in context.get_output():
+            # Only append once
+            if op.type == 'file' and output_files.count(op.abspath) < 1:
+                output_files.append(op.abspath)       
+        try:
+            mkpath(os.path.dirname(os.path.abspath(options.what)))
+            what_fh = open(os.path.abspath(options.what), 'w')
+            try:
+                [what_fh.write('%s\n' % ofile) for ofile in output_files]
+                print "Wrote output file list to '%s'" % options.what
+            finally:
+                what_fh.close()
+        except Exception:
+            log.info("Could not create directory for '%s'" % options.what)
     
-    rule_exec_results = context.results
     print "Generated %s to %s!" % (options.configuration, impls.output)
     
+    # Store temporary rule execution outputs to a new configuration
+    if options.dump_autodata:
+        # Make sure autodata layer is the one we're dealing with     
+        plugin.get_autoconfig(config)
+        lastconfig = config.get_last_configuration()
+        lastconfig.set_name(utils.resourceref.to_objref(utils.resourceref.get_filename(utils.resourceref.norm(options.dump_autodata))))
+        data = persistentconfml.dumps(lastconfig)
+        try:
+            mkpath(utils.resourceref.get_path(utils.resourceref.norm(options.dump_autodata)))
+            fh = open(options.dump_autodata, 'w')
+            try:        fh.write(data)
+            finally:    fh.close()
+            print 'Saved autodata to %s' % options.dump_autodata
+        except DistutilsFileError:
+            log.info('Unable to dump autodata')
+        
     
     # ---------------
     # Generate report
     # ---------------
-    
+
     # If reporting is enabled collect data for report
     if options.report != None or options.report_data_output != None:
         logging.getLogger('cone').info('Collecting data for report.')
-        all_refs = reffilters or utils.distinct_array(config.get_configuration_by_index(-1).list_leaf_datas())
-        logging.getLogger('cone').info('Collecting data found refs %s' % all_refs)
-        logging.getLogger('cone').info('Collecting data found gen_impls %s' % gen_impls)
-        rep_data = generation_report.collect_report_data(config, options, all_refs, gen_impls, rule_exec_results)
+        
+        rep_data = generation_report.ReportData() 
+        rep_data.context = context
+        rep_data.context.log_file = os.path.abspath(options.log_file)
+        rep_data.context.log = _read_log(options.log_file)
+        rep_data.project_dir = options.project
         logging.getLogger('cone').info('Collecting data found rep_data  %s' % rep_data)
         
         duration = str("%.3f" % (time.time() - start_time) )
         rep_data.set_duration( duration )
+        rep_data.options = options
         
         # Save intermediary report data file if necessary
         if options.report_data_output != None:
@@ -389,11 +421,16 @@
         
         # Generate the report if necessary
         if options.report != None:
-            generation_report.generate_report(rep_data, options.report, options.template)
+            generation_report.generate_report([rep_data], options.report, options.template, [ROOT_PATH], options.report_option)
             print_summary(rep_data)
     
     if current: current.close()
 
+def _read_log(log_file):
+    logf = open(log_file)
+    # strip endlines
+    return [line.strip('\n') for line in logf.readlines()]
+    
 def _get_new_refs(old_refs, new_refs):
     """
     Return a distinct array of refs in ``new_refs`` that are not present in ``old_refs``.
@@ -404,12 +441,84 @@
             result.append(ref)
     return result
 
+
+def _filter_by_refs(config, options, parser):
+    """
+    """
+    filter_by_refs = True
+    if options.all_layers:
+        filter_by_refs = False 
+    elif not options.layers and not options.layer_regexes and not options.layer_wildcards:
+        filter_by_refs = False
+    return filter_by_refs
+
+def _get_included_layers(config, options, parser):
+    """
+    Collect a list of included layer root paths from the config based on the
+    given parameters in options.
+    @return: A list of layer configuration paths (empty if all layers
+        should be generated).
+    """
+    # --all-layers overrides all other definitions
+    if options.all_layers:
+        options.layers = [i for i in range(len(config.list_configurations()))] 
+    elif not options.layers and not options.layer_regexes and not options.layer_wildcards:
+        options.layers = [i for i in range(len(config.list_configurations()))]
+    
+    # Command line definitions override others
+    if options.layers or options.layer_regexes or options.layer_wildcards:
+        layer_paths = []
+        all_layers = config.list_configurations()
+        
+        for layer_index in options.layers or []:
+            try:
+                layer_paths.append(all_layers[int(layer_index)])
+            except (IndexError, ValueError):
+                parser.error("Invalid layer index: %s" % layer_index)
+        
+        for regex in options.layer_regexes or []:
+            for layer_path in all_layers:
+                if re.search(regex, layer_path):
+                    layer_paths.append(layer_path)
+        
+        for wildcard in options.layer_wildcards or []:
+            for layer_path in all_layers:
+                if fnmatch.fnmatch(layer_path, wildcard):
+                    layer_paths.append(layer_path)
+        
+        if not layer_paths:
+            parser.error('No layers matched by layer patterns')
+        
+        return utils.distinct_array(layer_paths)
+    
+    # Use iMaker API definitions if no others have been specified
+    return _get_included_layers_from_imaker_api(config, parser)
+
+def _get_included_layers_from_imaker_api(config, parser):
+    try:
+        layer_str_list = (config.get_default_view().get_feature('imakerapi.cone_layers').get_value() or '').split(',')
+        # Make sure that empty layers definitions are ignored
+        layer_str_list = utils.distinct_array(layer_str_list)
+        if '' in layer_str_list:
+            layer_str_list.remove('')
+        
+        all_layers = config.list_configurations()
+        layerdefs = []
+        for layerstr in layer_str_list:
+            try:
+                layerdefs.append(all_layers[int(layerstr)])
+            except (ValueError, IndexError):
+                parser.error("Invalid layer index from iMaker API: %s" % layerstr)
+        return layerdefs
+    except exceptions.NotFound:
+        return []
+
 def print_summary(rep_data):
     """ Prints generation summary to logger and console. """
     print "\nGENERATION SUMMARY:"
     print "--------------------"
-    print "Refs in files: %s" % rep_data.nbr_of_refs
-    print "Refs with no implementation: %s" % rep_data.nbr_of_refs_noimpl
+    print "Refs in files: %s" % len(rep_data.context.changed_refs)
+    print "Refs with no implementation: %s" % len(rep_data.context.get_refs_with_no_output())
     print "Generation duration: %s" % rep_data.duration
     print "\n\n"
     
--- a/configurationengine/source/scripts/conesub_import_browserbookmarks.py.old	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/conesub_import_browserbookmarks.py.old	Tue Aug 10 14:29:28 2010 +0300
@@ -12,7 +12,10 @@
 #
 # Contributors:
 #
-# Description: 
+# Description:
+#
+## 
+# @author Teemu Rytkonen
 
 import os
 import logging
--- a/configurationengine/source/scripts/conesub_info.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/conesub_info.py	Tue Aug 10 14:29:28 2010 +0300
@@ -24,7 +24,7 @@
 from cone.public import api, plugin, utils, exceptions
 from cone.confml import persistentconfml
 from cone.storage.filestorage import FileStorage
-import report_util
+from cone.report import report_util
 
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
 
@@ -66,6 +66,7 @@
 }
 
 def main():
+    """ Get information about project / configurations. """
     shortcut_container = report_util.ReportShortcutContainer(REPORT_SHORTCUTS,
                                                              None)
     
@@ -147,11 +148,19 @@
                    metavar="FILE",
                    default=None)
     
+    info_group.add_option("--print-active-root",
+                   action="store_true",
+                   help="Print active root in the current project and exit.")
+    
     parser.add_option_group(info_group)
     
     (options, args) = parser.parse_args()
     cone_common.handle_common_options(options)
     
+    if options.print_active_root:
+        print_active_root(options)
+        sys.exit(0)
+    
     if not shortcut_container.is_valid_shortcut(options.report_type):
         parser.error("Invalid report type: %s" % options.report_type)
     if (options.report_type or options.template) and \
@@ -170,7 +179,7 @@
             print e
             sys.exit(1)
     
-    current = api.Project(api.Storage.open(options.project,"r"))
+    current = api.Project(api.Storage.open(options.project,"r", username=options.username, password=options.password))
     print "Opened project in %s" % options.project
     
     # Get a list of configurations if necessary
@@ -216,7 +225,7 @@
                               'api_data'    : ApiDataProvider(configs[0]),
                               'content_data': ContentDataProvider(configs[0]),
                               'value_data'  : ValueDataProvider(configs, view)}
-            report_util.generate_report(template, report, {'data': ReportDataProxy(data_providers)})
+            report_util.generate_report(template, report, {'data': ReportDataProxy(data_providers)}, [ROOT_PATH])
         else:
             # Printing configuration info
             config_name = config_list[0]
@@ -233,6 +242,14 @@
             print config
     if current: current.close()
 
+def print_active_root(options):
+    storage = api.Storage.open(options.project,"r", username=options.username, password=options.password)
+    active_root = storage.get_active_configuration()
+    if active_root:
+        print "Active root: %s" % active_root
+    else:
+        print "No active root."
+    
 
 # ============================================================================
 # Report data proxy and data providers
@@ -285,7 +302,7 @@
         Generate the actual report data. Called when get_data() is called
         the first time.
         """
-        raise NotImplmentedError()
+        raise NotImplementedError()
 
 # ----------------------------------------------------------------------------
 
@@ -368,9 +385,11 @@
             self.options = kwargs['options']
     
     class Config(object):
-        def __init__(self, path, values):
+        def __init__(self, name, path, values, refs):
+            self.name = name
             self.path = path
             self.values = values
+            self.refs = refs
     
     class SequenceColumn(object):
         def __init__(self, ref, name, type):
@@ -443,8 +462,9 @@
                         values[entry.ref] = self._resolve_value(feature)
                     except exceptions.NotFound:
                         pass
-                
-            output_configs.append(self.Config(config.get_path(), values))
+            # Get the feature refs from last layer
+            last_layer_refs = set(config.get_last_configuration().list_leaf_datas())
+            output_configs.append(self.Config(config.get_name(), config.get_path(), values, last_layer_refs))
         
         # Add a 'modified' attribute to all features
         for group in feature_groups:
@@ -640,7 +660,7 @@
 
 def _load_view_from_file(filename):
     """
-    Load the first view from the given ConfML file.
+    Load the last view from the given ConfML file.
     @raise ViewLoadError: An error occurred when loading the file.
     """
     file_abspath = os.path.abspath(filename)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/conesub_initvariant.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,265 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+import sys
+import logging
+import tempfile
+import os, re
+import shutil
+                          
+from optparse import OptionParser, OptionGroup
+import cone_common
+
+from cone.public import api, utils
+
+from conesub_merge import merge_config_root_to_config_root,\
+                          get_active_root_if_necessary,\
+                          MergePolicy, MergeFailedException
+                          
+from conesub_export import run_export
+
+VERSION = '1.0'
+
+logger    = logging.getLogger('cone')
+
+class  MetaNotFoundException(Exception):
+    pass    
+
+def find_variant_layers_to_merge(source_config, target_config, find_pattern):
+    """
+    Find all layers in the configuration that contain custvariant* in
+    their path name and return a list containing source->target mappings.
+    @param source_config: The source configuration object.
+    @param target_config: The target configuration object.
+    @param new_name: The new name to replace custvariant* in the
+        target path name with.
+    @return: A list of (source_layer, target_layer) tuples.
+    """
+    pattern = re.compile(find_pattern)
+    
+    result = []
+    for src in source_config.list_configurations():
+        m = pattern.match(src)
+        if m:
+            result.append(src)
+            
+    print "Found layers %r" % result
+    return result        
+
+def main(argv=sys.argv):
+    """ Initialize a variant from a cpf. """
+    parser = OptionParser(version="%%prog %s" % VERSION)
+    
+    parser.add_options(cone_common.COMMON_OPTIONS)
+
+    parser.add_option("-p", "--project",
+                       dest="project",
+                       help="Defines the location of current project. Default is the current working directory.",
+                       default=".",
+                       metavar="STORAGE")
+    
+    group = OptionGroup(parser, 'Initvariant options',
+                        'The initvariant action is intended for merging a variant CPF back into the '
+                        'configuration project, or creating a new empty variant based on an existing '
+                        'configuration. It merges all customer variant layers (layers with '
+                        'custvariant* in their path name) and renames them based on the variant ID '
+                        'and variant name ("custvariant_<id>_<name>").')
+    
+    group.add_option("-c", "--configuration",
+                        dest="configuration",
+                        help="Defines the name of the target configuration. By default the "
+                             "configuration file name is composed of product name, variant ID "
+                             "and variant name like this: <product>_custvariant_<id>_<name>_root.confml",
+                        metavar="CONFIG")
+    
+    group.add_option("-r", "--remote",
+                   dest="remote",
+                   help="Defines the location of remote storage (CPF)",
+                   metavar="STORAGE")
+    
+    group.add_option("-s", "--sourceconfiguration",
+                        dest="sourceconfiguration",
+                        help="Defines the name of the remote configuration inside the remote storage. "
+                             "Default is the active root of the remote project.",
+                        metavar="CONFIG")
+    
+    group.add_option("--variant-id", help="Variant ID, mandatory.")
+    group.add_option("--variant-name", help="Variant name, optional.")
+    group.add_option("--product-name",
+                     help="Product name, taken from the configuration data by default "
+                          "(i.e. defaults to '${imakerapi.productname}')",
+                     default="${imakerapi.productname}")
+    
+    group.add_option("--set-active-root",
+                     action="store_true",
+                     help="Set the newly created (or update) configuration root as the "
+                          "project's active root after the merge is done.")
+    
+    group.add_option("-b","--based-on-configuration",
+                     dest="boconfig",
+                   help="Defines the configuration root which is used as a base "
+                        "configuration for the new empty variant.")
+    
+    group.add_option("--find-layer-regexp",
+                     dest="find_pattern",
+                     default='.*/manual/.*|.*/configurator/.*',
+                     help="Defines the pattern which is used to find the layers "
+                          "from source configuration that will be merged"
+                          "Default: '.*/manual/.*|.*/configurator/.*' " )
+        
+    parser.add_option_group(group)
+    (options, _) = parser.parse_args(argv)
+    
+    cone_common.handle_common_options(options)
+    
+    # Check the passed options
+    if not options.remote and not options.boconfig:
+        parser.error("Remote project or based-on-configuration must be given")
+    if options.remote and options.boconfig:
+        parser.error("Only either remote project or based-on-configuration can be given, but not both")
+    if not options.variant_id:  parser.error("Variant ID must be given")
+    
+    temp_cpf_folder = None
+    
+    if options.boconfig:   
+        class ExportOptions(object):
+            pass
+            
+        path = ''
+        coreplat_name = ''
+        product = ''
+        
+        project = api.Project(api.Storage.open(options.project,"a", username=options.username, password=options.password))
+        config = project.get_configuration(options.boconfig)
+        meta = config.meta
+        
+        if meta:
+            for prop in meta.array:
+                if 'name' in prop.attrs and 'value' in prop.attrs:
+                    name = prop.attrs['name']
+                    if name == 'coreplat_name':
+                        coreplat_name =  prop.attrs['value']
+                    if name == 'product_name':
+                        product = prop.attrs['value']
+        
+        if not coreplat_name or not product:
+            print >>sys.stderr, "Could not find coreplat_name or product_name from meta data."
+            print >>sys.stderr, "Are you sure the given based-on-configuration is valid?"
+            sys.exit(2)
+        
+        path = coreplat_name + '/' + product        
+                    
+        temp_cpf_folder = tempfile.mkdtemp()
+        
+        export_options = ExportOptions()
+        export_options.project = options.project
+        export_options.remote = os.path.join(temp_cpf_folder, 'temp.cpf')
+        export_options.configs = [options.boconfig]
+        export_options.username = options.username
+        export_options.password = options.password
+        export_options.config_wildcards = None
+        export_options.config_regexes   = None
+        export_options.export_dir = None
+        export_options.exclude_content_filter = None
+        export_options.added = [path + '/customer/custvariant/manual/root.confml',
+                                path + '/customer/custvariant/configurator/root.confml']
+        export_options.exclude_empty_folders = False
+        export_options.action = None
+                
+        options.remote = export_options.remote
+        
+        print "Exporting variant CPF to a temporary directory"
+        run_export(export_options)
+
+    target_project = api.Project(api.Storage.open(options.project,"a", username=options.username, password=options.password))
+    source_project = api.Project(api.Storage.open(options.remote,"r", username=options.username, password=options.password))
+
+    print "Target project: %s" % options.project
+    print "Source project: %s" % options.remote
+    replace_dict = {"VAR_ID": options.variant_id, "VAR_NAME": options.variant_name}    
+    
+    try:
+        # Open the source configuration
+        source_config = get_active_root_if_necessary(source_project, options.sourceconfiguration, 'source')
+        source_config = source_project.get_configuration(source_config)
+        
+        # Determine the new name of the layer part (replaces 'custvariant[^/]*')
+        if options.variant_name:
+            new_name = "custvariant_%s_%s" % (options.variant_id, options.variant_name)
+        else:
+            new_name = "custvariant_%s" % options.variant_id
+        
+        # Determine the target configuration
+        if options.configuration:
+            target_config = options.configuration
+        else:
+            # Target configuration not given explicitly, automatically
+            # determine the name based on the product name and the new
+            # layer name
+            try:
+                product_name = utils.expand_refs_by_default_view(
+                    options.product_name,
+                    source_config.get_default_view(),
+                    catch_not_found = False)
+            except Exception, e:
+                print "Could not determine product name: %s" % e
+                sys.exit(2)
+            print "Product name:   %s" % product_name
+            target_config = "%s_%s_root.confml" % (product_name, new_name)
+        
+        
+        def find_layers(source_config, target_config):
+            ret_list = []
+            
+            layers = find_variant_layers_to_merge(source_config,
+                                                target_config,
+                                                options.find_pattern)            
+            p = re.compile(r'custvariant[^/]*')
+            for layer in layers:
+                tgt_layer = p.sub(new_name, layer) 
+                ret_list.append((layer, tgt_layer))
+            
+            return ret_list
+        
+        # Perform the merge
+        merge_config_root_to_config_root(
+            source_project      = source_project,
+            target_project      = target_project,
+            source_config       = options.sourceconfiguration,
+            target_config       = target_config,
+            layer_finder_func   = find_layers,
+            merge_policy        = MergePolicy.OVERWRITE_LAYER)
+        
+        if options.set_active_root:
+            target_project.get_storage().set_active_configuration(target_config)
+    except MergeFailedException, e:
+        print "Could not initialize variant: %s" % e
+        sys.exit(2)
+    else:
+        # Merge successful, so save the target project
+        # to persist the changes
+        target_project.save()
+    
+    target_project.close()
+    source_project.close()
+    
+    if temp_cpf_folder:
+        logger.debug("Removing temporary CPF directory '%s'" % temp_cpf_folder)
+        shutil.rmtree(temp_cpf_folder)
+    
+
+if __name__ == "__main__":
+    main()
--- a/configurationengine/source/scripts/conesub_merge.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/conesub_merge.py	Tue Aug 10 14:29:28 2010 +0300
@@ -116,6 +116,8 @@
         if confml_path not in already_included:
             print "Including %s in layer root %s" % (confml_path, targetconfig.path)
             targetconfig.include_configuration(confml_path)
+    
+    merge_metadata(sourceconfig, targetconfig)
 
 def find_layers_to_merge(layer_indices, rename, sourceconfig, targetconfig):
     """
@@ -150,7 +152,7 @@
 def sort_mergeconfigs(layers, sourceconfigs):
     """
     Return a correctly sorted list of source configuration layers.
-    @param layers: List of the indices of the layers to merg. Can be None, in
+    @param layers: List of the indices of the layers to merge. Can be None, in
         which case all layers are returned.
     @param sourceconfigs: List of all configuration layer root paths in the
         source project.
@@ -162,29 +164,40 @@
     sorted_configs = filter(lambda x: x != None, sorted_configs)
     return sorted_configs
 
+def merge_metadata(source_config, target_config):
+    # Merge (well, replace) configuration meta-data
+    if source_config.meta:
+        target_config.meta = source_config.meta._clone(recursion=True)
+    else:
+        del target_config.meta
+
+def get_active_root_if_necessary(project, configuration, name):
+    if configuration:
+        return configuration
+    else:
+        active_root = project.get_storage().get_active_configuration()
+        if active_root == "":
+            raise MergeFailedException("No %s configuration given and the project does not have an active root" % name)
+        else:
+            return active_root
+
 def merge_config_root_to_config_root(source_project, target_project,
                                      source_config, target_config,
-                                     layer_indices, rename,
+                                     layer_finder_func,
                                      merge_policy):
     """
     Merge the source configuration root to the target configuration root.
-    @param layer_indices: List of layer indices to specify the layers
-        to merge, can be None.
-    @param rename: If True, the merged layers are renamed based on the
-        name of the target configuration root.
+    
+    @param source_config: Name of the source configuration.
+    @param target_config: Name of the target configuration.
+    @param layer_finder_func: Function for finding the layers that are to be
+        merged. It should take source and target configuration objects as
+        arguments and return a list of tuples (layer_root, target_layer_root),
+        where layer_root is the path to the layer root in the source
+        configuration and target_layer_root the one in the target
+        configuration.
     @param merge_policy: The used merge policy.
     """
-    
-    def get_active_root_if_necessary(project, configuration, name):
-        if configuration:
-            return configuration
-        else:
-            active_root = project.get_storage().get_active_configuration()
-            if active_root == "":
-                raise MergeFailedException("No %s configuration given and the project does not have an active root" % name)
-            else:
-                return active_root
-    
     target_root = get_active_root_if_necessary(target_project, target_config, 'target')
     source_root = get_active_root_if_necessary(source_project, source_config, 'source')
     
@@ -214,11 +227,7 @@
                 target_config.create_configuration(sourcelayer_path)
     
     # Collect a correctly sorted list of all layer paths to merge
-    layers_to_merge = find_layers_to_merge(
-        layer_indices   = layer_indices,
-        rename          = rename,
-        sourceconfig    = source_config,
-        targetconfig    = target_config)
+    layers_to_merge = layer_finder_func(source_config, target_config)
     
     print "Merging %d layer(s)..." % len(layers_to_merge)
     
@@ -243,10 +252,11 @@
             target_layer = target_config.create_configuration(target_path)
         
         merge_configuration_layer(source_layer, target_layer, merge_policy)
-
-
+    
+    merge_metadata(source_config, target_config)
 
 def main(argv=sys.argv):
+    """ Merge a configuration/layer to the project. """
     parser = OptionParser(version="%%prog %s" % VERSION)
     
     parser.add_options(cone_common.COMMON_OPTIONS)
@@ -384,14 +394,20 @@
             if options.all: layer_indices = None
             else:           layer_indices = utils.distinct_array(options.layers)
             
+            def find_layers(source_config, target_config):
+                return find_layers_to_merge(
+                    layer_indices   = layer_indices,
+                    rename          = options.rename,
+                    sourceconfig    = source_config,
+                    targetconfig    = target_config)
+            
             merge_config_root_to_config_root(
-                source_project = source_project,
-                target_project = target_project,
-                source_config  = options.sourceconfiguration,
-                target_config  = options.configuration,
-                layer_indices  = layer_indices,
-                rename         = options.rename,
-                merge_policy   = options.merge_policy)
+                source_project      = source_project,
+                target_project      = target_project,
+                source_config       = options.sourceconfiguration,
+                target_config       = options.configuration,
+                layer_finder_func   = find_layers,
+                merge_policy        = options.merge_policy)
     except MergeFailedException, e:
         print "Could not merge: %s" % e
         sys.exit(2)
@@ -407,6 +423,3 @@
 
 if __name__ == "__main__":
     main()
-
-
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/conesub_packvariant.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,240 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+import os.path
+import sys
+import logging
+from optparse import OptionParser, OptionGroup
+import cone_common
+from cone.public import api
+from conesub_merge import get_active_root_if_necessary
+                          
+VERSION = '1.0'
+
+logger    = logging.getLogger('cone')
+
+def find_variant_layers(source_config):
+    """
+    Find all layers in the configuration that contain custvariant* in
+    their path name and return a list containing source->target mappings.
+    @param target_config: The target configuration object.
+    @param new_name: The new name to replace custvariant* in the
+        target path name with.
+    @return: A list of (source_layer, target_layer) tuples.
+    """
+    import re
+    pattern = re.compile(r'.*/(custvariant[^/]*)/.*')
+    result = []
+
+    for src in source_config.list_configurations():
+        m = pattern.match(src)
+        if m:
+            result.append(src)
+
+    return result
+    
+def get_metadatas_as_convertprojectml(configuration_root):
+    """
+    Creates lines for convertprojectml file from metadata items and also adds
+    version info to correct place. 
+    @param configuration_root: Configuration root object which contains metadatas.
+    @return: A list of metadata lines for convertprojectml.
+    """
+    metadatas = configuration_root.get_meta()
+    metadata_line = []
+    
+    for metadata in metadatas:
+        if metadata.ns == "http://www.s60.com/xml/confml/1" or metadata.ns == "http://www.s60.com/xml/confml/2":
+            if metadata.tag == 'release':
+                metadata_line.append("<" + metadata.tag + ">${convertproject.versioninfo}</" + metadata.tag + ">")
+            elif metadata.tag == 'version':
+                metadata_line.append("<" + metadata.tag + ">001</" + metadata.tag + ">")
+            else:
+                metadata_line.append("<" + metadata.tag + ">" + metadata.value + "</" + metadata.tag + ">")
+
+        if metadata.ns == "http://www.nokia.com/xml/cpf-id/1":
+            if metadata.attrs['name'] == 'sw_version':
+                metadata_line.append('<cv:configuration-property name="' + metadata.attrs['name'] + '" value="${convertproject.versioninfo}" />')
+            else:
+                metadata_line.append('<cv:configuration-property name="' + metadata.attrs['name'] + '" value="' + metadata.attrs['value'] + '" />')
+
+    return metadata_line
+    
+def get_layerlist_as_convertprojectml(configuration_root):
+    """
+    Creates lines for convertprojectml file from layer items in configurtion root
+    @param configuration_root: Configuration root object
+    @return: A list of layer lines for convertprojectml.
+    """
+    layer_line = []
+    layer_list = configuration_root.list_configurations()
+    
+    for layer_item in layer_list:
+        layer_line.append('<filter action="include_layer" data="' + layer_item + '"/>')
+    
+    return layer_line
+    
+def create_convertprojectml_file(conf_filename, conv_proj_filename, filepath,layerlist, metadatas, root_name):
+    """
+    Creates convertprojectml file for package
+    @param conf_filename: configuration root filename
+    @param conv_proj_filename: convertprojectml filename
+    @param filepath: path where file is created
+    @param layerlist: list of layers 
+    @param metadatas: list of metadatas
+    @param root_name: Name of configuration root
+    """
+
+    file_header = ['<?xml version="1.0" encoding="UTF-8"?>' + "\r\n", 
+                   '<convertprojectml xmlns="http://www.s60.com/xml/convertprojectml/1">' + "\r\n\r\n",
+                   '<targetProject path=""/>' + "\r\n",
+                   "\t" + '<layer path="">' + "\r\n",
+                   "\t\t" + '<file type="configuration_root" path="'+ conf_filename + '"']
+
+    #root_name can be empty so we need to check is there some content.
+    if root_name:
+        file_header.append(' configuration_name="' + root_name + '"')                 
+    file_header.append('>' + "\r\n")
+
+    file_footer = ["\t\t" + '</file>' + "\r\n",
+                   "\t" +'</layer>' + "\r\n",
+                   '</convertprojectml>'+ "\r\n"]
+
+    convert_file =  os.path.abspath(filepath + "/" + conv_proj_filename)
+    fh = open(convert_file,'wb')
+    fh.writelines(file_header)
+    fh.write("\t\t\t" + '<meta xmlns:cv="http://www.nokia.com/xml/cpf-id/1">' + "\r\n")
+
+    for meta_line in metadatas:
+        fh.write("\t\t\t\t" + meta_line + "\r\n")
+    fh.write("\t\t\t" + '</meta>' + "\r\n")
+
+    for layer_line in layerlist:
+        fh.write("\t\t\t" + layer_line + "\r\n")
+
+    fh.writelines(file_footer)
+    fh.close()
+    
+def main(argv=sys.argv):
+    """ Pack (zip) the variant layers of a configuration. """
+    parser = OptionParser(version="%%prog %s" % VERSION)
+    
+    parser.add_options(cone_common.COMMON_OPTIONS)
+
+    parser.add_option("-p", "--project",
+                       dest="project",
+                       help="Defines the location of current project. Default is the current working directory.",
+                       default=".",
+                       metavar="STORAGE")
+    
+    group = OptionGroup(parser, "Packvariant options",
+                        "The packvariant action is intended for packing variant to a zip-file for integration purposes.")
+    
+    group.add_option("-c", "--configuration",
+                        dest="configuration",
+                        help="Name of the configuration wanted to be packed.",
+                        metavar="CONFIG")
+    
+    group.add_option("-r", "--remote",
+                        dest="remote",
+                        help="Defines a location and a name of remote storage (ZIP)",
+                        metavar="STORAGE")
+    
+    group.add_option("-l", "--convert-location",
+                        dest="convertlocation",
+                        help="Defines a location of convertprojectml file."
+                        "Default location is <PROJECT>/convertpluginlayer/implml/",
+                        default="/convertpluginlayer/implml/")
+        
+    parser.add_option_group(group)
+    (options, _) = parser.parse_args(argv)
+    
+    cone_common.handle_common_options(options)
+    
+    # Check the passed options
+    if not options.remote:      parser.error("Target where variant package is placed must be given")
+    if not options.configuration:  parser.error("Configuration root to be packed must be given")
+    
+    try:
+        target_storage = api.Storage.open(options.remote,'w', username=options.username, password=options.password)
+        target_project = api.Project(target_storage)
+        source_storage = api.Storage.open(options.project,'r', username=options.username, password=options.password)
+ 
+        if not os.path.isdir(source_storage.get_path()):
+            print "ERROR: --Project must be a directory. Terminating the program."
+            sys.exit(1)
+        
+        source_project = api.Project(source_storage)
+        source_config = get_active_root_if_necessary(source_project, options.configuration, 'source')
+        source_config = source_project.get_configuration(source_config)
+        fname, _ = os.path.splitext(options.configuration)
+        conv_project_filename =  fname + ".convertprojectml"
+        print "Packing configuration: %s" % options.configuration
+        print "Source project: %s" % options.project
+        print "Target project: %s" % options.remote
+        
+        # Adding all files in layers
+        layer_list = find_variant_layers(source_config)
+
+        for add_layer in layer_list:
+            layer_config = source_project.get_configuration(add_layer)
+            layer = layer_config.get_layer()
+            path_part = layer.path + "/"
+            target_project.import_configuration(layer_config)
+            resource_list = layer_config.layer.list_all_resources(recurse=True)
+
+            for single_resource in resource_list:
+                parsed_path = path_part + single_resource
+                if source_storage.is_resource(parsed_path):
+                    logger.info("Adding file: %s" % parsed_path)
+                    target_storage.import_resources([parsed_path], source_storage)
+                if source_storage.is_folder(path_part + single_resource):
+                    logger.info("Adding folder: %s" % parsed_path)
+                    target_storage.create_folder(parsed_path)
+
+        layer_list = get_layerlist_as_convertprojectml(source_config)
+        metadata_list = get_metadatas_as_convertprojectml(source_config)
+        if not source_storage.is_folder(os.path.normpath(options.convertlocation + "/")):
+            source_storage.create_folder(os.path.normpath(options.convertlocation + "/"))
+        create_convertprojectml_file(options.configuration,
+                                     conv_project_filename,
+                                     options.project + "/"+ options.convertlocation + "/" ,
+                                     layer_list,
+                                     metadata_list,
+                                     source_config.get_name())
+
+        target_storage.import_resources([os.path.normpath(options.convertlocation + "/" +conv_project_filename)], source_storage) 
+    except Exception ,e:
+        print "Could not create Zip archive: %s" % e
+        sys.exit(2)
+
+    try:
+        target_storage.save()
+        source_project.close()
+        target_project.close()
+        
+        conv_path = (os.path.normpath(options.project + "/" + options.convertlocation + "/"))
+        conv_file_path = (os.path.normpath(conv_path + "/" + conv_project_filename))
+        
+        os.remove(conv_file_path)
+        os.removedirs(conv_path)
+    except:
+        pass  
+        
+
+
+if __name__ == "__main__":
+    main()
--- a/configurationengine/source/scripts/conesub_report.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/conesub_report.py	Tue Aug 10 14:29:28 2010 +0300
@@ -16,18 +16,18 @@
 
 import os
 import logging
-import pickle
 from optparse import OptionParser, OptionGroup
 import cone_common
-import generation_report
-from cone.public import api, plugin, utils, exceptions
+from cone.report import generation_report
 
 
 VERSION     = '1.0'
+ROOT_PATH = os.path.abspath(os.path.dirname(__file__))
 
 logger    = logging.getLogger('cone')
 
 def main():
+    """ Create report of existing report data. """
     parser = OptionParser(version="%%prog %s" % VERSION)
     
     parser.add_options(cone_common.COMMON_OPTIONS)
@@ -62,6 +62,16 @@
                    metavar="FILE",\
                    default="report.html")
     
+    group.add_option("--report-option",\
+                   action="append",
+                   help="Specifies the report verbose options, that defines "\
+                        "what data is included to the report. The option can be "\
+                        "used multiple times."\
+                        "choises=[default|all]"\
+                        "Example --report-option=all",
+                   metavar="OPTION",\
+                   default=[])
+
     group.add_option("-t", "--template",\
                    dest="template",\
                    action="store",
@@ -92,44 +102,22 @@
         parser.error("At least one input data file must be specified.")
     
     
-    class DataEntry(object):
-        def __init__(self, label, data):
-            self.label = label
-            self.data = data
     
     # Load all data files
-    data_entries = []
+    data_reports = []
     for data_file in files:
         print "Loading data file '%s'" % data_file
-        label = get_generation_run_label(data_file)
         data = generation_report.load_report_data(data_file)
-        data_entries.append(DataEntry(label, data))
+        data_reports.append(data)
     
     # Sort by time stamp
-    data_entries.sort(key=lambda entry: entry.data.generation_timestamp)
-    
-    # Use the first data object as the main report data
-    main_entry = data_entries[0]
+    data_reports.sort(key=lambda entry: entry.generation_timestamp)
     
-    # Merge the rest of the data objects into the main data
-    if len(data_entries) > 1:
-        # Update the generation_runs attribute of all implementations
-        # in the main data
-        for line in main_entry.data.lines:
-            for impl in line.impls:
-                impl.generation_runs = [main_entry.label]
-         
-        # Load other report data files and merge them to the main data object
-        for i in xrange(len(data_entries) - 1):
-            entry = data_entries[i + 1]
-            print "Merging data for '%s'" % entry.label
-            merge_report_data(main_entry.data, entry.data, entry.label)
- 
     # Generate the report
-    main_entry.data.report_filename = options.report
-    generation_report.generate_report(main_entry.data, options.report, options.template)
+    print "Generating report to '%s'" % options.report
+    generation_report.generate_report(data_reports, options.report, options.template, [ROOT_PATH], options.report_option)
     
-    print "Generated report to '%s'" % options.report
+    print "Done!'"
 
 def get_input_data_files(directory):
     files = []
@@ -138,69 +126,7 @@
         if os.path.isfile(path):
             files.append(path)
     return files
-    
 
-def get_generation_run_label(datafile_path):
-    filename = os.path.split(datafile_path)[1]
-    filename_noext = os.path.splitext(filename)[0]
-    return filename_noext
-
-def get_feature(rep_data, ref):
-    for feat in rep_data.lines:
-        if feat.ref == ref:
-            return feat
-    raise RuntimeError("Feature '%s' not found in refs with impl" % ref)
-
-def get_impl(rep_data, ref, impl_name):
-    feat = get_feature(rep_data, ref)
-    for impl in feat.impls:
-        if impl.name == impl_name:
-            return impl
-    raise RuntimeError("Impl '%s' not found for feature '%s'" % (impl_name, ref))
-
-def merge_report_data(data, data_to_merge, generation_run_label):
-    impls_by_ref = {}
-    for feat in data.lines:
-        impls_dict = {}
-        impls_by_ref[feat.ref] = impls_dict
-        for impl in feat.impls:
-            impls_dict[impl.name] = impl
-    
-    for feat in data_to_merge.lines:
-        if feat.ref in impls_by_ref:
-            # Feature has implementations in both report data objects
-            # -------------------------------------------------------
-            impls_dict = impls_by_ref[feat.ref]
-            
-            for impl in feat.impls:
-                if impl.name in impls_dict:
-                    # Same implementation in both: add the generation run to merge to the impl
-                    impl = get_impl(data, feat.ref, impl.name)
-                    impl.generation_runs.append(generation_run_label)
-                else:
-                    # Implementation only in the data to merge: add to the main data
-                    impl = get_impl(data_to_merge, feat.ref, impl.name)
-                    impl.generation_runs = [generation_run_label]
-                    feat = get_feature(data, feat.ref)
-                    feat.impls.append(impl)
-                    feat.nbr_impls += 1
-        else:
-            # Feature has implementations only in the data to merge
-            # -----------------------------------------------------
-            
-            # Add the feature and impls to the main data
-            feat = get_feature(data_to_merge, feat.ref)
-            for impl in feat.impls:
-                impl.generation_runs = [generation_run_label]
-            data.lines.append(feat)
-            data.nbr_of_refs += 1
-            
-            # Remove from features with no impl in the main data
-            for i, noimpl_feat in enumerate(data.ref_noimpl):
-                if feat.ref == noimpl_feat.ref:
-                    del data.ref_noimpl[i]
-                    data.nbr_of_refs_noimpl -= 1
-                    break
 
 if __name__ == "__main__":
     main()
--- a/configurationengine/source/scripts/conesub_update.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/conesub_update.py	Tue Aug 10 14:29:28 2010 +0300
@@ -21,7 +21,7 @@
 from optparse import OptionParser, OptionGroup
 
 import cone_common
-from cone.public import api, plugin, utils, exceptions
+from cone.public import api, plugin, utils, exceptions, container
 
 
 VERSION     = '1.0'
@@ -32,6 +32,7 @@
 logger    = logging.getLogger('cone')
 
 def main():
+    """ Update/set values to features in configuration(s). """
     parser = OptionParser(version="%%prog %s" % VERSION)
     
     parser.add_options(cone_common.COMMON_OPTIONS)
@@ -120,13 +121,29 @@
                         "Example --add-data \"KCRUidAvkon.KAknDefaultAppOrientation=1\"",
                    default=None) 
 
+    group.add_option("--add-configuration",\
+                   dest="configurations",\
+                   action="append",
+                   type="string",
+                   help="Include given configuration inside the updated configuration."\
+                        "Example --add-configuration \"test_configuration.confml\"",
+                   default=None) 
+
+    group.add_option("--add-policy",\
+                   dest="policy",\
+                   type="string",
+                   help="Define the data update policy, which can be append|prepend|replace."\
+                        "Example --add-configuration \"test_configuration.confml\" --add-policy=prepend"\
+                        "This would add the configuration as the first include to the target configuration.",
+                   default='append') 
+
     parser.add_option_group(group)
     (options, args) = parser.parse_args()
     
     cone_common.handle_common_options(options)
     
     # Open the project and find out the active configuration
-    project = api.Project(api.Storage.open(options.project, "a"))
+    project = api.Project(api.Storage.open(options.project, "a", username=options.username, password=options.password))
     try:
         active_root = project.get_storage().get_active_configuration()
     except AttributeError:
@@ -167,6 +184,10 @@
         if added_meta:      _add_meta(config, added_meta)
         if added_cpf_meta:  _add_cpf_meta(config, added_cpf_meta)
         if added_data:      _add_data(config, added_data)
+        
+        # Handle configuration additions
+        for configinc in options.configurations or []:
+            config.include_configuration(configinc, parse_policy(options.policy))
           
         # Handle description  
         if options.desc:        
@@ -215,7 +236,7 @@
             value = mo.group(2)
             result[name] = value
         else:
-            logger.error("Illegal %s definition: %s" % (entry_name, entry))
+            logger.error("Illegal %s definition: %s" % (entry_type_name, entry))
     return result
 
 def _add_meta(config, added_meta):
@@ -257,8 +278,28 @@
             config.get_default_view().get_feature(ref).set_value(value)
             logger.info("Set %s=%s" % (ref, value))
 
+def parse_policy(policy_str):
+    """
+    >>> parse_policy('replace')
+    0
+    >>> parse_policy('append')
+    1
+    >>> parse_policy('prepend')
+    2
+    """
+    if policy_str == 'append':
+        return container.APPEND
+    elif policy_str == 'replace':
+        return container.REPLACE
+    elif policy_str == 'prepend':
+        return container.PREPEND
+    else:
+        raise Exception('Could not parse policy string! %s' % policy_str)
+
 if __name__ == "__main__":
     main()
+    
+    
 
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/conesub_validate.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,298 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+import sys, os, shutil
+import logging
+from optparse import OptionParser, OptionGroup
+import cone_common
+from cone.report import report_util
+from cone.public import api, exceptions, utils, plugin, parsecontext
+import cone.validation.parsecontext
+import cone.validation.schemavalidation
+import cone.validation.implmlvalidation
+import cone.validation.confmlvalidation
+from cone.validation.problem_type_filter import ProblemTypeFilter
+
+ROOT_PATH = os.path.abspath(os.path.dirname(__file__))
+
+VERSION     = '1.0'
+
+logger    = logging.getLogger('cone')
+
+REPORT_SHORTCUTS = {
+    'xml': report_util.ReportShortcut(
+        os.path.join(ROOT_PATH, 'validation_report_template.xml'),
+        'validation_report.xml',
+        "Create a validation report of xml type."),
+    
+    'html': report_util.ReportShortcut(
+        os.path.join(ROOT_PATH, 'validation_report_template.html'),
+        'validation_report.html',
+        "Create a validation report of html type."),
+}
+
+def main():
+    """ Validate a configuration, or individual confml/implml files. """
+    shortcut_container = report_util.ReportShortcutContainer(REPORT_SHORTCUTS,
+                                                             'html')
+
+    parser = OptionParser(version="ConE validate %s" % VERSION)
+    
+    parser.add_options(cone_common.COMMON_OPTIONS)
+    
+    parser.add_option("-c", "--configuration",
+                        dest="configuration",
+                        help="Defines the name of the configuration for the action",
+                        metavar="CONFIG")
+
+    parser.add_option("-p", "--project",
+                       dest="project",
+                       default=".",
+                       help="defines the location of current project. Default is the "\
+                            "current working directory.",
+                       metavar="STORAGE")
+    
+    group = OptionGroup(parser, 'Validate options',
+                        'The validate action is intended for performing validation on a     '\
+                        'configuration or individual files.                                 ')
+    
+    group.add_option('--confml-file',
+                     action="append",
+                     help='Validate only the given single ConfML file.',
+                     metavar="FILE",
+                     default=None)
+    
+    group.add_option('--implml-file',
+                     action="append",
+                     help='Validate only the given single ImplML file.',
+                     metavar="FILE",
+                     default=None)
+        
+    group.add_option("--template",
+                     help="Template used in report generation. "\
+                          "Example: --template=report_template.html.",
+                     metavar="FILE",
+                     default=None)
+        
+    group.add_option("--report-type",
+                   help="The type of the report to generate. This is a convenience "\
+                        "switch for setting the used template. If --template is given, this option has no effect. "\
+                        "Possible values:                                        "\
+                        + shortcut_container.get_shortcut_help_text(),
+                   metavar="TYPE",\
+                   default=None)    
+    
+    group.add_option("--report",
+                   help="Specifies the location of the validation report. "\
+                        "Example --report=report.html.",
+                   metavar="FILE",
+                   default=None)
+    
+    group.add_option("--dump-schema-files",
+                     help="Dump the XML schema files used for validation into the specified directory.",
+                     metavar="DIR",
+                     default=None)
+
+    group.add_option("--exclude-filter",
+                     action="append",
+                     help="Exclude validation problems by given filter. "\
+                          "Examples: --exclude-filter=schema, --exclude-filter=schema.implml, --exclude-filter=schema.confml, --exclude-filter=schema.implml.ruleml",
+                     default=None)
+
+    group.add_option("--include-filter",
+                     action="append",
+                     help="Include validation problems by given filter."\
+                          "Examples: --include-filter=schema.implml, --include-filter=schema.implml.ruleml",
+                     default=None)
+
+    parser.add_option_group(group)
+    (options, _) = parser.parse_args()
+    
+    cone_common.handle_common_options(options)
+    
+    if not shortcut_container.is_valid_shortcut(options.report_type):
+        parser.error("Invalid report type: %s" % options.report_type)
+            
+    if options.dump_schema_files:
+        dump_dir = options.dump_schema_files
+        print "Dumping XML schema files to '%s'" % dump_dir
+        
+        cone.validation.schemavalidation.dump_schema_files(dump_dir)
+        return
+    
+    pt_filter = ProblemTypeFilter(includes = options.include_filter or [],
+                               excludes = options.exclude_filter or [])
+    
+    problems = []
+    if options.confml_file or options.implml_file:
+        if options.confml_file:
+            
+            func = cone.validation.schemavalidation.validate_confml_data
+            for file in options.confml_file:
+                problems.extend(validate_file(file, func))
+        if options.implml_file:
+            func = cone.validation.schemavalidation.validate_implml_data
+            for file in options.implml_file:
+                problems.extend(validate_file(file, func))
+    else:
+        problems = validate_configuration(options.project, options.configuration, pt_filter)
+    
+    if problems is not None:
+        filters = {'filter_by_severity':filter_by_severity}
+        problems = pt_filter.filter(problems)
+        
+        print "Total %d problem(s) after filtering" % len(problems)
+        
+        print "Generating report..."
+        problems.sort(key=lambda p: (p.severity, p.file, p.line))
+        template, report = shortcut_container.determine_template_and_report(
+            options.report_type,
+            options.template,
+            options.report,
+            'validation_report')
+        report_util.generate_report(template, report, {'problems': problems},extra_filters=filters)
+
+def extend_without_duplicates(source, target):
+    for item in source:
+        if item not in target:
+            target.append(item)
+
+def validate_file(filename, validator_func):
+    if not os.path.isfile(filename):
+        print "'%s' does not exist or is not a file!" % filename
+        return
+    else:
+        print "Validating file '%s'" % filename
+    
+    f = open(filename, 'rb')
+    try:        data = f.read()
+    finally:    f.close()
+    
+    problems = []
+    try:
+        validator_func(data)
+    except exceptions.ParseError, e:
+        problems.append(api.Problem.from_exception(e))
+    print "Found %d problem(s)" % len(problems)
+    
+    for p in problems:
+        p.file = filename
+    return problems
+
+def validate_configuration(project_path, config_path, problem_type_filter):
+    print "Project:       %s" % project_path
+    try:
+        project = api.Project(api.Storage.open(project_path, 'r'))
+    except exceptions.StorageException:
+        print "No such project."
+        return
+    
+    confml_parse_context = cone.validation.parsecontext.ValidationParseContext()
+    parsecontext.set_confml_context(confml_parse_context)
+    
+    if config_path is None:
+        config_path = project.get_storage().get_active_configuration()
+        if config_path is None:
+            print "Project does not have an active configuration, please specify the configuration using --configuration."
+            return
+    print "Configuration: %s" % config_path
+    
+    try:
+        config  = project.get_configuration(config_path)
+    except exceptions.NotFound:
+        print "No such configuration in project."
+        return
+    
+    result = []
+    
+    
+    print "Finding ConfML files in configuration..."
+    configs = config._traverse(type=api.Configuration)
+    print "%d ConfML file(s)" % len(configs)
+    print "%d problem(s) while parsing" % len(confml_parse_context.problems)
+    result.extend(confml_parse_context.problems)
+    
+    # Schema-validate ConfML files if not filtered out
+    if problem_type_filter.match('schema.confml'):
+        print "Performing XML schema validation on ConfML files..."
+        schema_problems = cone.validation.schemavalidation.validate_confml_file(config, config_path)
+        for conf in configs:
+            path = conf.get_full_path()
+            problems = cone.validation.schemavalidation.validate_confml_file(config, path)
+            schema_problems.extend(problems)
+        print "%d problem(s)" % len(schema_problems)
+        
+        # Add the schema problems with duplicates removed, since XML parse
+        # errors might have already been recorded in the ConfML parsing phase
+        extend_without_duplicates(source=schema_problems, target=result)
+    
+    
+    # Validate the ConfML model if not filtered out
+    validator_classes = cone.validation.confmlvalidation.get_validator_classes(problem_type_filter)
+    if validator_classes:
+        print "Validating ConfML model..."
+        model_problems = cone.validation.confmlvalidation.validate_configuration(config, validator_classes).problems
+        print "%d problem(s)" % len(model_problems)
+        result.extend(model_problems)
+        
+    
+    print "Finding ImplML files in configuration..."
+    impls = []
+    for file in config.get_layer().list_implml():
+        if plugin.ImplFactory.is_supported_impl_file(file):
+            impls.append(file)
+    print "Found %d supported files" % len(impls)
+    
+    # Schema-validate ImplML files if not filtered out
+    if problem_type_filter.match('schema.implml'):
+        print "Performing XML schema validation on ImplML files..."
+        schema_problems = []
+        for impl in impls:
+            probs = cone.validation.schemavalidation.validate_implml_file(config, impl)
+            schema_problems.extend(probs)
+        print "%d problem(s)" % len(schema_problems)
+        result.extend(schema_problems)
+    
+    # Validate the ImplML model if not filtered out
+    if problem_type_filter.match('model.implml'):
+        print "Parsing implementations..."
+        implml_parse_context = cone.validation.parsecontext.ValidationParseContext()
+        parsecontext.set_implml_context(implml_parse_context)
+        impl_set = plugin.create_impl_set(impls, config)
+        
+        # Add the model-level problems with duplicates removed, since XML parse
+        # errors might have already been recorded in the schema validation phase
+        extend_without_duplicates(source=implml_parse_context.problems, target=result)
+        
+        
+        validator_classes = cone.validation.implmlvalidation.get_validator_classes(problem_type_filter)
+        if validator_classes:
+            print "Validating implementations..."
+            impl_problems = cone.validation.implmlvalidation.validate_impl_set(impl_set, config, validator_classes)
+            print "%d problem(s)" % len(impl_problems)
+            result.extend(impl_problems)
+    
+    return result
+
+
+def filter_by_severity(problems, severity):
+    """
+    Filter problems by severity
+    """
+    return [p for p in problems if p.severity == severity]
+
+if __name__ == "__main__":
+    main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/configroot2flat.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,78 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+#!/usr/bin/env python
+## 
+# @author Teemu Rytkonen
+
+from optparse import OptionParser
+from cone.action import configroot2flat
+
+def get_parser():
+    parser = OptionParser()
+    parser.add_option("-c", "--configuration",
+                        dest="configs",
+                        action="append",
+                        help="Defines the name of the configuration for the action, can be "\
+                             "specified multiple times to include multiple configurations.",
+                        metavar="CONFIG",
+                        default=[])
+    
+    parser.add_option("--config-wildcard",
+                      action="append",
+                      dest="config_wildcards",
+                      help="Wildcard pattern for including configurations, e.g. "\
+                           "product_langpack_*_root.confml",
+                      metavar="WILDCARD",
+                      default=[])
+    
+    parser.add_option("--config-regex",
+                      action="append",
+                      dest="config_regexes",
+                      help="Regular expression for including configurations, e.g. "\
+                           "product_langpack_\\d{2}_root.confml",
+                      metavar="REGEX",
+                      default=[])
+    
+    parser.add_option("-p", "--project",\
+                       dest="project",\
+                       help="defines the location of current project. Default is the current working directory.",\
+                       default=".",\
+                       metavar="STORAGE")
+    return parser
+
+def main():
+    """ 
+    Configuration root flattener.
+    """
+    parser = get_parser()
+    options, _ = parser.parse_args()
+    
+    action = configroot2flat.ConeConfigroot2FlatAction(
+        project          = options.project,
+        configs          = options.configs,
+        config_wildcards = options.config_wildcards,
+        config_regexes   = options.config_regexes)
+        
+    try:
+        status = action.run()
+        if status:
+            action.save()
+            action.close()
+    except configroot2flat.Configroot2FlatFailed, e:
+        parser.error(str(e))
+    
+if __name__ == "__main__":
+    main()
\ No newline at end of file
--- a/configurationengine/source/scripts/crml_dc_report_template.html	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/crml_dc_report_template.html	Tue Aug 10 14:29:28 2010 +0300
@@ -4,7 +4,7 @@
 
     <h1>CRML Data Compatibility Report</h1><br>
     
-    <table class="report">
+    <table class="report" id="cdc_report">
       <tr>
         <td>Source:</td>
         <td>{{ data.sourcedata.name }}</td>
@@ -14,12 +14,18 @@
         <td>{{ data.targetdata.name }}</td>
       </tr>
     </table>
+    <script language="javascript" type="text/javascript">
+//<![CDATA[
+    setFilterGrid("cdc_report");
+//]]>
+</script>
+    
     
     <br/>
     
     <h2>Modified keys/files:</h2>
     
-    <table class="report">
+    <table class="report" id="mk_report">
     <tr>
         <th>File</th>
         <th>Repository UID</th>
@@ -60,11 +66,17 @@
         {% endif -%}
     {% endfor %}
     </table>
+    <script language="javascript" type="text/javascript">
+//<![CDATA[
+    setFilterGrid("mk_report");
+//]]>
+</script>
+    
     
     
     <h2>Added keys/files:</h2>
     
-    <table class="report">
+    <table class="report" id="ak_report">
     <tr>
         <th>File</th>
         <th>Repository UID</th>
@@ -92,11 +104,16 @@
         {% endif -%}
     {% endfor %}
     </table>
+    <script language="javascript" type="text/javascript">
+//<![CDATA[
+    setFilterGrid("ak_report");
+//]]>
+</script>
     
     
     <h2>Removed keys/files:</h2>
     
-    <table class="report">
+    <table class="report" id="rk_report">
     <tr>
         <th>File</th>
         <th>Repository UID</th>
@@ -124,11 +141,16 @@
         {% endif -%}
     {% endfor %}
     </table>
+    <script language="javascript" type="text/javascript">
+//<![CDATA[
+    setFilterGrid("rk_report");
+//]]>
+</script>
     
     
     <h2>Duplicate repositories:</h2>
     
-    <table class="report">
+    <table class="report" id="dr_report">
     <tr>
         <th>Repository UID</th>
         <th>Files in source</th>
@@ -149,4 +171,10 @@
         {% endif -%}
     {% endfor %}
     </table>
+    <script language="javascript" type="text/javascript">
+//<![CDATA[
+    setFilterGrid("dr_report");
+//]]>
+</script>
+    
 {% endblock %}
--- a/configurationengine/source/scripts/gen_report_template.html	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/gen_report_template.html	Tue Aug 10 14:29:28 2010 +0300
@@ -1,6 +1,7 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
 <html lang="en">
 <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> 
     <title>ConE generation report</title>
     <style type="text/css">
         body {
@@ -110,331 +111,409 @@
             font: Tahoma, Verdana, Arial;
             _font-size: 0.8em;
         }
-
+        div.popup  {
+            background-color: #f9fafd;
+            font: #595a5f Tahoma, Verdana, Arial bold;
+            font-size: 0.8em;
+            border-top: 1px #9d9da1;
+            border-bottom: 1px #9d9da1;
+        }
+        div.floater  {
+            text-align: left; 
+            width: 50%; 
+            float: left;
+        }
+        div.floater-right  {
+            text-align: right; 
+            width: 50%; 
+            float: right;
+        }
+        table.log {
+            word-wrap: break-word;
+            border: 1px #EBEBEB;
+            padding: 5px;
+            border-style: solid; 
+            vertical-align: top;
+            font: #595a5f Tahoma, Verdana, Arial;
+            font-size: 0.8em;
+        }
         .currentValue {
             background-color: #e8f2fe;
         }
     </style>
+    <script language="javascript" type="text/javascript">
+    //<![CDATA[
+    {% include 'tablefilter.js' without context %}
+    //]]>
+    </script>
+    
+    <script language="javascript" type="text/javascript">
+    //<![CDATA[
+    {% include 'popup.js' without context %}
+    //]]>
+    </script>
+
 </head>
 <body>
 
     <h1>Generation summary:</h1>
     <table class="summary">
-     <tr>
-        <th class="featureName" colspan="2">Statistics</th>
-     </tr>
-     <tr>
+    <tr>
+        <th class="featureName">Statistics</th>
+        {% for report in rep_data -%}
+        <th class="featureName">{{ report.label }}</th>
+        {% endfor -%}
+    </tr>
+    <tr>
         <td>Refs in files</td>
-        <td>{{ rep_data.nbr_of_refs }}</td>
+        {% for report in rep_data -%}
+        <td>{{ report.context.changed_refs|length }}</td>
+        {% endfor -%}
     </tr>
     <tr>
-        <td>Refs with no implementation</td>
-        <td>{{ rep_data.nbr_of_refs_noimpl }}</td>
+        <td>Not generated Refs</td>
+        {% for report in rep_data -%}
+        <td>{{ report.context.get_refs_with_no_output()|length }}</td>
+        {% endfor -%}
     </tr>
     <tr>
-        <th class="featureName" colspan="2">Details</th>
-     </tr>
+        <th class="featureName" colspan="{{ rep_data|length + 1 }}">Details</th>
+    </tr>
     <tr>
         <td>Report generated</td>
-        <td>{{ rep_data.generation_time }}</td>
+        {% for report in rep_data -%}
+        <td>{{ report.generation_time }}</td>
+        {% endfor -%}
     </tr>
     <tr>
         <td>Generation duration</td>
-        <td>{{ rep_data.duration }}</td>
+        {% for report in rep_data -%}
+        <td>{{ report.duration }}</td>
+        {% endfor -%}
     </tr>
     <tr>
         <td>Generation log</td>
-        <td><a href="file:{{ rep_data.cwd|pathname_to_url }}/cone.log">cone.log</a></td>
+        {% for report in rep_data -%}
+        <td><a href="file:{{ report.context.log_file|pathname_to_url }}">cone log</a></td>
+        {% endfor -%}
     </tr>
     <tr>
-        <th class="featureName" colspan="2">Generation options</th>
+        <th class="featureName" colspan="{{ rep_data|length + 1 }}">Generation options</th>
     </tr>
     <tr>
         <td align="left">Layers</td>
-        <td align="left">{{ rep_data.options.layers }}</td>
+        {% for report in rep_data -%}
+        <td align="left">{{ report.options.layers }}</td>
+        {% endfor -%}
     </tr>
     <tr>
         <td align="left">Added</td>
-        <td align="left">{{ rep_data.options.added }}</td>
+        {% for report in rep_data -%}
+        <td align="left">{{ report.options.added }}</td>
+        {% endfor -%}
     </tr>
     <tr>
         <td align="left">Dryrun</td>
-        <td align="left">{{ rep_data.options.dryrun }}</td>
+        {% for report in rep_data -%}
+        <td align="left">{{ report.options.dryrun }}</td>
+        {% endfor -%}
     </tr>
     <tr>
         <td align="left">Verbose</td>
-        <td align="left">{{ rep_data.options.verbose }}</td>
+        {% for report in rep_data -%}
+        <td align="left">{{ report.options.verbose }}</td>
+        {% endfor -%}
     </tr>
     <tr>
         <td align="left">Overrides</td>
-        <td align="left">{{ rep_data.options.overrides }}</td>
+        {% for report in rep_data -%}
+        <td align="left">{{ report.options.overrides }}</td>
+        {% endfor -%}
     </tr>
     <tr>
         <td align="left">Project</td>
-        <td align="left">{{ rep_data.options.project }}</td>
+        {% for report in rep_data -%}
+        <td align="left">{{ report.options.project }}</td>
+        {% endfor -%}
     </tr>
         <tr>
         <td align="left">Report</td>
-        <td align="left">{{ rep_data.options.report }}</td>
+        {% for report in rep_data -%}
+        <td align="left">{{ report.options.report }}</td>
+        {% endfor -%}
     </tr>
     <tr>
         <td align="left">Impls</td>
-        <td align="left">{{ rep_data.options.impls }}</td>
+        {% for report in rep_data -%}
+        <td align="left">{{ report.options.impls }}</td>
+        {% endfor -%}
+    </tr>
+    <tr>
+        <td align="left">Tags</td>
+        {% for report in rep_data -%}
+        <td align="left">{{ report.context.tags }}</td>
+        {% endfor -%}
     </tr>
     <tr>
         <td align="left">Output</td>
-        <td align="left">{{ rep_data.options.output }}</td>
+        {% for report in rep_data -%}
+        <td align="left">{{ report.options.output }}</td>
+        {% endfor -%}
     </tr>
     <tr>
         <td align="left">Configuration</td>
-        <td align="left">{{ rep_data.options.configuration }}</td>
-    </tr>
-    <tr>
-        <td align="left">Working directory</td>
-        <td align="left">{{ rep_data.cwd }}</td>
+        {% for report in rep_data -%}
+        <td align="left">{{ report.options.configuration }}</td>
+        {% endfor -%}
     </tr>
     </table>
     
-    <h1>Rule execution results:</h1><br>
-    
-    <table class="report">
-        <tr>
-            <th class="featureName">File</th>
-            <th class="featureName">Rule No.</th>
-            <th class="featureName">Input refs</th>
-            <th class="featureName">Affected refs</th>
-        </tr>
+    <h1>Generation Outputs:</h1><br>
+    <p>Predefined filters:<br>
+        <FORM>
+        <INPUT type="button" value="Refs with no implementation" onclick="tf_outputs.SetFilterValue(1,'None');tf_outputs.SetFilterValue(0, '');tf_outputs.SetFilterValue(2, '');tf_outputs.Filter();return false;" name="Refs with no implementation"">
+        <br>
+        <INPUT type="button" value="Refs with not output" onclick="tf_outputs.SetFilterValue(2, 'None');tf_outputs.SetFilterValue(0, '');tf_outputs.SetFilterValue(1, '');tf_outputs.Filter();return false;" name="Refs with not output">
+        </FORM>
+    </p>
+    <table class="report" id="outputs">
+    <tr>
+        <th class="featureName">Settings</th>
+        <th class="featureName">Impl. file</th>
+        <th class="featureName">Outputs</th>
+    </tr>
+
+    {% macro popup_link(source, linkid, linkname) -%}
+        {% if 'all' in report_options %}
+            <a href="#" onclick="Showpopup({{source}}, '{{linkid}}');return false;">{{ linkname }}</a>
+        {% else %}
+           {{ linkname }}
+        {% endif %}
+    {%- endmacro %}
+
+    {% macro get_report_colums(reports_list, report_elem) -%}        
+    {%- endmacro %}
+
+    <!-- process the output files -->    
+    {% for out in merged_context.get_output() %}
+    <tr>
+        <td>
+            {%- if out.implementation.get_refs() %}
+                {%- for ref in out.implementation.get_refs() %}
+                   {%- if ref in merged_context.changed_refs %}                  
+                     {%- if ref in merged_context.temp_features %}
+                       <i>{{ popup_link('this', ref+'.apidiv',ref) }}</i><br>
+                     {%- else %}
+                       <B>{{ popup_link('this', ref+'.apidiv', ref) }}</B><br>
+                     {%- endif %}
+                   {%- else %}
+                     {{ ref }}<br>
+                   {%- endif %}
+                {%- endfor %}
+            {%- endif %}
+        </td>
+        <td>
+          {%- if out.type == 'ref' %}
+            Rule: 
+          {%- elif out.type == 'exception'  %}
+            Exception: 
+          {%- endif  %}
+          {{ popup_link('this',out.implementation.ref|replace("/", ".") +':'+out.implementation.lineno|string+'.impldiv',out.implementation.ref+':'+out.implementation.lineno|string) }}
+        </td>
+        <td>
+        {%- if out.name != None and out.type != 'exception' %}
+        {{ popup_link('this',out.name|replace("/", ".")|replace("\\", ".")+'.output',out.name) }}
+        {%- else %}
+            <span class="red">None</span><br>
+        {%- endif %}
+        </td>
+    </tr>
+    {%- endfor %}
+            
+    <!-- process the refs with no output -->    
+    {%- for ref in merged_context.get_refs_with_no_output(merged_context.get_changed_refs(operation='intersection',ignore_temps=True)) %}
+    <tr>
+        <td>
+          <B>
+            {{ popup_link('this',ref+'.apidiv',ref) }}
+          </B><br>
+        </td>
+        <td>
+          {%- if merged_context.impl_set.get_implementations_with_ref(ref) %}    
+              {%- for impl in merged_context.impl_set.get_implementations_with_ref(ref) %}
+                {{ popup_link('this',impl.ref|replace("/", ".")|replace("\\", ".")+'.impldiv',impl.ref) }}
+              {%- endfor %}
+          {%- else %}
+            <span class="red">None</span><br>           
+          {%- endif %}
+        </td>
+        <td>
+            <span class="red">None</span><br> 
+        </td>
+    </tr>
+    {%- endfor %}
+
+    </table>
         
-        {% for result in rep_data.rule_exec_results %}
-        {#- Report only rule executions that affected something #}
-        {%- if result.affected_refs|length > 0 %}
-        <tr>
-            <a name="rule:{{result.source}}:{{result.index}}"/>
-            <td><a href="file:{{ rep_data.project_dir|pathname_to_url }}/{{ result.source|pathname_to_url }}">{{ result.source }}</a></td>
-            <td>{{result.index}}</td>
-            <td>
-            {%- for ref in result.input_refs -%}
-                {{ref}}<br/>
-            {% endfor %}
-            </td>
-            <td>
-            {%- for ref in result.affected_refs -%}
-                {{ref}}<br/>
-            {% endfor %}
-            </td>
-        </tr>
-        {% endif -%}
+    <!-- Create extra data divs only when debug is on -->        
+    {% if 'all' in report_options %}
+        <!-- Create data divs for feature ref elements -->
+        {%- for feat in merged_context.features.get_features(merged_context.changed_refs) %}
+            <div id="{{ feat.fqr|replace("/", ".")  }}.apidiv" style="background-color:#f9fafd;border:1px solid black;display:none;padding:2px;width:50%;">
+                <table class="report">
+                <tr><td>
+                    <div class="floater"><b>Ref:</b>{{ feat.fqr }}</div> 
+                    <div class="floater-right"><a href="#" onclick="Popup.hide('{{ feat.fqr }}.apidiv');return false;">Close</a></div>
+                </td></tr>
+                <tr><td>
+                    <div>
+                        <b>Name: </b>{{ feat.name }}<br>
+                        <b>Type: </b>{{ feat.type }}<br>
+                        <b>ConfML: </b><a href="file:{{ rep_data[0].project_dir|pathname_to_url }}/{{ feat.get_proxied_obj().get_configuration_path()|pathname_to_url }}">{{ feat.get_proxied_obj().get_configuration_path() }}</a>
+                    </div>
+                </tr></td>
+                </table>
+                <b>Data: </b>
+                <table class="report">
+                {%- if feat.is_sequence_root() %}
+                    <tr>
+                      {%- for columnfea in feat.get_column_features() %}
+                      <th class="th.header">{{ columnfea.ref }}</th>
+                      {%- endfor %}
+                    </tr>
+                    {%- for row in feat.get_value() %}
+                       <tr>
+                        {%- for col in row %}
+                            <td>{{ col|e|xml_charref_replace  }}</td>
+                        {%- endfor %}
+                       </tr>
+                    {%- endfor %}
+                {%- else %}
+                    {%- for data in feat.get_datas() %}
+                        {% if loop.first %}
+                            <tr>
+                                <th class="th.header">Layer</th>
+                                <th class="th.header">Value</th>
+                            </tr>
+                        {% endif -%}    
+                        {% if not data.template %}
+                            <tr>
+                                <td><a href="file:{{ rep_data[0].project_dir|pathname_to_url }}/{{ data.get_configuration_path()|pathname_to_url }}">{{ data.get_configuration_path() }}</a></td>
+                                <td>{{ data.get_value()|e|xml_charref_replace  }}</td>
+                            </tr>
+                        {% endif -%}
+                    {% endfor %}
+                {% endif -%}
+                </table>
+            </div>
+        {%- endfor %}
+    
+        <!-- Create data divs for generation output elements -->
+        {% for output in merged_context.outputs.values() %}
+            <div id="{{ output.name|replace("/", ".")|replace("\\", ".") }}.output" style="background-color:#f9fafd;border:1px solid black;display:none;padding:2px;width:50%;">
+                <table class="report">
+                <tr><td>
+                    <div class="floater"><b>Ref:</b>{{ output.name }}</div> 
+                    <div class="floater-right"><a href="#" onclick="Popup.hide('{{ output.name|replace("/", ".")|replace("\\", ".") }}.output');return false;">Close</a></div>
+                </td></tr>
+                <tr><td>
+                    <div>
+                        <b>Implml: </b>{{ output.implementation }}<br>
+                        <b>Type: </b>{{ output.type }}<br>
+                        {% if output.type == 'file' %}
+                        <b>File: </b><a href="file:{{ output.abspath|pathname_to_url }}">{{ output.name }}</a><br>
+                        {% elif output.type == 'ref' %}
+                        <b>Target ref: </b>{{ output.name }} <a href="#" onclick="tf_outputs.SetFilterValue(0, '{{output.name}}');tf_outputs.SetFilterValue(1, '');tf_outputs.SetFilterValue(2, '');tf_outputs.Filter();return false;">filter</a><br>
+                        {% elif output.type == 'exception' %}
+                        <b>Exception: </b>{{ output.exception }}<br>
+                        {% endif %}
+                        <b>Related log entries: </b><br>
+                        <table class="log">
+                        {% for log in merged_context.grep_log(output.filename) -%}
+                        <tr><td>{{ log[0] }}</td><td>{{ log[1] }}</td></tr>
+                        {% endfor -%}
+                        </table>
+                    </div>
+                </tr></td>
+                </table>
+            </div>
+        {% endfor %}
+    
+        <!-- Create data divs for generation specific implementation elements -->
+        {% for output in merged_context.outputs.values() %}
+            <div id="{{ output.implementation.ref|replace("/", ".") }}:{{ output.implementation.lineno }}.impldiv" style="background-color:#f9fafd;border:1px solid black;display:none;padding:2px;width:50%;">
+                <table class="report">
+                <tr><td>
+                    <div class="floater"><b>Ref:</b>{{ output.name }}</div> 
+                    <div class="floater-right"><a href="#" onclick="Popup.hide('{{ output.implementation.ref|replace("/", ".") }}:{{ output.implementation.lineno }}.impldiv');return false;">Close</a></div>
+                </td></tr>
+                <tr><td>
+                    <div>
+                        <b>Implml: </b>{{ output.implementation }}<br>
+                        <b>Type: </b>{{ output.implementation.__class__.__name__ }}<br>
+                        <b>File: </b><a href="file:{{ [rep_data[0].project_dir,output.implementation.ref]|join('/')|pathname_to_url }}">{{ output.implementation.ref }}</a><br>
+                        <b>Line: </b>{{output.implementation.lineno}}<br>
+                        {% if output.type == 'exception' %}
+                        <b>Exception: </b>{{ output.exception }}<br>
+                        {% endif %}
+                        <b>Related log entries: </b><br>
+                        <table class="log">
+                        {% for log in merged_context.grep_log(output.implementation.ref) -%}
+                        <tr><td>{{ log[0] }}</td><td>{{ log[1] }}</td></tr>
+                        {% endfor -%}
+                        </table>
+                    </div>
+                </tr></td>
+                </table>
+            </div>
         {% endfor %}
         
-    </table>
-    
-    
-    <h1>Output files:</h1><br>
-    
-    <table class="report">
-    <tr>
-        <th class="featureName">API</th>
-        <th class="featureName">Data</th>
-        <th class="featureName">Impl. file</th>
-        <th class="featureName">Impl. type</th>
-        <th class="featureName">Generated for</th>
-        <th class="featureName">Output files</th>
-    </tr>
-    {% for feat in rep_data.lines %}
+        <!-- Create data divs for implementation elements -->
+        {% for impl in merged_context.impl_dict.values() %}
+            <div id="{{ impl.ref|replace("/", ".")|replace("\\", ".") }}.impldiv" style="background-color:#f9fafd;border:1px solid black;display:none;padding:2px;width:50%;">
+                <table class="report">
+                <tr><td>
+                    <div class="floater"><b>Ref:</b>{{ impl.ref|replace("/", ".")|replace("\\", ".") }}}</div> 
+                    <div class="floater-right"><a href="#" onclick="Popup.hide('{{ impl.ref|replace("/", ".")|replace("\\", ".") }}.impldiv');return false;">Close</a></div>
+                </td></tr>
+                <tr><td>
+                    <div>
+                        <b>Implml: </b><a href="file:{{ [rep_data[0].project_dir,impl.ref]|join('/')|pathname_to_url }}">{{ impl.ref }}</a><br>
+                        <b>Type: </b>{{ impl.__class__.__name__ }}<br>
+                        <b>Related log entries: </b><br>
+                        <table class="log">
+                        {% for log in merged_context.grep_log(impl.ref) -%}
+                        <tr><td>{{ log[0] }}</td><td>{{ log[1] }}</td></tr>
+                        {% endfor -%}
+                        </table>
     
-        <tr>
-            <td align="left" rowspan={{ feat.nbr_impls }}>
-                {% if feat.is_temp_feature -%}
-                <b><i>{{ feat.ref }}</i></b><br>
-                {%- else -%}
-                <b>{{ feat.ref }}</b><br>
-                {%- endif %}
-                <b>Name: </b>{{ feat.feat_name }}<br>
-                <b>Type: </b>{{ feat.feat_type }}<br>
-                <b>ConfML: </b><a href="file:{{ rep_data.project_dir|pathname_to_url }}/{{ feat.config_path|pathname_to_url }}">{{ feat.config_path }}</a>
-            </td>
-            <td align="left" rowspan={{ feat.nbr_impls }}>
-            <table class="report">
-            
-            {% for data in feat.datas %}
-                {% if loop.first %}
-                    <tr>
-                        <th class="th.header">Layer</th>
-                        <th class="th.header">Value</th>
-                    </tr>
-                    <tr>
-                        <td><a href="file:{{ rep_data.project_dir|pathname_to_url }}/{{ data.layer|pathname_to_url }}">{{ data.layer }}</a></td>
-                        <td>{{ data.value|e|xml_charref_replace }}</td>
-                    </tr>
-                {% else %}
-                    <tr>
-                        <td><a href="file:{{ rep_data.project_dir|pathname_to_url }}/{{ data.layer|pathname_to_url }}">{{ data.layer }}</a></td>
-                        <td>{{ data.value|e|xml_charref_replace  }}</td>
-                    </tr>
-                {% endif %}
-            {% endfor %}
-            </table>
-
-            <table class="report">
-                {% for data in feat.seq_data %}
-                    {% if loop.first %}
-                        <tr>
-                            <th class="th.header">Setting</th>
-                            <th class="th.header">Value</th>
-                        </tr>
-                        <tr>
-                            <td><b>{{ data[0]|e|xml_charref_replace }}</b></td>
-                            <td>
-                                {% for value in data[1] %}
-                                    {{ value|e|xml_charref_replace }}<br>
-                                {% endfor %}
-                            </td>
-                        </tr>
-                    {% else %}
-                        <tr>
-                            <td><b>{{ data[0]|e|xml_charref_replace }}</b></td>
-                            <td>
-                                {% for value in data[1] %}
-                                    {{ value|e|xml_charref_replace }}<br>
-                                {% endfor %}
-                            </td>
-                        </tr>
-                    {% endif %}
-                {% endfor %}
-            </table>
+                    </div>
+                </tr></td>
+                </table>
+            </div>
+        {% endfor %}
+    {% endif %} <!-- verbose 3 -->
+        
+    <script language="javascript" type="text/javascript">
+        //<![CDATA[
+             var output_Props =  {  
+                     paging: false,
+                     highlight_keywords: true,                      
+                     rows_counter: true,  
+                     rows_counter_text: "Rows:",  
+                     btn_reset: true,  
+                     loader: true,  
+                     loader_text: "Filtering data..."  
+                 }; 
+            setFilterGrid("outputs", output_Props);
             
-            {% for impl in feat.impls %}
-                {% if loop.first %}
-                    <td align="left">
-                        <a href="file:{{ rep_data.project_dir|pathname_to_url }}/{{ impl.name|pathname_to_url }}">{{ impl.name }}</a>
-                    </td>
-                    <td align="left">
-                        {{ impl.type }}
-                    </td>
-                    <td align="left">
-                        {{ ', '.join(impl.generation_runs) }}
-                    </td>
-                    <td align="left">
-                        {% for output in impl.outputfiles -%}
-                            {% if output.exists %}
-                                <a href="file:{{ output.abs_filename|pathname_to_url }}">{{ output.filename }}</a><br>
-                            {% else %}
-                                <span class="red">{{ output.filename }}</span><br>
-                            {% endif %}
-                        {%- endfor %}
-                    </td>
-                {% else %}
-                    <tr>
-                    <td align="left">
-                        <a href="file:{{ rep_data.project_dir|pathname_to_url }}/{{ impl.name|pathname_to_url }}">{{ impl.name }}</a>
-                    </td>
-                    <td align="left">
-                        {{ impl.type }}
-                    </td>
-                    <td align="left">
-                        {{ ', '.join(impl.generation_runs) }}
-                    </td>
-                    <td align="left">
-                        {% for output in impl.outputfiles %}
-                            {% if output.exists %}
-                                <a href="file:{{ output.abs_filename|pathname_to_url }}">{{ output.filename }}</a><br>
-                            {% else %}
-                                <span class="red">{{ output.filename }}</span><br>
-                            {% endif %}
-                        {% endfor %}
-                    </td>
-                    </tr>
-                {% endif %}
-                
-            {% endfor %}
-        </tr>
-    {% endfor %}    
-    </table>
+            function Showpopup(item_over, popup_ref)
+            {
+                Popup.show(popup_ref, item_over,'top left', {'offsetTop':20});
+            } 
+        //]]>
+    </script>
 
-    <h1>Refs with no implementation:</h1><br>
-    
-    <table class="report">
-    <tr>
-        <th class="featureName">API</th>
-        <th class="featureName">Data</th>
-    </tr>
-    {% for feat in rep_data.ref_noimpl %}
-        <tr>
-            <td align="left" >
-                {% if feat.is_temp_feature -%}
-                <b><i>{{ feat.ref }}</i></b><br>
-                {%- else -%}
-                <b>{{ feat.ref }}</b><br>
-                {%- endif %}
-                <b>Name: </b>{{ feat.feat_name|e|xml_charref_replace }}<br>
-                <b>Type: </b>{{ feat.feat_type|e|xml_charref_replace }}<br>
-                <b>ConfML: </b><a href="file:{{ rep_data.project_dir|pathname_to_url }}/{{ feat.config_path|pathname_to_url }}">{{ feat.config_path }}</a>
-            </td>
-            <td align="left">
-            <table class="report">
-            
-            {% for data in feat.datas %}
-                {% if loop.first %}
-                    <tr>
-                        <th class="th.header">Layer</th>
-                        <th class="th.header">Value</th>
-                    </tr>
-                    <tr>
-                        <td><a href="file:{{ rep_data.project_dir|pathname_to_url }}/{{ data.layer|pathname_to_url }}">{{ data.layer }}</a></td>
-                        <td>{{ data.value|e|xml_charref_replace }}</td>
-                    </tr>
-                {% else %}
-                    <tr>
-                        <td><a href="file:{{ rep_data.project_dir|pathname_to_url }}/{{ data.layer|pathname_to_url }}">{{ data.layer }}</a></td>
-                        <td>{{ data.value|e|xml_charref_replace }}</td>
-                    </tr>
-                {% endif %}
-            {% endfor %}
-            </table>
-            
-            <table class="report">
-                {% for data in feat.seq_data %}
-                    {% if loop.first %}
-                        <tr>
-                            <th class="th.header">Setting</th>
-                            <th class="th.header">Value</th>
-                        </tr>
-                        <tr>
-                            <td><b>{{ data[0] }}</b></td>
-                            <td>
-                                {% for value in data[1] %}
-                                    {{ value|e|xml_charref_replace }}<br>
-                                {% endfor %}
-                            </td>
-                        </tr>
-                    {% else %}
-                        <tr>
-                            <td><b>{{ data[0] }}</b></td>
-                            <td>
-                                {% for value in data[1] %}
-                                    {{ value|e|xml_charref_replace }}<br>
-                                {% endfor %}
-                            </td>
-                        </tr>
-                    {% endif %}
-                {% endfor %}
-            </table>
-        </tr>
-    {% endfor %}    
-    </table>
-    <h1>Not generated output files:</h1><br>
-    
-    <table class="report">
-    <tr>
-        <th class="featureName">Output file</th>
-    </tr>
-    {% for file in rep_data.missing_output_files %}
-        <tr>
-            <td align="left" >
-                {{ file.filename }}
-            </td>
-    {% endfor %}
-    </table>
     
 </body>
-</html>
+</html>
\ No newline at end of file
--- a/configurationengine/source/scripts/generation_report.py	Fri Mar 12 08:30:17 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,315 +0,0 @@
-#
-# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
-# All rights reserved.
-# This component and the accompanying materials are made available
-# under the terms of "Eclipse Public License v1.0"
-# which accompanies this distribution, and is available
-# at the URL "http://www.eclipse.org/legal/epl-v10.html".
-#
-# Initial Contributors:
-# Nokia Corporation - initial contribution.
-#
-# Contributors:
-#
-# Description:
-#
-
-import os, logging, pickle
-import time
-from time import gmtime, strftime
-from jinja2 import Environment, PackageLoader, FileSystemLoader, Template
-from cone.public import api, exceptions, utils, plugin
-from cone.confml import model
-import report_util
-
-ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
-
-def save_report_data(rep_data, file_path):
-    """
-    Save report data into an intermediary report data file.
-    """
-    dir = os.path.dirname(file_path)
-    if dir != '' and not os.path.exists(dir):
-        os.makedirs(dir)
-    
-    pickle_data = pickle.dumps(rep_data)
-    f = open(file_path, 'wb')
-    try:        f.write(pickle_data)
-    finally:    f.close()
-
-def load_report_data(file_path):
-    """
-    Load report data from an intermediary report data file.
-    """
-    f = open(file_path, "rb")
-    try:        data = f.read()
-    finally:    f.close()
-    
-    return pickle.loads(data)
-
-def _get_parent_sequence_or_self(feature):
-    current = feature._parent
-    while current is not None:
-        if isinstance(current, api.FeatureSequence):
-            return current
-        current = current._parent
-    return feature
-
-def collect_report_data(config, options, all_refs, impl_set, rule_exec_results):
-    """
-    Collect data for report generation.
-    """
-    impls = impl_set.get_all_implementations()
-    impls.sort(key=lambda impl: (impl.ref, impl.index))
-    rep_data = ReportData()
-    
-    # Sort the rule results for unit testing purposes
-    rep_data.rule_exec_results = sorted(rule_exec_results, key=lambda e: (e.source, e.index))
-    
-    # Collect a dictionary that maps refs shown in the report to a list of
-    # actual sub-refs used in the generation.
-    # This is done because for sequence settings only an entry for the main
-    # sequence setting is shown, but the actual refs used in generation point
-    # to the individual sub-settings (and possibly even under them).
-    # An example entry in the dictionary could be
-    #   'MyFeature.MySequence' : ['MyFeature.MySequence.Name',
-    #                             'MyFeature.MySequence.File.localPath',
-    #                             'MyFeature.MySequence.File.targetPath']
-    dview = config.get_default_view()
-    refs_dict = {}
-    for ref in all_refs:
-        try:
-            feature = dview.get_feature(ref)
-        except exceptions.NotFound:
-            logging.getLogger('cone.generation_report').warning("Feature for data ref not found: %s" % ref)
-            continue
-        
-        feature = _get_parent_sequence_or_self(feature._obj)
-        ref_to_report = feature.fqr
-        
-        if ref_to_report not in refs_dict:
-            refs_dict[ref_to_report] = []
-        refs_dict[ref_to_report].append(ref)
-    
-#    msg = []
-#    for ref, sub_refs in refs_dict.iteritems():
-#        msg.append("Ref: %s\nSub-refs:\n%s" % (ref, '\n'.join(sub_refs)))
-#    logging.getLogger('cone').debug('\n--------------------------------------\n'.join(msg))
-    
-    # Go through the refs and create report data entries
-    for ref in sorted(refs_dict.iterkeys()):
-        sub_refs = refs_dict[ref]
-        
-        #print "Ref: %s" % ref
-        try:
-            feat = dview.get_feature(ref)
-            
-            # Skip imaker-internal settings
-            if isinstance(feat._obj, model.ConfmlSetting):
-                try:
-                    prop = feat.get_property('cone-report-ignore')
-                    if prop.value.lower() in ('1', 'true'):
-                        continue
-                except exceptions.NotFound:
-                    pass
-            
-            #print "Still %s" % ref
-            
-            found_output = False
-            line = RefLine(ref, feat.get_type())
-            
-            if plugin.is_temp_feature(feat):
-                line.is_temp_feature = True
-
-            if feat.get_type() == 'sequence':
-                for f in feat.list_all_features():
-                    line.add_sequence(feat.get_feature(f).get_name(), feat.get_feature(f).get_value())
-            else:
-                if isinstance(feat.get_datas(), list): 
-                    for d in feat.get_datas():
-                        line.add_data(d.find_parent(type=api.Configuration).get_full_path(), d.get_value())
-                else:
-                    line.add_data(feat.get_data().find_parent(type=api.Configuration).get_full_path(), feat.get_value())
-            
-            
-            # Impl and output files
-            has_impl = False
-            for impl in impls:
-                # Check for implementations using the actual sub-refs
-                if impl.has_ref(sub_refs):
-                    has_impl = True
-                    line.add_impl(impl.ref, impl.IMPL_TYPE_ID, impl.list_output_files())
-            if has_impl:    rep_data.add_line(line)
-            else:           rep_data.add_ref_noimpl(line)
-                
-            
-            # For localPath and targetPath, the name should be the one from its parent file/folder setting
-            if isinstance(feat._obj, (model.ConfmlLocalPath, model.ConfmlTargetPath)):
-                name = feat._obj._parent.name
-            else:
-                name = feat.name
-            
-            line.set_feat_name(name)
-            line.set_config_path( feat._obj.find_parent(type=api.Configuration).get_full_path())
-            
-        except Exception, e:
-            utils.log_exception(logging.getLogger('cone'), 'Failed to collect data for report. Exception: %s' % e)
-        
-    # create one list of not generated files
-    for myline in rep_data.lines:
-        for myimpl in myline.impls:
-            for output_file in myimpl.outputfiles:
-                if not output_file.exists and output_file not in rep_data.missing_output_files:
-                    rep_data.missing_output_files.append(output_file)
-    
-    rep_data.set_options(options)
-    rep_data.set_output_dir(options.output)
-    rep_data.update_nbr_of_refs()
-    rep_data.update_nbr_of_refs_noimpl()
-    
-    return rep_data
-
-def generate_report(rep_data, report_file_path, template_file_path=None):
-    """
-    Generate a generation report based on the given report data.
-    @param rep_data: The report data.
-    @param report_file_path: Path to the report file to generate.
-    @param template_file_path: Path to the template file to use.
-        If None, the default template is used.
-    """
-    # Determine the template file and directory to use
-    if template_file_path is None:
-        template_file_path = os.path.join(ROOT_PATH, 'gen_report_template.html')
-    
-    report_util.generate_report(template_file_path, report_file_path, {'rep_data' : rep_data})
-
-class ReportData(object):
-    """
-    Data object that stores all information used in report generation.
-    """
-    
-    def __init__(self):
-        self.generation_timestamp = time.time()
-        self.generation_time = strftime("%d.%m.%Y %H:%M:%S")
-        self.options = None
-        self.lines = []
-        self.nbr_of_refs = 0
-        self.nbr_of_refs_noimpl = 0
-        self.cwd = os.getcwd()
-        self.ref_noimpl = []
-        self.duration = 0
-        self.output_dir = os.getcwd()
-        self.project_dir = ''
-        self.rule_exec_results = []
-        self.missing_output_files = []    
-    
-    def set_output_dir(self, dir):
-        self.output_dir = os.path.abspath(os.path.normpath(dir))
-    
-    def add_line(self, line):
-        self.lines.append(line)
-    
-    def set_duration(self, duration):
-        self.duration = duration
-    
-    def set_options(self, options):
-        self.options = options
-        self.project_dir = os.path.abspath(options.project)
-        
-    def set_report_filename(self, filename):
-        self.report_filename = filename
-        
-    def add_ref_noimpl(self, ref):
-        self.ref_noimpl.append(ref)
-        
-    def update_nbr_of_refs(self):
-        self.nbr_of_refs = len(self.lines)
-    
-    def update_nbr_of_refs_noimpl(self):
-        self.nbr_of_refs_noimpl = len(self.ref_noimpl)
-    
-    def __repr__(self):
-        return "ReportData(%s)" % [self.generation_timestamp, 
-                                   self.generation_time,
-                                   self.options,
-                                   self.lines,
-                                   self.nbr_of_refs,
-                                   self.nbr_of_refs_noimpl,
-                                   self.cwd,
-                                   self.ref_noimpl,
-                                   self.duration,
-                                   self.output_dir,
-                                   self.project_dir,
-                                   self.rule_exec_results,
-                                   self.missing_output_files]    
-    
-class RefLine(object):
-    """
-    Data object that stores information for one ref in report generation.
-    """
-    
-    def __init__(self, ref, type):
-        self.ref = ref
-        self.feat_type = type 
-        self.feat_name = None
-        self.feat_value = None
-        self.config_path = None
-        self.impls = []
-        self.output = None
-        self.nbr_impls = 0
-        self.nbr_outputfiles = 0
-        self.datas = []
-        self.nbr_of_datas = 0
-        self.nbr_of_rows = 0
-        self.seq_data = []
-        self.is_temp_feature = False
-        
-    def add_impl(self, impl_file, impl_type, outputfiles):
-        self.impls.append(ImplLine(impl_file, impl_type, outputfiles))
-        self.nbr_impls = len(self.impls)
-        self.nbr_outputfiles = len(outputfiles) + self.nbr_outputfiles
-
-    def add_data(self, layer, value):
-        self.datas.append(DataLine(layer,value))
-        self.nbr_of_datas = len(self.datas)
-        
-    def add_sequence(self, subsetting, values):
-        self.seq_data.append([subsetting, values])
-        
-    def set_feat_name(self, name):
-        self.feat_name = name
-        
-    def set_feat_value(self, value):
-        self.feat_value = value
-        
-    def set_config_path(self, filename):
-        self.config_path = os.path.normpath(filename)
-        
-class ImplLine():
-    def __init__(self, impl_file, impl_type, outputfiles, generation_runs=[]):
-        self.name = os.path.normpath(impl_file)
-        self.type = impl_type
-        files = []
-        
-        for outputfile in outputfiles:
-            files.append(Outputfile(outputfile))
-        
-        self.outputfiles = files
-        self.generation_runs = generation_runs
-        
-class Outputfile():
-    def __init__(self, filename):
-        self.filename = os.path.normpath(filename)
-        self.abs_filename = os.path.abspath(filename)
-        self.exists = os.path.isfile(self.abs_filename)
-    
-    def __eq__(self, other):
-        if type(self) is type(other):
-            return self.filename == other.filename
-        else:
-            return False
-        
-class DataLine():
-    def __init__(self, layer, value):
-        self.layer = os.path.normpath(layer)
-        self.value = value
\ No newline at end of file
--- a/configurationengine/source/scripts/imaker_variantdir.cfg	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/imaker_variantdir.cfg	Tue Aug 10 14:29:28 2010 +0300
@@ -1,3 +1,4 @@
+#
 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
 # All rights reserved.
 # This component and the accompanying materials are made available
@@ -10,7 +11,7 @@
 #
 # Contributors:
 #
-# Description: 
+# Description:
 #
 
 
--- a/configurationengine/source/scripts/info_api_report_template.html	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/info_api_report_template.html	Tue Aug 10 14:29:28 2010 +0300
@@ -3,7 +3,7 @@
 {% block content %}
     <h1>Configuration API info</h1><br>
 
-    <table class="report">
+    <table class="report" id="report_data">
     <tr>
         <th class="featureName">File</th>
         {% for item in data.api_data.columns %}
@@ -22,4 +22,10 @@
     {% endfor %}
     
     </table>
+
+<script language="javascript" type="text/javascript">
+//<![CDATA[
+    setFilterGrid("report_data");
+//]]>
+</script>
 {% endblock %}
\ No newline at end of file
--- a/configurationengine/source/scripts/info_content_report_template.html	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/info_content_report_template.html	Tue Aug 10 14:29:28 2010 +0300
@@ -3,7 +3,7 @@
 {% block content %}
     <h1>Configuration content files</h1><br>
 
-    <table class="report">
+    <table class="report" id="report_data">
     <tr>
         <th class="featureName">Content file</th>
 		<th class="featureName">Actual files (used one last)</th>
@@ -20,4 +20,9 @@
     {% endfor %}
     
     </table>
+    <script language="javascript" type="text/javascript">
+//<![CDATA[
+    setFilterGrid("report_data");
+//]]>
+</script>
 {% endblock %}
\ No newline at end of file
--- a/configurationengine/source/scripts/info_impl_report_template.html	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/info_impl_report_template.html	Tue Aug 10 14:29:28 2010 +0300
@@ -3,10 +3,10 @@
 {% block content %}
     <h1>Implementations</h1><br>
 
-    <table class="report">
+    <table class="report" id="report_data">
     <tr>
         <th class="featureName">File</th>
-		<th class="featureName">Index</th>
+		<th class="featureName">Line</th>
 		<th class="featureName">Type</th>
 		<th class="featureName">Phase</th>
 		<th class="featureName">Tags</th>
@@ -15,7 +15,7 @@
     {% for impl in data.impl_data %}
     <tr>
         <td>{{ impl.ref }}</td>
-		<td>{{ impl.index }}</td>
+		<td>{{ impl.lineno }}</td>
 		<td>{{ impl.IMPL_TYPE_ID }}</td>
 		<td>{{ impl.invocation_phase() }}</td>
 		<td>
@@ -37,4 +37,10 @@
     {% endfor %}
     
     </table>
+    <script language="javascript" type="text/javascript">
+//<![CDATA[
+    setFilterGrid("report_data");
+//]]>
+</script>
+    
 {% endblock %}
\ No newline at end of file
--- a/configurationengine/source/scripts/info_value_report_template.csv	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/info_value_report_template.csv	Tue Aug 10 14:29:28 2010 +0300
@@ -1,5 +1,5 @@
 {#- Note: The empty comments are used for removing line feeds -#}
-Name,Type,Possible values,{% for config in data.value_data.configs %}{{ config.path | csv_escape }},{% endfor %}
+Name,Type,Possible values,{% for config in data.value_data.configs %}{% if config.name %}{{config.name + ' (' + config.path + ')'|csv_escape}}{% else %}{{config.path}}{% endif %},{% endfor %}
 {# -#}
 {% for feature_group in data.value_data.feature_groups %}
 {{ feature_group.name }}
--- a/configurationengine/source/scripts/info_value_report_template.html	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/info_value_report_template.html	Tue Aug 10 14:29:28 2010 +0300
@@ -3,13 +3,13 @@
 {% block content %}
     <h1>Configuration data value info</h1><br>
 
-    <table class="report">
+    <table class="report" id="report_data">
     <tr>
         <th class="featureName">Name</th>
         <th class="featureName">Type</th>
         <th class="featureName">Possible values</th>
         {% for config in data.value_data.configs %}
-        <th class="featureName">{{ config.path }}</th>
+        <th class="featureName">{% if config.name %}{{config.name}} ({{ config.path }}){% else %}{{config.path}}{% endif %}</th>
         {% endfor %}
     </tr>
     {% for feature_group in data.value_data.feature_groups %}
@@ -39,14 +39,18 @@
                         {%- for column in value.columns -%}
                             <tr>
                             <td><b>{{ column.name }}</b></td>
-                            <td>{{ row[column.ref] }}</td>
+                            <td>{% if feature.ref+'.'+column.ref in config.refs %}<b>{% endif %}
+                            {{- row[column.ref] -}}
+                            {% if feature.ref+'.'+column.ref in config.refs %}</b>{% endif %}</td>
                             </tr>
                         {%- endfor -%}
                     {%- endfor -%}
                 </table>
                 {% endif %}
             {%- else -%}
+            	{% if feature.ref in config.refs %}<b>{% endif %}
                 {{- value -}}
+                {% if feature.ref in config.refs %}</b>{% endif %}
             {%- endif -%}
         </td>
         {% endfor %}
@@ -56,4 +60,9 @@
     {% endfor %}
     
     </table>
+    <script language="javascript" type="text/javascript">
+//<![CDATA[
+    setFilterGrid("report_data");
+//]]>
+</script>
 {% endblock %}
\ No newline at end of file
--- a/configurationengine/source/scripts/logging.ini	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/logging.ini	Tue Aug 10 14:29:28 2010 +0300
@@ -33,10 +33,8 @@
 args=('%(logfile)s','w')
 
 [formatter_consoleFormatter]
-format=%(levelname)-8s: %(name)s 
- %(message)s
+format=%(levelname)s: %(name)s %(message)s
 datefmt=%m-%d %H:%M
 
 [formatter_fileFormatter]
-format=%(asctime)s %(levelname)-8s: %(name)s 
- %(message)s
\ No newline at end of file
+format=%(asctime)s %(levelname)-8s: %(name)s %(message)s
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/popup.js	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,1215 @@
+/**
+ * Copyright (c)2005-2009 Matt Kruse (javascripttoolbox.com)
+ * 
+ * Dual licensed under the MIT and GPL licenses. 
+ * This basically means you can use this code however you want for
+ * free, but don't claim to have written it yourself!
+ * Donations always accepted: http://www.JavascriptToolbox.com/donate/
+ * 
+ * Please do not link to the .js files on javascripttoolbox.com from
+ * your site. Copy the files locally to your server instead.
+ * 
+ */
+/* ******************************************************************* */
+/*   UTIL FUNCTIONS                                                    */
+/* ******************************************************************* */
+var Util = {'$VERSION':1.06};
+
+// Util functions - these are GLOBAL so they
+// look like built-in functions.
+
+// Determine if an object is an array
+function isArray(o) {
+	return (o!=null && typeof(o)=="object" && typeof(o.length)=="number" && (o.length==0 || defined(o[0])));
+};
+
+// Determine if an object is an Object
+function isObject(o) {
+	return (o!=null && typeof(o)=="object" && defined(o.constructor) && o.constructor==Object && !defined(o.nodeName));
+};
+
+// Determine if a reference is defined
+function defined(o) {
+	return (typeof(o)!="undefined");
+};
+
+// Iterate over an array, object, or list of items and run code against each item
+// Similar functionality to Perl's map() function
+function map(func) {
+	var i,j,o;
+	var results = [];
+	if (typeof(func)=="string") {
+		func = new Function('$_',func);
+	}
+	for (i=1; i<arguments.length; i++) {
+		o = arguments[i];
+		if (isArray(o)) {
+			for (j=0; j<o.length; j++) {
+				results[results.length] = func(o[j]);
+			}
+		}
+		else if (isObject(o)) {
+			for (j in o) {
+				results[results.length] = func(o[j]);
+			}
+		}
+		else {
+			results[results.length] = func(o);
+		}
+	}
+	return results;
+};
+
+// Set default values in an object if they are undefined
+function setDefaultValues(o,values) {
+	if (!defined(o) || o==null) {
+		o = {};
+	}
+	if (!defined(values) || values==null) {
+		return o;
+	}
+	for (var val in values) {
+		if (!defined(o[val])) {
+			o[val] = values[val];
+		}
+	}
+	return o;
+};
+
+/* ******************************************************************* */
+/*   DEFAULT OBJECT PROTOTYPE ENHANCEMENTS                             */
+/* ******************************************************************* */
+// These functions add useful functionality to built-in objects
+Array.prototype.contains = function(o) {
+	var i,l;
+	if (!(l = this.length)) { return false; }
+	for (i=0; i<l; i++) {
+		if (o==this[i]) {
+			return true;
+		}
+	}
+};
+
+/* ******************************************************************* */
+/*   DOM FUNCTIONS                                                     */
+/* ******************************************************************* */
+var DOM = (function() { 
+	var dom = {};
+	
+	// Get a parent tag with a given nodename
+	dom.getParentByTagName = function(o,tagNames) {
+		if(o==null) { return null; }
+		if (isArray(tagNames)) {
+			tagNames = map("return $_.toUpperCase()",tagNames);
+			while (o=o.parentNode) {
+				if (o.nodeName && tagNames.contains(o.nodeName)) {
+					return o;
+				}
+			}
+		}
+		else {
+			tagNames = tagNames.toUpperCase();
+			while (o=o.parentNode) {
+				if (o.nodeName && tagNames==o.nodeName) {
+					return o;
+				}
+			}
+		}
+		return null;
+	};
+	
+	// Remove a node from its parent
+	dom.removeNode = function(o) {
+		if (o!=null && o.parentNode && o.parentNode.removeChild) {
+			// First remove all attributes which are func references, to avoid memory leaks
+			for (var i in o) {
+				if (typeof(o[i])=="function") {
+					o[i] = null;
+				}
+			}
+			o.parentNode.removeChild(o);
+			return true;
+		}
+		return false;
+	};
+
+	// Get the outer width in pixels of an object, including borders, padding, and margin
+	dom.getOuterWidth = function(o) {
+		if (defined(o.offsetWidth)) {
+			return o.offsetWidth;
+		}
+		return null;
+	};
+
+	// Get the outer height in pixels of an object, including borders, padding, and margin
+	dom.getOuterHeight = function(o) {
+		if (defined(o.offsetHeight)) {
+			return o.offsetHeight;
+		}
+		return null;
+	};
+
+	// Resolve an item, an array of items, or an object of items
+	dom.resolve = function() {
+		var results = new Array();
+		var i,j,o;
+		for (var i=0; i<arguments.length; i++) {
+			var o = arguments[i];
+			if (o==null) {
+				if (arguments.length==1) {
+					return null;
+				}
+				results[results.length] = null;
+			}
+			else if (typeof(o)=='string') {
+				if (document.getElementById) {
+					o = document.getElementById(o);
+				}
+				else if (document.all) {
+					o = document.all[o];
+				}
+				if (arguments.length==1) {
+					return o;
+				}
+				results[results.length] = o;
+			}
+			else if (isArray(o)) {
+				for (j=0; j<o.length; j++) {
+					results[results.length] = o[j];
+				}
+			}
+			else if (isObject(o)) {
+				for (j in o) {
+					results[results.length] = o[j];
+				}
+			}
+			else if (arguments.length==1) {
+				return o;
+			}
+			else {
+				results[results.length] = o;
+			}
+	  }
+	  return results;
+	};
+	dom.$ = dom.resolve;
+	
+	return dom;
+})();
+
+/* ******************************************************************* */
+/*   CSS FUNCTIONS                                                     */
+/* ******************************************************************* */
+var CSS = (function(){
+	var css = {};
+
+	// Convert an RGB string in the form "rgb (255, 255, 255)" to "#ffffff"
+	css.rgb2hex = function(rgbString) {
+		if (typeof(rgbString)!="string" || !defined(rgbString.match)) { return null; }
+		var result = rgbString.match(/^\s*rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*/);
+		if (result==null) { return rgbString; }
+		var rgb = +result[1] << 16 | +result[2] << 8 | +result[3];
+		var hex = "";
+		var digits = "0123456789abcdef";
+		while(rgb!=0) { 
+			hex = digits.charAt(rgb&0xf)+hex; 
+			rgb>>>=4; 
+		} 
+		while(hex.length<6) { hex='0'+hex; }
+		return "#" + hex;
+	};
+
+	// Convert hyphen style names like border-width to camel case like borderWidth
+	css.hyphen2camel = function(property) {
+		if (!defined(property) || property==null) { return null; }
+		if (property.indexOf("-")<0) { return property; }
+		var str = "";
+		var c = null;
+		var l = property.length;
+		for (var i=0; i<l; i++) {
+			c = property.charAt(i);
+			str += (c!="-")?c:property.charAt(++i).toUpperCase();
+		}
+		return str;
+	};
+	
+	// Determine if an object or class string contains a given class.
+	css.hasClass = function(obj,className) {
+		if (!defined(obj) || obj==null || !RegExp) { return false; }
+		var re = new RegExp("(^|\\s)" + className + "(\\s|$)");
+		if (typeof(obj)=="string") {
+			return re.test(obj);
+		}
+		else if (typeof(obj)=="object" && obj.className) {
+			return re.test(obj.className);
+		}
+		return false;
+	};
+	
+	// Add a class to an object
+	css.addClass = function(obj,className) {
+		if (typeof(obj)!="object" || obj==null || !defined(obj.className)) { return false; }
+		if (obj.className==null || obj.className=='') { 
+			obj.className = className; 
+			return true; 
+		}
+		if (css.hasClass(obj,className)) { return true; }
+		obj.className = obj.className + " " + className;
+		return true;
+	};
+	
+	// Remove a class from an object
+	css.removeClass = function(obj,className) {
+		if (typeof(obj)!="object" || obj==null || !defined(obj.className) || obj.className==null) { return false; }
+		if (!css.hasClass(obj,className)) { return false; }
+		var re = new RegExp("(^|\\s+)" + className + "(\\s+|$)");
+		obj.className = obj.className.replace(re,' ');
+		return true;
+	};
+	
+	// Fully replace a class with a new one
+	css.replaceClass = function(obj,className,newClassName) {
+		if (typeof(obj)!="object" || obj==null || !defined(obj.className) || obj.className==null) { return false; }
+		css.removeClass(obj,className);
+		css.addClass(obj,newClassName);
+		return true;
+	};
+	
+	// Get the currently-applied style of an object
+	css.getStyle = function(o, property) {
+		if (o==null) { return null; }
+		var val = null;
+		var camelProperty = css.hyphen2camel(property);
+		// Handle "float" property as a special case
+		if (property=="float") {
+			val = css.getStyle(o,"cssFloat");
+			if (val==null) { 
+				val = css.getStyle(o,"styleFloat"); 
+			}
+		}
+		else if (o.currentStyle && defined(o.currentStyle[camelProperty])) {
+			val = o.currentStyle[camelProperty];
+		}
+		else if (window.getComputedStyle) {
+			val = window.getComputedStyle(o,null).getPropertyValue(property);
+		}
+		else if (o.style && defined(o.style[camelProperty])) {
+			val = o.style[camelProperty];
+		}
+		// For color values, make the value consistent across browsers
+		// Convert rgb() colors back to hex for consistency
+		if (/^\s*rgb\s*\(/.test(val)) {
+			val = css.rgb2hex(val);
+		}
+		// Lowercase all #hex values
+		if (/^#/.test(val)) {
+			val = val.toLowerCase();
+		}
+		return val;
+	};
+	css.get = css.getStyle;
+
+	// Set a style on an object
+	css.setStyle = function(o, property, value) {
+		if (o==null || !defined(o.style) || !defined(property) || property==null || !defined(value)) { return false; }
+		if (property=="float") {
+			o.style["cssFloat"] = value;
+			o.style["styleFloat"] = value;
+		}
+		else if (property=="opacity") {
+			o.style['-moz-opacity'] = value;
+			o.style['-khtml-opacity'] = value;
+			o.style.opacity = value;
+			if (defined(o.style.filter)) {
+				o.style.filter = "alpha(opacity=" + value*100 + ")";
+			}
+		}
+		else {
+			o.style[css.hyphen2camel(property)] = value;
+		}
+		return true;
+	};
+	css.set = css.setStyle;
+	
+	// Get a unique ID which doesn't already exist on the page
+	css.uniqueIdNumber=1000;
+	css.createId = function(o) {
+		if (defined(o) && o!=null && defined(o.id) && o.id!=null && o.id!="") { 
+			return o.id;
+		}
+		var id = null;
+		while (id==null || document.getElementById(id)!=null) {
+			id = "ID_"+(css.uniqueIdNumber++);
+		}
+		if (defined(o) && o!=null && (!defined(o.id)||o.id=="")) {
+			o.id = id;
+		}
+		return id;
+	};
+	
+	return css;
+})();
+
+/* ******************************************************************* */
+/*   EVENT FUNCTIONS                                                   */
+/* ******************************************************************* */
+
+var Event = (function(){
+	var ev = {};
+	
+	// Resolve an event using IE's window.event if necessary
+	// --------------------------------------------------------------------
+	ev.resolve = function(e) {
+		if (!defined(e) && defined(window.event)) {
+			e = window.event;
+		}
+		return e;
+	};
+	
+	// Add an event handler to a function
+	// Note: Don't use 'this' within functions added using this method, since
+	// the attachEvent and addEventListener models differ.
+	// --------------------------------------------------------------------
+	ev.add = function( obj, type, fn, capture ) {
+		if (obj.addEventListener) {
+			obj.addEventListener( type, fn, capture );
+			return true;
+		}
+		else if (obj.attachEvent) {
+			obj.attachEvent( "on"+type, fn );
+			return true;
+		}
+		return false;
+	};
+
+	// Get the mouse position of an event
+	// --------------------------------------------------------------------
+	// PageX/Y, where they exist, are more reliable than ClientX/Y because 
+	// of some browser bugs in Opera/Safari
+	ev.getMouseX = function(e) {
+		e = ev.resolve(e);
+		if (defined(e.pageX)) {
+			return e.pageX;
+		}
+		if (defined(e.clientX)) {
+			return e.clientX+Screen.getScrollLeft();
+		}
+		return null;
+	};
+	ev.getMouseY = function(e) {
+		e = ev.resolve(e);
+		if (defined(e.pageY)) {
+			return e.pageY;
+		}
+		if (defined(e.clientY)) {
+			return e.clientY+Screen.getScrollTop();
+		}
+		return null;
+	};
+
+	// Stop the event from bubbling up to parent elements.
+	// Two method names map to the same function
+	// --------------------------------------------------------------------
+	ev.cancelBubble = function(e) {
+		e = ev.resolve(e);
+		if (typeof(e.stopPropagation)=="function") { e.stopPropagation(); } 
+		if (defined(e.cancelBubble)) { e.cancelBubble = true; }
+	};
+	ev.stopPropagation = ev.cancelBubble;
+
+	// Prevent the default handling of the event to occur
+	// --------------------------------------------------------------------
+	ev.preventDefault = function(e) {
+		e = ev.resolve(e);
+		if (typeof(e.preventDefault)=="function") { e.preventDefault(); } 
+		if (defined(e.returnValue)) { e.returnValue = false; }
+	};
+	
+	return ev;
+})();
+
+/* ******************************************************************* */
+/*   SCREEN FUNCTIONS                                                  */
+/* ******************************************************************* */
+var Screen = (function() {
+	var screen = {};
+
+	// Get a reference to the body
+	// --------------------------------------------------------------------
+	screen.getBody = function() {
+		if (document.body) {
+			return document.body;
+		}
+		if (document.getElementsByTagName) {
+			var bodies = document.getElementsByTagName("BODY");
+			if (bodies!=null && bodies.length>0) {
+				return bodies[0];
+			}
+		}
+		return null;
+	};
+
+	// Get the amount that the main document has scrolled from top
+	// --------------------------------------------------------------------
+	screen.getScrollTop = function() {
+		if (document.documentElement && defined(document.documentElement.scrollTop) && document.documentElement.scrollTop>0) {
+			return document.documentElement.scrollTop;
+		}
+		if (document.body && defined(document.body.scrollTop)) {
+			return document.body.scrollTop;
+		}
+		return null;
+	};
+	
+	// Get the amount that the main document has scrolled from left
+	// --------------------------------------------------------------------
+	screen.getScrollLeft = function() {
+		if (document.documentElement && defined(document.documentElement.scrollLeft) && document.documentElement.scrollLeft>0) {
+			return document.documentElement.scrollLeft;
+		}
+		if (document.body && defined(document.body.scrollLeft)) {
+			return document.body.scrollLeft;
+		}
+		return null;
+	};
+	
+	// Util function to default a bad number to 0
+	// --------------------------------------------------------------------
+	screen.zero = function(n) {
+		return (!defined(n) || isNaN(n))?0:n;
+	};
+
+	// Get the width of the entire document
+	// --------------------------------------------------------------------
+	screen.getDocumentWidth = function() {
+		var width = 0;
+		var body = screen.getBody();
+		if (document.documentElement && (!document.compatMode || document.compatMode=="CSS1Compat")) {
+		    var rightMargin = parseInt(CSS.get(body,'marginRight'),10) || 0;
+		    var leftMargin = parseInt(CSS.get(body,'marginLeft'), 10) || 0;
+			width = Math.max(body.offsetWidth + leftMargin + rightMargin, document.documentElement.clientWidth);
+		}
+		else {
+			width =  Math.max(body.clientWidth, body.scrollWidth);
+		}
+		if (isNaN(width) || width==0) {
+			width = screen.zero(self.innerWidth);
+		}
+		return width;
+	};
+	
+	// Get the height of the entire document
+	// --------------------------------------------------------------------
+	screen.getDocumentHeight = function() {
+		var body = screen.getBody();
+		var innerHeight = (defined(self.innerHeight)&&!isNaN(self.innerHeight))?self.innerHeight:0;
+		if (document.documentElement && (!document.compatMode || document.compatMode=="CSS1Compat")) {
+		    var topMargin = parseInt(CSS.get(body,'marginTop'),10) || 0;
+		    var bottomMargin = parseInt(CSS.get(body,'marginBottom'), 10) || 0;
+			return Math.max(body.offsetHeight + topMargin + bottomMargin, document.documentElement.clientHeight, document.documentElement.scrollHeight, screen.zero(self.innerHeight));
+		}
+		return Math.max(body.scrollHeight, body.clientHeight, screen.zero(self.innerHeight));
+	};
+	
+	// Get the width of the viewport (viewable area) in the browser window
+	// --------------------------------------------------------------------
+	screen.getViewportWidth = function() {
+		if (document.documentElement && (!document.compatMode || document.compatMode=="CSS1Compat")) {
+			return document.documentElement.clientWidth;
+		}
+		else if (document.compatMode && document.body) {
+			return document.body.clientWidth;
+		}
+		return screen.zero(self.innerWidth);
+	};
+	
+	// Get the height of the viewport (viewable area) in the browser window
+	// --------------------------------------------------------------------
+	screen.getViewportHeight = function() {
+		if (!window.opera && document.documentElement && (!document.compatMode || document.compatMode=="CSS1Compat")) {
+			return document.documentElement.clientHeight;
+		}
+		else if (document.compatMode && !window.opera && document.body) {
+			return document.body.clientHeight;
+		}
+		return screen.zero(self.innerHeight);
+	};
+
+	return screen;
+})();var Sort = (function(){
+	var sort = {};
+	sort.AlphaNumeric = function(a,b) {
+		if (a==b) { return 0; }
+		if (a<b) { return -1; }
+		return 1;
+	};
+
+	sort.Default = sort.AlphaNumeric;
+	
+	sort.NumericConversion = function(val) {
+		if (typeof(val)!="number") {
+			if (typeof(val)=="string") {
+				val = parseFloat(val.replace(/,/g,''));
+				if (isNaN(val) || val==null) { val=0; }
+			}
+			else {
+				val = 0;
+			}
+		}
+		return val;
+	};
+	
+	sort.Numeric = function(a,b) {
+		return sort.NumericConversion(a)-sort.NumericConversion(b);
+	};
+
+	sort.IgnoreCaseConversion = function(val) {
+		if (val==null) { val=""; }
+		return (""+val).toLowerCase();
+	};
+
+	sort.IgnoreCase = function(a,b) {
+		return sort.AlphaNumeric(sort.IgnoreCaseConversion(a),sort.IgnoreCaseConversion(b));
+	};
+
+	sort.CurrencyConversion = function(val) {
+		if (typeof(val)=="string") {
+			val = val.replace(/^[^\d\.]/,'');
+		}
+		return sort.NumericConversion(val);
+	};
+	
+	sort.Currency = function(a,b) {
+		return sort.Numeric(sort.CurrencyConversion(a),sort.CurrencyConversion(b));
+	};
+	
+	sort.DateConversion = function(val) {
+		// inner util function to parse date formats
+		function getdate(str) {
+			// inner util function to convert 2-digit years to 4
+			function fixYear(yr) {
+				yr = +yr;
+				if (yr<50) { yr += 2000; }
+				else if (yr<100) { yr += 1900; }
+				return yr;
+			};
+			var ret;
+			// YYYY-MM-DD
+			if (ret=str.match(/(\d{2,4})-(\d{1,2})-(\d{1,2})/)) {
+				return (fixYear(ret[1])*10000) + (ret[2]*100) + (+ret[3]);
+			}
+			// MM/DD/YY[YY] or MM-DD-YY[YY]
+			if (ret=str.match(/(\d{1,2})[\/-](\d{1,2})[\/-](\d{2,4})/)) {
+				return (fixYear(ret[3])*10000) + (ret[1]*100) + (+ret[2]);
+			}
+			return 99999999; // So non-parsed dates will be last, not first
+		};
+		return getdate(val);
+	};
+
+	sort.Date = function(a,b) {
+		return sort.Numeric(sort.DateConversion(a),sort.DateConversion(b));
+	};
+
+	return sort;
+})();
+
+var Position = (function() {
+	// Resolve a string identifier to an object
+	// ========================================
+	function resolveObject(s) {
+		if (document.getElementById && document.getElementById(s)!=null) {
+			return document.getElementById(s);
+		}
+		else if (document.all && document.all[s]!=null) {
+			return document.all[s];
+		}
+		else if (document.anchors && document.anchors.length && document.anchors.length>0 && document.anchors[0].x) {
+			for (var i=0; i<document.anchors.length; i++) {
+				if (document.anchors[i].name==s) { 
+					return document.anchors[i]
+				}
+			}
+		}
+	}
+	
+	var pos = {};
+	pos.$VERSION = 1.0;
+	
+	// Set the position of an object
+	// =============================
+	pos.set = function(o,left,top) {
+		if (typeof(o)=="string") {
+			o = resolveObject(o);
+		}
+		if (o==null || !o.style) {
+			return false;
+		}
+		
+		// If the second parameter is an object, it is assumed to be the result of getPosition()
+		if (typeof(left)=="object") {
+			var pos = left;
+			left = pos.left;
+			top = pos.top;
+		}
+		
+		o.style.left = left + "px";
+		o.style.top = top + "px";
+		return true;
+	};
+	
+	// Retrieve the position and size of an object
+	// ===========================================
+	pos.get = function(o) {
+		var fixBrowserQuirks = true;
+			// If a string is passed in instead of an object ref, resolve it
+		if (typeof(o)=="string") {
+			o = resolveObject(o);
+		}
+		
+		if (o==null) {
+			return null;
+		}
+		
+		var left = 0;
+		var top = 0;
+		var width = 0;
+		var height = 0;
+		var parentNode = null;
+		var offsetParent = null;
+	
+		
+		offsetParent = o.offsetParent;
+		var originalObject = o;
+		var el = o; // "el" will be nodes as we walk up, "o" will be saved for offsetParent references
+		while (el.parentNode!=null) {
+			el = el.parentNode;
+			if (el.offsetParent==null) {
+			}
+			else {
+				var considerScroll = true;
+				/*
+				In Opera, if parentNode of the first object is scrollable, then offsetLeft/offsetTop already 
+				take its scroll position into account. If elements further up the chain are scrollable, their 
+				scroll offsets still need to be added in. And for some reason, TR nodes have a scrolltop value
+				which must be ignored.
+				*/
+				if (fixBrowserQuirks && window.opera) {
+					if (el==originalObject.parentNode || el.nodeName=="TR") {
+						considerScroll = false;
+					}
+				}
+				if (considerScroll) {
+					if (el.scrollTop && el.scrollTop>0) {
+						top -= el.scrollTop;
+					}
+					if (el.scrollLeft && el.scrollLeft>0) {
+						left -= el.scrollLeft;
+					}
+				}
+			}
+			// If this node is also the offsetParent, add on the offsets and reset to the new offsetParent
+			if (el == offsetParent) {
+				left += o.offsetLeft;
+				if (el.clientLeft && el.nodeName!="TABLE") { 
+					left += el.clientLeft;
+				}
+				top += o.offsetTop;
+				if (el.clientTop && el.nodeName!="TABLE") {
+					top += el.clientTop;
+				}
+				o = el;
+				if (o.offsetParent==null) {
+					if (o.offsetLeft) {
+						left += o.offsetLeft;
+					}
+					if (o.offsetTop) {
+						top += o.offsetTop;
+					}
+				}
+				offsetParent = o.offsetParent;
+			}
+		}
+		
+	
+		if (originalObject.offsetWidth) {
+			width = originalObject.offsetWidth;
+		}
+		if (originalObject.offsetHeight) {
+			height = originalObject.offsetHeight;
+		}
+		
+		return {'left':left, 'top':top, 'width':width, 'height':height
+				};
+	};
+	
+	// Retrieve the position of an object's center point
+	// =================================================
+	pos.getCenter = function(o) {
+		var c = this.get(o);
+		if (c==null) { return null; }
+		c.left = c.left + (c.width/2);
+		c.top = c.top + (c.height/2);
+		return c;
+	};
+	
+	return pos;
+})();// CLASS CONSTRUCTOR
+// --------------------------------------------------------------------
+var Popup = function(div, options) {
+	this.div = defined(div)?div:null;
+	this.index = Popup.maxIndex++;
+	this.ref = "Popup.objects["+this.index+"]";
+	Popup.objects[this.index] = this;
+	// Store a reference to the DIV by id, also
+	if (typeof(this.div)=="string") {
+		Popup.objectsById[this.div] = this;
+	}
+	if (defined(this.div) && this.div!=null && defined(this.div.id)) {
+		Popup.objectsById[this.div.id] = this.div.id;
+	}
+	// Apply passed-in options
+	if (defined(options) && options!=null && typeof(options)=="object") {
+		for (var i in options) {
+			this[i] = options[i];
+		}
+	}
+	return this;
+};
+
+// CLASS PROPERTIES
+// --------------------------------------------------------------------
+// Index of popup objects, to maintain a global reference if necessary
+Popup.maxIndex = 0;
+Popup.objects = {};
+Popup.objectsById = {};
+
+// The z-index value that popups will start at
+Popup.minZIndex = 101;
+
+// Class names to assign to other objects
+Popup.screenClass = "PopupScreen";
+Popup.iframeClass = "PopupIframe";
+Popup.screenIframeClass = "PopupScreenIframe";
+
+// CLASS METHODS
+// --------------------------------------------------------------------
+
+// Hide all currently-visible non-modal dialogs
+Popup.hideAll = function() {
+	for (var i in Popup.objects) {
+		var p = Popup.objects[i];
+		if (!p.modal && p.autoHide) {
+			p.hide();
+		}
+	}
+};
+// Catch global events as a trigger to hide auto-hide popups
+Event.add(document, "mouseup", Popup.hideAll, false);
+
+// A simple class method to show a popup without creating an instance
+Popup.show = function(divObject, referenceObject, position, options, modal) {
+	var popup;
+	if (defined(divObject)) { 
+		popup = new Popup(divObject);
+	}
+	else {
+		popup = new Popup();
+		popup.destroyDivOnHide = true;
+	}
+	if (defined(referenceObject)) { popup.reference = DOM.resolve(referenceObject); }
+	if (defined(position)) { popup.position = position; }
+	if (defined(options) && options!=null && typeof(options)=="object") {
+		for (var i in options) {
+			popup[i] = options[i];
+		}
+	}
+	if (typeof(modal)=="boolean") {
+		popup.modal = modal;
+	}
+	popup.destroyObjectsOnHide = true;
+	popup.show();
+	return popup;
+};
+
+// A simple class method to show a modal popup
+Popup.showModal = function(divObject, referenceObject, position, options) {
+	Popup.show(divObject, referenceObject, position, options, true);
+};
+
+// A method to retrieve a popup object based on a div ID
+Popup.get = function(divId) {
+	if (defined(Popup.objectsById[divId])) {
+		return Popup.objectsById[divId];
+	}
+	return null;
+};
+
+// A method to hide a popup based on a div id
+Popup.hide = function(divId) {
+	var popup = Popup.get(divId);
+	if (popup!=null) {
+		popup.hide();
+	}
+};
+
+// PROTOTYPE PROPERTIES
+// --------------------------------------------------------------------
+Popup.prototype.content = null;
+Popup.prototype.className = "PopupDiv";
+Popup.prototype.style = null; // Styles to be applied to the DIV
+Popup.prototype.width = null;
+Popup.prototype.height = null;
+Popup.prototype.top = null;
+Popup.prototype.left = null;
+Popup.prototype.offsetLeft = 0;
+Popup.prototype.offsetTop = 0;
+Popup.prototype.constrainToScreen = true;
+Popup.prototype.autoHide = true;
+Popup.prototype.useIframeShim = false; /*@cc_on @*/ /*@if (@_win32) {Popup.prototype.useIframeShim = true;} @end @*/ 
+Popup.prototype.iframe = null;
+Popup.prototype.position = null; // vertical: "above top center bottom below", horizontal: "adjacent-left,left,center,right,adjacent-right"
+Popup.prototype.reference = null;
+Popup.prototype.modal = false;
+Popup.prototype.destroyDivOnHide = false;
+Popup.prototype.destroyObjectsOnHide = false;
+Popup.prototype.screen = null;
+Popup.prototype.screenIframeShim = null;
+Popup.prototype.screenOpacity=.4;
+Popup.prototype.screenColor="#cccccc";
+
+// INSTANCE METHODS
+// --------------------------------------------------------------------
+
+// Show the popup
+// --------------------------------------------------------------------
+Popup.prototype.show = function(options, modal) {
+	this.modal = this.modal || (typeof(modal)=="boolean" && modal);
+	if (defined(options) && options!=null && typeof(options)=="object") {
+		for (var i in options) {
+			this[i] = options[i];
+		}
+	}
+	this.div = DOM.resolve(this.div);
+	CSS.setStyle(this.div,'position','absolute');
+	
+	// If there is no div pre-defined to use, create one
+	if (this.div==null) {
+		this.div = this.createDiv();
+	}
+	if (this.content!=null) {
+		this.div.innerHTML = this.content;
+		this.content = null;
+	}
+	if (this.className!=null) {
+		this.div.className = this.className;
+	}
+	if (this.style!=null) {
+		this.applyStyle();
+	}
+	if (this.width!=null) {
+		this.div.style.width = this.width+"px";
+		this.div.style.overflowX="auto";
+	}
+	if (this.height!=null) {
+		this.div.style.height = this.height+"px";
+		this.div.style.overflowY="auto";
+	}
+
+	// Do the actual display - this is a separate method so display transitions can be implemented
+	this.transition();
+	
+	// Make sure clicks on the DIV don't bubble up to the document
+	this.div.onclick = function(e) { 
+		Event.cancelBubble(Event.resolve(e));
+	};
+	this.div.onmouseup = this.div.onclick;
+	
+	// Focus to the DIV if possible	
+	if (this.modal && this.div.focus) {
+		this.div.focus();
+	}
+};
+
+// Show the popup but make it modal
+// --------------------------------------------------------------------
+Popup.prototype.transition = function() {
+	if (this.modal) {
+		this.addScreen();
+	}
+	
+	// Make the DIV displayed but hidden so its size can be measured
+	CSS.setStyle(this.div,'visibility','hidden');
+	CSS.setStyle(this.div,'display','block');
+
+	// Position the popup
+	this.setPosition();
+
+	// Add the shim if necessary	
+	if (this.useIframeShim) {
+		this.addIframeShim();
+	}
+
+	// Make sure the DIV is higher than the shim
+	this.div.style.zIndex = Popup.minZIndex++;
+
+	CSS.setStyle(this.div,'display','block');
+	CSS.setStyle(this.div,'visibility','visible');
+};
+
+// Show the popup but make it modal
+// --------------------------------------------------------------------
+Popup.prototype.showModal = function(options) {
+	this.show(options,true);
+};
+
+// Apply user styles to the DIV
+// --------------------------------------------------------------------
+Popup.prototype.applyStyle = function() {
+	if (this.div!=null && this.style!=null && typeof(this.style)=="object") {
+		for (var i in this.style) {
+			this.div.style[i] = this.style[i];
+		}
+	}
+};
+
+// Hide the popup
+// --------------------------------------------------------------------
+Popup.prototype.hide = function() {
+	// If this was a temp object creating on-the-fly, then remove objects from the DOM so
+	// The document doesn't get littered with extra objects
+	if (this.destroyDivOnHide) {
+		DOM.removeNode(this.div);
+		this.div = null;
+		delete Popup.objects[this.id];
+	}
+	else if (this.div!=null) {
+		CSS.setStyle(this.div,'display','none');
+	}
+
+	if (this.destroyObjectsOnHide) {
+		DOM.removeNode(this.iframe);
+		DOM.removeNode(this.screen);
+		DOM.removeNode(this.screenIframeShim);
+	}
+	else {
+		if (this.iframe!=null) {
+			this.iframe.style.display = "none";
+		}
+		if (this.screen!=null) {
+			this.screen.style.display = "none";
+		}
+		if (this.screenIframeShim!=null) {
+			this.screenIframeShim.style.display = "none";
+		}
+	}
+};
+
+// Util funcs for position
+// --------------------------------------------------------------------
+Popup.prototype.setTop = function(top) {
+	this.div.style.top = top+"px";
+};
+Popup.prototype.setLeft = function(left) {
+	this.div.style.left = left+"px";
+};
+Popup.prototype.getTop = function() {
+	return parseInt(CSS.getStyle(this.div,"top"),10);
+};
+Popup.prototype.getLeft = function() {
+	return parseInt(CSS.getStyle(this.div,"left"),10);
+};
+
+// All the logic to position the popup based on various criteria
+// --------------------------------------------------------------------
+Popup.prototype.setPosition = function() {
+	if (this.position!=null) {
+		var m = this.position.match(/^(\S+)\s+(\S+)/); 
+		if (m!=null && m.length==3) {
+			var v = m[1];
+			var h = m[2];
+
+			var ref = this.reference;
+			if (ref==null) { ref = Screen.getBody(); }
+			var p = Position.get(ref);
+			var refTop = p.top;
+			var refLeft = p.left;
+			var refWidth = DOM.getOuterWidth(ref);
+			var refHeight = DOM.getOuterHeight(ref);
+			
+			var width = DOM.getOuterWidth(this.div);
+			var height = DOM.getOuterHeight(this.div);
+			
+			var scrollLeft = Screen.getScrollLeft();
+			var scrollTop = Screen.getScrollTop();
+
+			// Set vertical position relative to reference object
+			if (v=="above") { this.setTop(refTop-height+this.offsetTop); }
+			else if (v=="top") { this.setTop(refTop+this.offsetTop); }
+			else if (v=="center") { this.setTop(refTop+(refHeight/2)-(height/2)+this.offsetTop); }
+			else if (v=="bottom") { this.setTop(refTop+refHeight-height+this.offsetTop); }
+			else if (v=="below") { this.setTop(refTop+refHeight+this.offsetTop); }
+
+			// Set horizontal position relative to reference object
+			if (h=="adjacent-left") { this.setLeft(refLeft-width+this.offsetLeft); }
+			else if (h=="left") { this.setLeft(refLeft+this.offsetLeft); }
+			else if (h=="center") { this.setLeft(refLeft+(refWidth/2)-(width/2)+this.offsetLeft); }
+			else if (h=="right") { this.setLeft(refLeft+refWidth-width+this.offsetLeft); }
+			else if (h=="adjacent-right") { this.setLeft(refLeft+refWidth+this.offsetLeft); }
+		}
+	}
+	else if (this.top==null && this.left==null) {
+		this.center();
+	}
+	else {
+		if (this.top==null) { this.top=0; }
+		if (this.left==null) { this.left=0; }
+		this.div.style.top = this.top+this.offsetTop+"px";
+		this.div.style.left = this.left+this.offsetLeft+"px";
+	}
+
+	// Re-position to make sure it stays on the screen
+	if (this.constrainToScreen) {
+		this.fitToScreen();
+	}
+};
+
+// Append an object to the body
+// --------------------------------------------------------------------
+Popup.prototype.appendToBody = function(o) {
+	var body = Screen.getBody();
+	if (body && body.appendChild) {
+		body.appendChild(o);
+	}
+};
+
+// Create a new DIV object to be used for a popup
+// --------------------------------------------------------------------
+Popup.prototype.createDiv = function() {
+	if (document.createElement) {
+		var d = document.createElement("DIV");
+		d.style.position="absolute";
+		d.style.display="block";
+		d.style.visibility="hidden";
+		this.appendToBody(d);
+		return d;
+	}
+	alert("ERROR: Couldn't create DIV element in Popup.prototype.createDiv()");
+	return null;
+};
+
+// Create a new IFRAME object to be used behind the popup
+// --------------------------------------------------------------------
+Popup.prototype.createIframe = function() {
+	if (document.createElement) {
+		var i= document.createElement("IFRAME");
+		i.style.position="absolute";
+		i.style.display="block";
+		i.style.visibility="hidden";
+		i.style.background="none";
+		this.appendToBody(i);
+		return i;
+	}
+	else {
+		alert("ERROR: Couldn't create IFRAME object in Popup.prototype.createIframe()");
+	}
+};
+
+// Add an IFRAME shim for the DIV
+// --------------------------------------------------------------------
+Popup.prototype.addIframeShim = function() {
+	if (this.iframe==null) {
+		this.iframe = this.createIframe();
+	}
+	this.iframe.className = Popup.iframeClass;
+	CSS.setStyle(this.iframe,'top',this.getTop()+"px");
+	CSS.setStyle(this.iframe,'left',this.getLeft()+"px");
+	CSS.setStyle(this.iframe,'width',DOM.getOuterWidth(this.div) + "px");
+	CSS.setStyle(this.iframe,'height',DOM.getOuterHeight(this.div) + "px");
+	CSS.setStyle(this.iframe,'zIndex',Popup.minZIndex++);
+	CSS.setStyle(this.iframe,'opacity',0);
+	CSS.setStyle(this.iframe,'visibility','visible');
+	CSS.setStyle(this.iframe,'display','block');
+};
+
+// Create a "screen" to make a popup modal
+// --------------------------------------------------------------------
+Popup.prototype.addScreen = function() {
+	if (this.screen==null) {
+		this.screen = this.createDiv();
+		this.screen.style.top="0px";
+		this.screen.style.left="0px";
+		this.screen.style.backgroundColor = this.screenColor;
+		this.screen.className=Popup.screenClass;;
+		CSS.setStyle(this.screen,"opacity",this.screenOpacity);
+		this.screen.onclick = function(e) { Event.cancelBubble(Event.resolve(e)); }
+	}
+	if (this.screenIframeShim==null) {
+		this.screenIframeShim = this.createIframe();
+		this.screenIframeShim.style.top="0px";
+		this.screenIframeShim.style.left="0px";
+		this.screenIframeShim.className=Popup.screenIframeClass;
+		CSS.setStyle(this.screenIframeShim,"opacity",0);
+	}
+	this.screen.style.width = Screen.getDocumentWidth()+"px";
+	this.screen.style.height = Screen.getDocumentHeight()+"px";
+	this.screenIframeShim.style.width = Screen.getDocumentWidth()+"px";
+	this.screenIframeShim.style.height = Screen.getDocumentHeight()+"px";
+	this.screenIframeShim.style.zIndex = Popup.minZIndex++;
+	this.screenIframeShim.style.visibility="visible";
+	this.screenIframeShim.style.display="block";
+	this.screen.style.zIndex = Popup.minZIndex++;
+	this.screen.style.visibility="visible";
+	this.screen.style.display="block";
+};
+
+// Re-position the DIV so it stays on the screen
+// --------------------------------------------------------------------
+Popup.prototype.fitToScreen = function() {
+	var width = DOM.getOuterWidth(this.div);
+	var height = DOM.getOuterHeight(this.div);
+	var top = this.getTop();
+	var left = this.getLeft();
+	
+	var clientWidth = Screen.getViewportWidth();
+	var clientHeight = Screen.getViewportHeight();
+	
+	var scrollLeft = Screen.getScrollLeft();
+	var scrollTop = Screen.getScrollTop();
+
+	if (top-scrollTop+height>clientHeight) {
+		top = top - ((top+height) - (scrollTop+clientHeight));
+		this.div.style.top = top + "px";
+	}
+	if (left-scrollLeft+width>clientWidth) {
+		left = left - ((left+width) - (scrollLeft+clientWidth));
+		this.div.style.left = left + "px";
+	}
+	if (top<scrollTop) {
+		this.div.style.top=scrollTop+"px";
+	}
+	if (left<scrollLeft) {
+		this.div.style.left=scrollLeft+"px";
+	}
+};
+
+// Center the DIV object
+// --------------------------------------------------------------------
+Popup.prototype.center = function() {
+	var left = DOM.getOuterWidth(this.div);
+	var top = DOM.getOuterHeight(this.div);
+	if (isNaN(left)) { left=0; }
+	if (isNaN(top)) { top=0; }	
+	var clientW = Screen.getViewportWidth();
+	var clientH = Screen.getViewportHeight();
+	if (clientW!=null && clientH!=null) {
+		top = (clientH-top)/2;
+		left = (clientW-left)/2;
+	}
+	top += Screen.getScrollTop();
+	left += Screen.getScrollLeft();
+	
+	this.div.style.top = top+this.offsetTop+"px";
+	this.div.style.left = left+this.offsetLeft+"px";
+};
+
--- a/configurationengine/source/scripts/report_util.py	Fri Mar 12 08:30:17 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,190 +0,0 @@
-#
-# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
-# All rights reserved.
-# This component and the accompanying materials are made available
-# under the terms of "Eclipse Public License v1.0"
-# which accompanies this distribution, and is available
-# at the URL "http://www.eclipse.org/legal/epl-v10.html".
-#
-# Initial Contributors:
-# Nokia Corporation - initial contribution.
-#
-# Contributors:
-#
-# Description:
-#
-
-import os
-import urllib
-import logging
-from jinja2 import Environment, FileSystemLoader, Template
-from cone.public import utils
-
-ROOT_PATH = os.path.abspath(os.path.dirname(__file__))
-
-log = logging.getLogger('cone.report_util')
-
-class ReportShortcut(object):
-    def __init__(self, template_file, report_file, description):
-        self.template_file = template_file
-        self.report_file = report_file
-        self.description = description
-
-class ReportShortcutContainer(object):
-    """
-    Container for report shortcuts.
-    
-    A report shortcut describes a pre-defined report option that
-    has a default template, report file and description. The shortcut
-    container holds a set of shortcuts and can be used to generate
-    
-    """
-    def __init__(self, shortcuts, default_shortcut):
-        """
-        @param shortcuts: The shortcuts, a dictionary mapping shortcut
-            names to ReportShortcut objects.
-        @param default_shortcut: The default shortcut name to use
-        """
-        if not isinstance(shortcuts, dict):
-            raise ValueError("'shortcuts' must a dictionary (%s given)!" % type(shortcuts))
-        if default_shortcut is not None and default_shortcut not in shortcuts:
-            raise ValueError("'default_shortcut' must be either None or exist ing 'shortcuts'!")
-        self.shortcuts = shortcuts
-        self.default_shortcut = default_shortcut
-    
-    def get_shortcut_help_text(self):
-        """
-        Create the text to append to the option description for the
-        option used to specify the used shortcut.
-        """
-        shortcuts_text = []
-        refs = sorted(self.shortcuts.keys())
-        if refs:
-            for ref in refs:
-                sc = self.shortcuts[ref]
-                text = "%s - %s" % (ref, sc.description)
-                COLUMN_WIDTH = (80 - 25)
-                space_count = COLUMN_WIDTH - (len(text) % COLUMN_WIDTH)
-                shortcuts_text.append(text + space_count * ' ')
-        else:
-            shortcuts_text.append("None")
-        shortcuts_text = '\n'.join(shortcuts_text)
-        return shortcuts_text
-    
-    def is_valid_shortcut(self, shortcut):
-        """
-        Return whether the given shortcut is valid within the context
-        of this container.
-        """
-        return shortcut is None or shortcut in self.shortcuts
-    
-    def determine_template_and_report(self, shortcut, template_file, report_file, report_file_name_without_ext):
-        """
-        Determine the actual template and report files based on the shortcuts
-        and given options.
-        @param shortcut: The used shortcut or None.
-        @param template_file: Explicitly given template file or None.
-        @param report_file: Explicitly given report file or None.
-        @param report_file_name_without_ext: Prefix used to determine the
-            report file name if the template was explicitly given, but the
-            report file was not. E.g. if this is 'test' and the explicitly
-            given template file is 'my_template.html', the report file would
-            be 'test.html'.
-        @return: Tuple (template_file, report_file) specifying the actual
-            template and report files.
-        """
-        actual_shortcut      = None
-        actual_template_file = None
-        actual_report_file   = None
-        
-        # Handle report shortcut (set to default or check the given one)
-        if not shortcut:
-            actual_shortcut = self.default_shortcut
-        else:
-            actual_shortcut = shortcut
-        
-        # Determine template file
-        if template_file:
-            actual_template_file = template_file
-        else:
-            actual_template_file = self.shortcuts[actual_shortcut].template_file
-        
-        # Determine report output file
-        if report_file:
-            actual_report_file = report_file
-        else:
-            if template_file:
-                # Determine report file name based on the template file name
-                # if the template was explicitly given
-                actual_report_file = report_file_name_without_ext + os.path.splitext(template_file)[1]
-            else:
-                actual_report_file = self.shortcuts[actual_shortcut].report_file
-        
-        return actual_template_file, actual_report_file
-
-def generate_report(template_file, report_file, report_data):
-    """
-    Generate a report based on the given template file, report file
-    and data dictionary.
-    @param template_file: Path to the template file to use.
-    @param report_file: Path to the output report file.
-    @param report_data: The report data dictionary used when rendering
-        the report from the template.
-    @return: True if successful, False if not.
-    """
-    log.debug('generate_report(template_file=%r, report_file=%r, <data>)' % (template_file, report_file))
-    if not isinstance(report_data, dict):
-        raise ValueError("report_data must be a dictionary!")
-    
-    try:
-        template_file = os.path.abspath(template_file)
-        
-        loader = FileSystemLoader([os.path.dirname(template_file), ROOT_PATH])
-        env = Environment(loader=loader)
-        _set_default_filters(env)
-        
-        template = env.get_template(os.path.basename(template_file))
-        file_string = template.render(report_data)
-        
-        # Create directories for the report
-        report_dir = os.path.dirname(report_file)
-        if report_dir != '' and not os.path.exists(report_dir):
-            os.makedirs(report_dir)
-        
-        # Write the rendered report to file
-        f = open(report_file, 'wb')
-        try:        f.write(file_string.encode('utf-8'))
-        finally:    f.close()
-        
-        print "Generated report to '%s'" % report_file
-        return True
-    except Exception, e:
-        utils.log_exception(log, "Failed to generate report: %s %s" % (type(e), e))
-        return False
-
-def _set_default_filters(env):
-    """
-    Set default filters to the given Jinja environment
-    """
-    env.filters['xml_charref_replace'] = lambda value: unicode(value).encode('ascii', 'xmlcharrefreplace')
-    env.filters['pathname_to_url'] = lambda value: urllib.pathname2url(value)
-    env.filters['csv_escape'] = _csv_escape
-    env.filters['csv_escape_partial'] = lambda value: unicode(value).replace('"', '""')
-
-def _csv_escape(value):
-    """
-    Escape a string value so that it can be used as a field in a CSV file.
-    """
-    value = unicode(value)
-    
-    needs_quoting = False
-    for special_char in '",\n':
-        if special_char in value:
-            needs_quoting = True
-    
-    if needs_quoting:
-        if '"' in value:
-            value = value.replace('"', '""')
-        value = '"' + value + '"'
-    
-    return value
--- a/configurationengine/source/scripts/setup.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/setup.py	Tue Aug 10 14:29:28 2010 +0300
@@ -19,14 +19,16 @@
 require("setuptools")
 from setuptools import setup, find_packages
 
-datafiles = ['gen_report_template.html',
-             'cone_defaults.cfg',
+datafiles = ['cone_defaults.cfg',
              'conesub_generate.cfg',
              'imaker_variantdir.cfg',
+             'cone.ini',
              'logging.ini',
              'cone_base.html',
+             'gen_report_template.html',
              'compare_api_report_template.html',
              'compare_data_report_template.html',
+             'compare_ci_report_template.html',
              'info_api_report_template.csv',
              'info_api_report_template.html',
              'info_impl_report_template.html',
@@ -34,7 +36,11 @@
              'info_value_report_template.html',
              'info_value_report_template.csv',
              'crml_dc_report_template.csv',
-             'crml_dc_report_template.html']
+             'crml_dc_report_template.html',
+             'validation_report_template.html',
+             'validation_report_template.xml',
+             'tablefilter.js',
+             'popup.js']
 
 setup(
     name = "cone-scripts",
@@ -43,6 +49,7 @@
                'cone_common.py',
                'cone_subaction.py',
                'conesub_info.py',
+               'conesub_fix.py',
                'conesub_export.py',
                'conesub_generate.py',
                'conesub_merge.py',
@@ -50,8 +57,10 @@
                #'conesub_import_browserbookmarks.py',
                'conesub_update.py',
                'conesub_report.py',
-               'generation_report.py',
-               'report_util.py'] + 
+               'conesub_validate.py',
+               'conesub_packvariant.py',
+               'conesub_initvariant.py',
+               'configroot2flat.py'] + 
                datafiles,
 
     author = "Teemu Rytkonen",
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tablefilter.js	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4843 @@
+/*------------------------------------------------------------------------
+	- HTML Table Filter Generator v1.9.6
+	- By Max Guglielmi (tablefilter.free.fr)
+	- Licensed under the MIT License
+--------------------------------------------------------------------------
+Copyright (c) 2009 Max Guglielmi
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+--------------------------------------------------------------------------
+	- Special credit to: 
+	Cedric Wartel, cnx.claude@free.fr, Florent Hirchy, Váry Péter, 
+	Anthony Maes, Nuovella Williams, Fuggerbit, Venkata Seshagiri Rao 
+	Raya for active contribution and inspiration
+------------------------------------------------------------------------*/
+
+function setFilterGrid(id)
+/*====================================================
+	- Sets filters grid bar
+	- Calls TF Constructor and generates grid bar
+	- Params:
+			- id: table id (string)
+			- refRow (optional): row index (number)
+			- config (optional): configuration 
+			object (literal object)
+=====================================================*/
+{
+	if( arguments.length==0 ) return;
+	eval( 'tf_'+id+' = new TF(arguments[0],arguments[1],arguments[2])' );
+	eval( 'tf_'+id+'.AddGrid();' );
+}
+
+/*===BEGIN removable section===========================
+	- Unobtrusive grid bar generation using 
+	'filterable' class
+	- If you don't use it you can remove safely this 
+	section
+/*=====================================================*/
+tf_addEvent(window, 'load', initFilterGrid);
+
+function initFilterGrid()
+{
+	if (!document.getElementsByTagName) return;
+	var tbls = tf_Tag(document,'table'), config;
+	for (var i=0; i<tbls.length; i++)
+	{
+		var cTbl = tbls[i], cTblId = cTbl.getAttribute('id');
+		if( tf_hasClass(cTbl,'filterable') && cTblId )
+		{
+			if( tf_isObj(cTblId+'_config') )
+				config = eval(cTblId+'_config');
+			else
+				config = undefined;
+			setFilterGrid( cTblId,config );
+		}
+	}// for i
+}
+/*===END removable section===========================*/
+
+var TF = function( id )
+/*====================================================
+	- TF object constructor
+	- Params:
+			- id: table id (string)
+			- refRow (optional): row index (number)
+			- config (optional): configuration 
+			object (literal object)
+=====================================================*/
+{
+	if( arguments.length==0 ) return;
+		
+	this.id = id;
+	this.tbl = tf_Id(id);
+	this.startRow = undefined;
+	this.refRow = null;
+	this.headersRow = null;
+	this.fObj = null;
+	this.nbFilterableRows = null;
+	this.nbRows = null;
+	this.nbCells = null;
+	this.hasGrid = false;
+	
+	if(this.tbl != null && this.tbl.nodeName.tf_LCase() == 'table' && this.GetRowsNb())
+    {
+		if(arguments.length>1)
+        {
+            for(var i=0; i<arguments.length; i++)
+            {
+                var argtype = typeof arguments[i];
+               
+                switch(argtype.tf_LCase())
+                {
+                    case 'number':
+                        this.startRow = arguments[i];
+                    break;
+                    case 'object':
+                        this.fObj = arguments[i];
+                    break;
+                }//switch                           
+            }//for
+        }//if
+		
+		var f = this.fObj;
+		
+		/*** filter types ***/
+		this.fltTypeInp =			'input';
+		this.fltTypeSlc =			'select';
+		this.fltTypeMulti =			'multiple';
+		this.fltTypeCheckList =		'checklist';
+		this.fltTypeNone =			'none';
+		
+		/*** filters' grid properties ***/
+		this.fltGrid = 				f!=undefined && f.grid==false ? false : true; //enables/disables filter grid
+		
+		/*** Grid layout ***/
+		this.gridLayout = 			f!=undefined && f.grid_layout ? true : false; //enables/disables grid layout (fixed headers)
+		this.gridWidth =			f!=undefined && f.grid_width!=undefined ? f.grid_width : null; //defines grid width
+		this.gridHeight =			f!=undefined && f.grid_height!=undefined ? f.grid_height : null; //defines grid height
+		this.gridMainContCssClass = f!=undefined && f.grid_cont_css_class!=undefined //defines css class for main container
+										? f.grid_cont_css_class : 'grd_Cont';
+		this.gridContCssClass =		f!=undefined && f.grid_tbl_cont_css_class!=undefined //defines css class for div containing table
+										? f.grid_tbl_cont_css_class : 'grd_tblCont';
+		this.gridHeadContCssClass = f!=undefined && f.grid_tblHead_cont_css_class!=undefined //defines css class for div containing headers' table
+										? f.grid_tblHead_cont_css_class : 'grd_headTblCont';
+		this.gridInfDivCssClass =	f!=undefined && f.grid_inf_grid_css_class!=undefined //defines css class for div containing rows counter, paging etc.
+										? f.grid_inf_grid_css_class : 'grd_inf';
+		this.gridHeadRowIndex =		f!=undefined && f.grid_headers_row_index!=undefined //defines which row contains column headers
+										? f.grid_headers_row_index : 0; 
+		this.gridHeadRows =			f!=undefined && f.grid_headers_rows!=undefined //array of headers row indexes to be placed in header table
+										? f.grid_headers_rows : [0];
+		this.gridEnableFilters =	f!=undefined && f.grid_enable_default_filters!=undefined 
+										? f.grid_enable_default_filters : true; //generate filters in table headers
+		this.gridDefaultColWidth =	f!=undefined && f.grid_default_col_width!=undefined 
+										? f.grid_default_col_width : '100px'; //default col width						
+		this.gridEnableColResizer =	f!=undefined && f.grid_enable_cols_resizer!=undefined 
+										? f.grid_enable_cols_resizer : true; //enables/disables columns resizer
+		this.hasGridWidthsRow =		false; //flag indicating if the grid has an additional row for column widths (IE<=7)
+		this.gridColElms =			[];
+		this.sourceTblHtml = 		this.tbl.outerHTML; //original table html												
+		/*** ***/
+								
+		this.filtersRowIndex =		f!=undefined && f.filters_row_index!=undefined //defines in which row filters grid bar is generated
+										? f.filters_row_index>1 ? 1 : f.filters_row_index : 0;
+		this.fltCellTag =			f!=undefined && f.filters_cell_tag!=undefined //defines tag of the cells containing filters (td/th)
+										? (f.filters_cell_tag!='th' ? 'td' : 'th') : 'td';		
+		this.fltIds = 				[]; //stores filters ids
+		this.searchArgs =			null; //stores filters values
+		this.tblData =				[]; //stores table data
+		this.validRowsIndex =		null; //stores valid rows indexes (rows visible upon filtering)
+		this.fltGridEl =			null; //stores filters row element
+		this.isFirstLoad =			true; //is first load boolean 
+		this.infDiv =				null; //container div for paging elements, reset btn etc.
+		this.lDiv =					null; //div for rows counter
+		this.rDiv =					null; //div for reset button and results per page select
+		this.mDiv =					null; //div for paging elements
+		this.contDiv =				null; //table container div for fixed headers (IE only)
+		this.infDivCssClass =		f!=undefined && f.inf_div_css_class!=undefined	//defines css class for div containing
+										? f.inf_div_css_class : 'inf';				//paging elements, rows counter etc.
+		this.lDivCssClass =			f!=undefined && f.left_div_css_class!=undefined	//defines css class for left div 
+										? f.left_div_css_class : 'ldiv';
+		this.rDivCssClass =			f!=undefined && f.right_div_css_class!=undefined //defines css class for right div 
+										? f.right_div_css_class : 'rdiv';
+		this.mDivCssClass =			f!=undefined && f.middle_div_css_class!=undefined //defines css class for mid div 
+										? f.middle_div_css_class : 'mdiv';
+		this.contDivCssClass =		f!=undefined && f.content_div_css_class!=undefined 
+										? f.content_div_css_class : 'cont';	//table container div css class
+		
+		/*** filters' grid appearance ***/
+		this.fltsRowCssClass =		f!=undefined && f.flts_row_css_class!=undefined //defines css class for filters row
+										? f.flts_row_css_class : 'fltrow';		
+		this.alternateBgs =			f!=undefined && f.alternate_rows ? true : false; //enables/disbles rows alternating bg colors
+		this.hasColWidth =			f!=undefined && f.col_width ? true : false; //defines widths of columns
+		this.colWidth =				f!=undefined && this.hasColWidth ? f.col_width : null;
+		this.fixedHeaders =			f!=undefined && f.fixed_headers ? true : false; //enables/disables fixed headers
+		this.tBodyH = 				f!=undefined && f.tbody_height ? f.tbody_height : 200; //tbody height if fixed headers enabled
+		this.fltCssClass =			f!=undefined && f.flt_css_class!=undefined //defines css class for filters
+										? f.flt_css_class : 'flt';
+		this.fltMultiCssClass =		f!=undefined && f.flt_multi_css_class!=undefined //defines css class for multiple selects filters
+										? f.flt_multi_css_class : 'flt_multi';
+		this.fltSmallCssClass =		f!=undefined && f.flt_small_css_class!=undefined //defines css class for filters
+										? f.flt_small_css_class : 'flt_s';
+		this.singleFltCssClass =	f!=undefined && f.single_flt_css_class!=undefined //defines css class for single-filter
+										? f.single_flt_css_class : 'single_flt';	
+		this.isStartBgAlternate =	true;
+		this.rowBgEvenCssClass =	f!=undefined && f.even_row_css_class!=undefined //defines css class for even rows
+										? f.even_row_css_class :'even';
+		this.rowBgOddCssClass =		f!=undefined && f.odd_row_css_class!=undefined //defines css class for odd rows
+										? f.odd_row_css_class :'odd';
+		
+		/*** filters' grid behaviours ***/
+		this.enterKey =				f!=undefined && f.enter_key==false ? false : true; //enables/disables enter key
+		this.isModFilterFn = 		f!=undefined && f.mod_filter_fn ? true : false; //enables/disables alternative fn call		
+		this.modFilterFn =			this.isModFilterFn ? f.mod_filter_fn : null;// used by tf_DetectKey fn
+		this.onBeforeFilter =		f!=undefined && tf_isFn(f.on_before_filter) //calls function before filtering starts
+										? f.on_before_filter : null;
+		this.onAfterFilter =		f!=undefined && tf_isFn(f.on_after_filter) //calls function after filtering
+										? f.on_after_filter : null;								
+		this.matchCase =			f!=undefined && f.match_case ? true : false; //enables/disables case sensitivity
+		this.exactMatch =			f!=undefined && f.exact_match ? true : false; //enables/disbles exact match for search
+		this.refreshFilters =		f!=undefined && f.refresh_filters ? true : false; //refreshes drop-down lists upon validation
+		this.activeFlt =			null; //stores active filter element
+		this.activeFilterId =		null; //id of active filter
+		this.hasColOperation =		f!=undefined && f.col_operation ? true : false; //enables/disbles column operation(sum,mean)
+		this.colOperation =			null;
+		this.hasVisibleRows = 		f!=undefined && f.rows_always_visible ? true : false; //enables always visible rows
+		this.visibleRows =			this.hasVisibleRows ? f.rows_always_visible : [];//array containing always visible rows
+		this.searchType =			f!=undefined && f.search_type!=undefined //defines search type: include or exclude
+										? f.search_type : 'include';
+		this.isExternalFlt =		f!=undefined && f.external_flt_grid ? true : false; //enables/disables external filters generation
+		this.externalFltTgtIds =	f!=undefined && f.external_flt_grid_ids!=undefined //array containing ids of external elements containing filters
+										? f.external_flt_grid_ids : null;
+		this.externalFltEls =		[]; //stores filters elements if isExternalFlt is true		
+		this.execDelay =			f!=undefined && f.exec_delay ? parseInt(f.exec_delay) : 100; //delays filtering process if loader true
+		this.status =				f!=undefined && f.status ? true : false; //enables/disables status messages
+		this.onFiltersLoaded =		f!=undefined && tf_isFn(f.on_filters_loaded) //calls function when filters grid loaded
+										? f.on_filters_loaded : null;
+		this.singleSearchFlt =		f!=undefined && f.single_search_filter ? true : false; //enables/disables single filter search
+		this.onRowValidated =		f!=undefined && tf_isFn(f.on_row_validated) //calls function after row is validated
+									 	? f.on_row_validated : null;
+		this.customCellDataCols =	f!=undefined && f.custom_cell_data_cols ? f.custom_cell_data_cols : []; //array defining columns for customCellData event 	
+		this.customCellData =		f!=undefined && tf_isFn(f.custom_cell_data) //calls custom function for retrieving cell data
+									 	? f.custom_cell_data : null;																
+		
+		/*** selects customisation and behaviours ***/
+		this.displayAllText =		f!=undefined && f.display_all_text!=undefined ? f.display_all_text : ''; //defines 1st option text
+		this.onSlcChange = 			f!=undefined && f.on_change==false ? false : true; //enables/disables onChange event on combo-box 
+		this.sortSlc =				f!=undefined && f.sort_select==false ? false : true; //enables/disables select options sorting
+		this.isSortNumAsc =			f!=undefined && f.sort_num_asc ? true : false; //enables/disables ascending numeric options sorting
+		this.sortNumAsc =			this.isSortNumAsc ? f.sort_num_asc : null;
+		this.isSortNumDesc =		f!=undefined && f.sort_num_desc ? true : false; //enables/disables descending numeric options sorting
+		this.sortNumDesc =			this.isSortNumDesc ? f.sort_num_desc : null;
+		this.slcFillingMethod =		f!=undefined && f.slc_filling_method!=undefined //sets select filling method: 'innerHTML' or 
+										? f.slc_filling_method : 'createElement';	//'createElement'
+		this.fillSlcOnDemand =		f!=undefined && f.fill_slc_on_demand ? true : false; //enabled selects are populated on demand
+		this.activateSlcTooltip =	f!=undefined && f.activate_slc_tooltip!=undefined //IE only, tooltip text appearing on select 
+										? f.activate_slc_tooltip : 'Click to activate'; // before it is populated
+		this.multipleSlcTooltip =	f!=undefined && f.multiple_slc_tooltip!=undefined //tooltip text appearing on multiple select 
+										? f.multiple_slc_tooltip : 'Use Ctrl key for multiple selections';
+		this.hasCustomSlcOptions =	f!=undefined && f.custom_slc_options &&
+										(typeof f.custom_slc_options).tf_LCase() == 'object' 
+										? true : false;	
+		this.customSlcOptions =		f!=undefined && f.custom_slc_options!=undefined
+										? f.custom_slc_options : null;
+		this.onBeforeOperation =	f!=undefined && tf_isFn(f.on_before_operation) //calls function before col operation
+										? f.on_before_operation : null;
+		this.onAfterOperation =		f!=undefined && tf_isFn(f.on_after_operation) //calls function after col operation
+										? f.on_after_operation : null;
+		
+		/*** checklist customisation and behaviours ***/
+		this.checkListDiv = 		[]; //checklist container div
+		this.checkListDivCssClass = f!=undefined && f.div_checklist_css_class!=undefined 
+										? f.div_checklist_css_class : 'div_checklist'; //defines css class for div containing checklist filter
+		this.checkListCssClass =	f!=undefined && f.checklist_css_class!=undefined //defines css class for checklist filters
+										? f.checklist_css_class : 'flt_checklist';
+		this.checkListItemCssClass = f!=undefined && f.checklist_item_css_class!=undefined //defines css class for checklist item (li)
+										? f.checklist_item_css_class : 'flt_checklist_item';
+		this.checkListSlcItemCssClass = f!=undefined && f.checklist_selected_item_css_class!=undefined //defines css class for selected checklist item (li)
+										? f.checklist_selected_item_css_class : 'flt_checklist_slc_item';								
+		this.activateCheckListTxt =	f!=undefined && f.activate_checklist_text!=undefined //Load on demand text 
+										? f.activate_checklist_text : 'Click to load data';
+		
+		/*** Filter operators ***/
+		this.orOperator =			f!=undefined && f.or_operator!=undefined ? f.or_operator : '||';
+		this.anOperator =			f!=undefined && f.and_operator!=undefined ? f.and_operator : '&&';
+		this.grOperator = 			f!=undefined && f.greater_operator!=undefined ? f.greater_operator : '>';
+		this.lwOperator =			f!=undefined && f.lower_operator!=undefined ? f.lower_operator : '<';
+		this.leOperator =			f!=undefined && f.lower_equal_operator!=undefined ? f.lower_equal_operator : '<=';
+		this.geOperator =			f!=undefined && f.greater_equal_operator!=undefined ? f.greater_equal_operator : '>=';
+		this.dfOperator =			f!=undefined && f.different_operator!=undefined ? f.different_operator : '!';
+		this.lkOperator =			f!=undefined && f.like_operator!=undefined ? f.like_operator : '*';
+		this.eqOperator =			f!=undefined && f.equal_operator!=undefined ? f.equal_operator : '=';
+		this.stOperator =			f!=undefined && f.start_with_operator!=undefined ? f.start_with_operator : '{';
+		this.enOperator =			f!=undefined && f.end_with_operator!=undefined ? f.end_with_operator : '}';
+		this.curExp =				f!=undefined && f.cur_exp!=undefined ? f.cur_exp : '^[¥£€$]';
+		this.separator = 			f!=undefined && f.separator!=undefined ? f.separator : ',';
+		
+		/*** rows counter ***/
+		this.rowsCounter = 			f!=undefined && f.rows_counter ? true : false; //show/hides rows counter
+		this.rowsCounterTgtId =		f!=undefined && f.rows_counter_target_id!=undefined //id of custom container element
+										? f.rows_counter_target_id : null;
+		this.rowsCounterDiv =		null; //element containing tot nb rows
+		this.rowsCounterSpan =		null; //element containing tot nb rows label
+		this.rowsCounterText =		f!=undefined && f.rows_counter_text!=undefined
+										? f.rows_counter_text : 'Rows: '; //defines rows counter text
+		this.totRowsCssClass =		f!=undefined && f.tot_rows_css_class!=undefined //defines css class rows counter
+										? f.tot_rows_css_class : 'tot';		
+		
+		/*** status bar ***/
+		this.statusBar =			f!=undefined && f.status_bar ? true : false; //show/hides status bar
+		this.statusBarTgtId =		f!=undefined && f.status_bar_target_id!=undefined //id of custom container element
+										? f.status_bar_target_id : null;
+		this.statusBarDiv =			null; //element containing status bar label
+		this.statusBarSpan =		null; //status bar
+		this.statusBarSpanText =	null; //status bar label
+		this.statusBarText =		f!=undefined && f.status_bar_text!=undefined
+										? f.status_bar_text : ''; //defines status bar text
+		this.statusBarCssClass =	f!=undefined && f.status_bar_css_class!=undefined //defines css class status bar
+										? f.status_bar_css_class : 'status';
+		this.statusBarCloseDelay =	250; //delay for status bar clearing			
+		
+		/*** loader ***/
+		this.loader =				f!=undefined && f.loader ? true : false; //enables/disables loader
+		this.loaderTgtId =			f!=undefined && f.loader_target_id!=undefined //id of container element
+										? f.loader_target_id : null;
+		this.loaderDiv =			null; //div containing loader
+		this.loaderText =			f!=undefined && f.loader_text!=undefined ? f.loader_text : 'Loading...'; //defines loader text
+		this.loaderHtml =			f!=undefined && f.loader_html!=undefined ? f.loader_html : null; //defines loader innerHtml
+		this.loaderCssClass = 		f!=undefined && f.loader_css_class!=undefined //defines css class for loader div
+										? f.loader_css_class : 'loader';
+		this.loaderCloseDelay =		200; //delay for hiding loader
+		this.onShowLoader =			f!=undefined && tf_isFn(f.on_show_loader) //calls function before loader is displayed
+										? f.on_show_loader : null;
+		this.onHideLoader =			f!=undefined && tf_isFn(f.on_hide_loader) //calls function after loader is closed
+										? f.on_hide_loader : null;					
+		
+		/*** validation - reset buttons/links ***/
+		this.displayBtn =			f!=undefined && f.btn ? true : false; //show/hides filter's validation button
+		this.btnText =				f!=undefined && f.btn_text!=undefined ? f.btn_text : 'go'; //defines validation button text
+		this.btnCssClass =			f!=undefined && f.btn_css_class!=undefined //defines css class for validation button
+										? f.btn_css_class : 'btnflt';
+		this.btnReset = 			f!=undefined && f.btn_reset ? true : false; //show/hides reset link
+		this.btnResetTgtId =		f!=undefined && f.btn_reset_target_id!=undefined //id of container element
+										? f.btn_reset_target_id : null;
+		this.btnResetEl =			null; //reset button element
+		this.btnResetText =			f!=undefined && f.btn_reset_text!=undefined ? f.btn_reset_text : 'Reset'; //defines reset text
+		this.btnResetHtml = 		f!=undefined && f.btn_reset_html!=undefined ? f.btn_reset_html : null; //defines reset button innerHtml
+		this.btnResetCssClass =		f!=undefined && f.btn_reset_css_class!=undefined //defines css class for reset button
+										? f.btn_reset_css_class :'reset';
+		
+		/*** paging ***/
+		this.paging =				f!=undefined && f.paging ? true : false; //enables/disables table paging
+		this.pagingTgtId =			f!=undefined && f.paging_target_id!=undefined //id of container element
+										? f.paging_target_id : null;		
+		this.pagingLength =			f!=undefined && f.paging_length!=undefined ? f.paging_length : 10; //defines table paging length
+		this.hasResultsPerPage =	f!=undefined && f.results_per_page ? true : false; //enables/disables results per page drop-down
+		this.resultsPerPageTgtId =	f!=undefined && f.results_per_page_target_id!=undefined //id of container element
+										? f.results_per_page_target_id : null;	
+		this.resultsPerPage =		null; //stores results per page text and values			
+		this.pagingSlc =			null; //stores paging select element
+		this.isPagingRemoved =		false; //indicates if paging elements were previously removed
+		this.pgSlcCssClass =		f!=undefined && f.paging_slc_css_class!=undefined
+										? f.paging_slc_css_class :'pgSlc'; //css class for paging select element
+		this.pgInpCssClass =		f!=undefined && f.paging_inp_css_class!=undefined
+										? f.paging_inp_css_class :'pgNbInp'; //css class for paging input element
+		this.resultsPerPageSlc =	null; //results per page select element
+		this.resultsSlcCssClass =	f!=undefined && f.results_slc_css_class!=undefined
+										? f.results_slc_css_class :'rspg'; //defines css class for results per page select
+		this.resultsSpanCssClass =	f!=undefined && f.results_span_css_class!=undefined
+										? f.results_span_css_class :'rspgSpan'; //css class for label preceding results per page select
+		this.nbVisibleRows	=		0; //nb visible rows
+		this.nbHiddenRows =			0; //nb hidden rows
+		this.startPagingRow =		0; //1st row index of current page
+		this.nbPages = 				0; //total nb of pages
+		this.currentPageNb =		1; //current page nb
+		this.btnNextPageText = 		f!=undefined && f.btn_next_page_text!=undefined
+										? f.btn_next_page_text : '>'; //defines next page button text
+		this.btnPrevPageText =		f!=undefined && f.btn_prev_page_text!=undefined
+										? f.btn_prev_page_text : '<'; //defines previous page button text
+		this.btnLastPageText =		f!=undefined && f.btn_last_page_text!=undefined
+										? f.btn_last_page_text : '>|'; //defines last page button text
+		this.btnFirstPageText =		f!=undefined && f.btn_first_page_text!=undefined
+										? f.btn_first_page_text : '|<' ; //defines first page button text
+		this.btnNextPageHtml =		f!=undefined && f.btn_next_page_html!=undefined
+										? f.btn_next_page_html : null; //defines next page button html
+		this.btnPrevPageHtml =		f!=undefined && f.btn_prev_page_html!=undefined
+										? f.btn_prev_page_html : null; //defines previous page button html
+		this.btnFirstPageHtml =		f!=undefined && f.btn_first_page_html!=undefined
+										? f.btn_first_page_html : null; //defines last page button html
+		this.btnLastPageHtml =		f!=undefined && f.btn_last_page_html!=undefined
+										? f.btn_last_page_html : null; //defines previous page button html
+		this.btnPageCssClass =		f!=undefined && f.paging_btn_css_class!=undefined
+										? f.paging_btn_css_class :'pgInp'; //css class for paging buttons (previous,next,etc.)
+		this.nbPgSpanCssClass = 	f!=undefined && f.nb_pages_css_class!=undefined
+										? f.nb_pages_css_class :'nbpg'; //css class for span containing tot nb of pages
+		this.hasPagingBtns =		f!=undefined && f.paging_btns==false ? false : true; //enables/disables paging buttons
+		this.pagingBtnEvents =		null; //stores paging buttons events
+		this.pageSelectorType =		f!=undefined && f.page_selector_type!=undefined
+										? f.page_selector_type : this.fltTypeSlc; //defines previous page button html		
+		
+		/*** webfx sort adapter ***/
+		this.sort =					f!=undefined && f.sort ? true : false; //enables/disables default table sorting
+		this.isSortEnabled =		false; //indicates if sort is set (used in tfAdapter.sortabletable.js)
+		this.sorted =				false; //indicates if tables was sorted
+		this.sortConfig =			f!=undefined && f.sort_config!=undefined 
+										? f.sort_config : {};
+		this.sortConfig.name =		f!=undefined && f.sort_config!=undefined && f.sort_config.name
+										? f.sort_config.name : 'sortabletable';
+		this.sortConfig.src =		f!=undefined && f.sort_config!=undefined && f.sort_config.src
+										? f.sort_config.src : 'sortabletable.js';
+		this.sortConfig.adapterSrc =f!=undefined && f.sort_config!=undefined && f.sort_config.adapter_src
+										? f.sort_config.adapter_src : 'tfAdapter.sortabletable.js';
+		this.sortConfig.initialize =f!=undefined && f.sort_config!=undefined && f.sort_config.initialize
+										? f.sort_config.initialize
+										: function(o){ if(o.SetSortTable) o.SetSortTable(); };
+		this.sortConfig.sortTypes =	f!=undefined && f.sort_config!=undefined && f.sort_config.sort_types
+										? f.sort_config.sort_types : [];
+		this.sortConfig.sortCol =	f!=undefined && f.sort_config!=undefined && f.sort_config.sort_col!=undefined
+										? f.sort_config.sort_col : null;
+		this.sortConfig.asyncSort =	f!=undefined && f.sort_config!=undefined && f.sort_config.async_sort
+										? true : false;
+		this.sortConfig.triggerIds =f!=undefined && f.sort_config!=undefined && f.sort_config.sort_trigger_ids
+										? f.sort_config.sort_trigger_ids : [];									
+		
+		/*** onkeyup event ***/
+		this.onKeyUp =				f!=undefined && f.on_keyup ? true : false; //enables/disables onkeyup event, table is filtered when user stops typing
+		this.onKeyUpDelay =			f!=undefined && f.on_keyup_delay!=undefined ? f.on_keyup_delay : 900; //onkeyup delay timer (msecs)
+		this.isUserTyping = 		null; //typing indicator
+		this.onKeyUpTimer = 		undefined;		
+		
+		/*** keyword highlighting ***/
+		this.highlightKeywords = 	f!=undefined && f.highlight_keywords ? true : false; //enables/disables keyword highlighting
+		this.highlightCssClass =	f!=undefined && f.highlight_css_class!=undefined //defines css class for highlighting
+										? f.highlight_css_class : 'keyword';	
+		
+		/*** data types ***/
+		this.defaultDateType =		f!=undefined && f.default_date_type!=undefined //defines default date type (european DMY)
+										? f.default_date_type : 'DMY';
+		this.thousandsSeparator =	f!=undefined && f.thousands_separator!=undefined //defines default thousands separator 
+										? f.thousands_separator : ','; //US = ',' EU = '.'
+		this.decimalSeparator = 	f!=undefined && f.decimal_separator!=undefined //defines default decimal separator 
+										? f.decimal_separator : '.'; //US & javascript = '.' EU = ','
+		this.hasColNbFormat = 		f!=undefined && f.col_number_format ? true : false; //enables number format per column
+		this.colNbFormat = 			f!=undefined && this.hasColNbFormat ? f.col_number_format : null; //array containing columns nb formats
+		this.hasColDateType = 		f!=undefined && f.col_date_type ? true : false; //enables date type per column
+		this.colDateType =			f!=undefined && this.hasColDateType ? f.col_date_type : null; //array containing columns date type
+		
+		/*** status messages ***/
+		this.msgFilter =			f!=undefined && f.msg_filter!=undefined //filtering
+										? f.msg_filter : 'Filtering data...'; 
+		this.msgPopulate =			f!=undefined && f.msg_populate!=undefined //populating drop-downs
+										? f.msg_populate : 'Populating filter...'; 
+		this.msgPopulateCheckList =	f!=undefined && f.msg_populate_checklist!=undefined //populating drop-downs
+										? f.msg_populate_checklist : 'Populating list...'; 
+		this.msgChangePage =		f!=undefined && f.msg_change_page!=undefined //changing paging page
+										? f.msg_change_page : 'Collecting paging data...';
+		this.msgClear =				f!=undefined && f.msg_clear!=undefined //clearing filters
+										? f.msg_clear : 'Clearing filters...';
+		this.msgChangeResults =		f!=undefined && f.msg_change_results!=undefined //changing nb results/page
+										? f.msg_change_results : 'Changing results per page...';
+		this.msgResetValues =		f!=undefined && f.msg_reset_grid_values!=undefined //re-setting grid values
+										? f.msg_reset_grid_values : 'Re-setting filters values...';
+		this.msgResetPage =			f!=undefined && f.msg_reset_page!=undefined //re-setting page
+										? f.msg_reset_page : 'Re-setting page...';
+		this.msgResetPageLength =	f!=undefined && f.msg_reset_page_length!=undefined //re-setting page length
+										? f.msg_reset_page_length : 'Re-setting page length...';
+		this.msgSort =				f!=undefined && f.msg_sort!=undefined //table sorting
+										? f.msg_sort : 'Sorting data...';
+		this.msgLoadExtensions =	f!=undefined && f.msg_load_extensions!=undefined //table sorting
+										? f.msg_load_extensions : 'Loading extensions...';			
+
+		/*** ids prefixes ***/
+		this.prfxFlt =				'flt'; //filters (inputs - selects)
+		this.prfxValButton =		'btn'; //validation button
+		this.prfxInfDiv =			'inf_'; //container div for paging elements, rows counter etc.
+		this.prfxLDiv =				'ldiv_'; //left div
+		this.prfxRDiv =				'rdiv_'; //right div
+		this.prfxMDiv =				'mdiv_'; //middle div
+		this.prfxContentDiv =		'cont_'; //table container if fixed headers enabled
+		this.prfxCheckListDiv =		'chkdiv_'; //checklist filter container div
+		this.prfxSlcPages =			'slcPages_'; //pages select
+		this.prfxSlcResults = 		'slcResults_'; //results per page select
+		this.prfxSlcResultsTxt =	'slcResultsTxt_'; //label preciding results per page select	
+		this.prfxBtnNextSpan =		'btnNextSpan_'; //span containing next page button
+		this.prfxBtnPrevSpan =		'btnPrevSpan_'; //span containing previous page button
+		this.prfxBtnLastSpan =		'btnLastSpan_'; //span containing last page button
+		this.prfxBtnFirstSpan =		'btnFirstSpan_'; //span containing first page button
+		this.prfxBtnNext =			'btnNext_'; //next button
+		this.prfxBtnPrev =			'btnPrev_'; //previous button
+		this.prfxBtnLast =			'btnLast_'; //last button
+		this.prfxBtnFirst =			'btnFirst_'; //first button
+		this.prfxPgSpan =			'pgspan_'; //span for tot nb pages
+		this.prfxPgBeforeSpan =		'pgbeforespan_'; //span preceding pages select (contains 'Page')
+		this.prfxPgAfterSpan =		'pgafterspan_'; //span following pages select (contains ' of ')
+		this.prfxCounter =			'counter_'; //rows counter div
+		this.prfxTotRows =			'totrows_span_'; //nb displayed rows label
+		this.prfxTotRowsTxt =		'totRowsTextSpan_'; //label preceding nb rows label
+		this.prfxResetSpan =		'resetspan_'; //span containing reset button
+		this.prfxLoader =			'load_'; //loader div
+		this.prfxStatus =			'status_'; //status bar div
+		this.prfxStatusSpan =		'statusSpan_'; //status bar label
+		this.prfxStatusTxt =		'statusText_';//text preceding status bar label
+		this.prfxCookieFltsValues =	'tf_flts_'; //filter values cookie
+		this.prfxCookiePageNb =		'tf_pgnb_'; //page nb cookie
+		this.prfxCookiePageLen = 	'tf_pglen_'; //page length cookie
+		this.prfxMainTblCont =		'gridCont_'; //div containing grid elements if grid_layout true
+		this.prfxTblCont =			'tblCont_'; //div containing table if grid_layout true
+		this.prfxHeadTblCont = 		'tblHeadCont_'; //div containing headers table if grid_layout true
+		this.prfxHeadTbl =			'tblHead_';	//headers' table if grid_layout true
+		this.prfxGridFltTd =		'_td_'; //id of td containing the filter if grid_layout true
+		this.prfxGridTh =			'tblHeadTh_'; //id of th containing column header if grid_layout true				
+
+		/*** cookies ***/
+		this.hasStoredValues =		false;
+		this.rememberGridValues =	f!=undefined && f.remember_grid_values ? true : false; //remembers filters values on page load
+		this.fltsValuesCookie =		this.prfxCookieFltsValues + this.id; //cookie storing filter values
+		this.rememberPageNb =		this.paging && f!=undefined && f.remember_page_number
+										? true : false; //remembers page nb on page load	
+		this.pgNbCookie =			this.prfxCookiePageNb + this.id; //cookie storing page nb
+		this.rememberPageLen =		this.paging && f!=undefined && f.remember_page_length
+										? true : false; //remembers page length on page load
+		this.pgLenCookie =			this.prfxCookiePageLen + this.id; //cookie storing page length
+		this.cookieDuration =		f!=undefined && f.set_cookie_duration 
+										? parseInt(f.set_cookie_duration) :100000; //cookie duration
+		
+		/*** extensions ***/
+		this.hasExtensions =		f!=undefined && f.extensions ? true : false; //imports external script
+		this.extensions =			(this.hasExtensions) ? f.extensions : null;
+
+		/***(deprecated: backward compatibility) ***/
+		this.hasBindScript =		f!=undefined && f.bind_script ? true : false; //imports external script
+		this.bindScript =			(this.hasBindScript) ? f.bind_script : null;
+		
+		/*** TF events ***/
+		var o = this;
+		this.Evt = {
+			name: {
+				filter: 'Filter',
+				populateselect: 'Populate',
+				populatechecklist: 'PopulateCheckList',
+				changepage: 'ChangePage',
+				clear: 'Clear',
+				changeresultsperpage: 'ChangeResults',
+				resetvalues: 'ResetValues',
+				resetpage: 'ResetPage',
+				resetpagelength: 'ResetPageLength',
+				sort: 'Sort',
+				loadextensions: 'LoadExtensions'			
+			},
+			_DetectKey: function(e)
+			/*====================================================
+				- common fn that detects return key for a given
+				element (onkeypress for inputs)
+			=====================================================*/
+			{
+				if(!o.enterKey) return;
+				var evt=(e)?e:(window.event)?window.event:null;
+				if(evt)
+				{
+					var key=(evt.charCode)?evt.charCode:
+						((evt.keyCode)?evt.keyCode:((evt.which)?evt.which:0));
+					if(key=='13')
+					{
+						o.Filter();
+					} else { 
+						o.isUserTyping = true;
+						window.clearInterval(o.onKeyUpTimer);
+						o.onKeyUpTimer = undefined; 
+					}
+				}//if evt
+			},
+			_OnKeyUp: function(e)
+			/*====================================================
+				- onkeyup event for text filters 
+				(onKeyUp property)
+			=====================================================*/
+			{
+				if(!o.onKeyUp) return;
+				var evt=(e)?e:(window.event)?window.event:null;
+				var key=(evt.charCode)?evt.charCode:
+						((evt.keyCode)?evt.keyCode:((evt.which)?evt.which:0));
+				o.isUserTyping = false;
+				
+				if( key!=13 && key!=9 && key!=27 && key!=38 && key!=40 )
+				{
+					function filter()
+					{
+						window.clearInterval(o.onKeyUpTimer);
+						o.onKeyUpTimer = undefined;
+						if( !o.isUserTyping )
+						{
+							o.Filter();
+							o.isUserTyping = null;			
+						}
+					}
+					if(o.onKeyUpTimer==undefined)
+						o.onKeyUpTimer = window.setInterval( filter, o.onKeyUpDelay );
+				} else { 
+					window.clearInterval(o.onKeyUpTimer); 
+					o.onKeyUpTimer = undefined; 
+				}
+			},
+			_OnKeyDown: function(e)
+			/*====================================================
+				- onkeydown event for input filters 
+				(onKeyUp property)
+			=====================================================*/
+			{
+				if(!o.onKeyUp) return;
+				o.isUserTyping = true;
+			},
+			_OnInpBlur: function(e)
+			/*====================================================
+				- onblur event for input filters (onKeyUp property)
+			=====================================================*/
+			{
+				if(!o.onKeyUp) return;
+				o.isUserTyping = false; 
+				window.clearInterval(o.onKeyUpTimer);
+			},
+			_OnInpFocus: function()
+			/*====================================================
+				- onfocus event for input filters
+			=====================================================*/
+			{
+				o.activeFilterId=this.getAttribute('id');
+				o.activeFlt = tf_Id(o.activeFilterId);
+			},
+			_OnSlcFocus: function()
+			/*====================================================
+				- onfocus event for select filters
+			=====================================================*/
+			{
+				o.activeFilterId = this.getAttribute('id');
+				o.activeFlt = tf_Id(o.activeFilterId);
+				if(o.fillSlcOnDemand && this.getAttribute('filled') == '0')
+				{// select is populated when element has focus
+					var ct = this.getAttribute('ct');
+					o.PopulateSelect(ct);
+					if(!tf_isIE) this.setAttribute('filled','1');
+				}
+			},
+			_OnSlcChange: function()
+			/*====================================================
+				- onchange event for select filters
+			=====================================================*/
+			{
+				if(o.onSlcChange) o.Filter();
+			},
+			_OnSlcBlur: function()
+			/*====================================================
+				- onblur event for select filters
+			=====================================================*/
+			{
+			},
+			_OnCheckListClick: function()
+			/*====================================================
+				- onclick event for checklist filters
+			=====================================================*/
+			{
+				if(o.fillSlcOnDemand && this.getAttribute('filled') == '0')
+				{
+					var ct = this.getAttribute('ct');
+					o.PopulateCheckList(ct);
+					o.checkListDiv[ct].onclick = null;
+					o.checkListDiv[ct].title = '';
+				}
+			},
+			_OnCheckListFocus: function()
+			/*====================================================
+				- onclick event for checklist filter container
+			=====================================================*/
+			{
+				o.activeFilterId = this.firstChild.getAttribute('id');
+				o.activeFlt = tf_Id(o.activeFilterId);
+			},
+			_OnBtnClick: function()
+			/*====================================================
+				- onclick event for validation button 
+				(btn property)
+			=====================================================*/
+			{
+				o.Filter();
+			},
+			_OnSlcPagesChange: function()
+			/*====================================================
+				- onchange event for paging select
+			=====================================================*/
+			{
+				if(o.Evt._Paging._OnSlcPagesChangeEvt)
+					o.Evt._Paging._OnSlcPagesChangeEvt();
+				o.ChangePage();
+				this.blur();
+				//ie only: blur is not enough...
+				if(this.parentNode && tf_isIE)
+					this.parentNode.focus();
+			},
+			_OnSlcPagesChangeEvt: null, //used by sort adapter
+			_OnSlcResultsChange: function()
+			/*====================================================
+				- onchange event for results per page select
+			=====================================================*/
+			{
+				o.ChangeResultsPerPage();
+				this.blur();
+				//ie only: blur is not enough...
+				if(this.parentNode && tf_isIE) 
+					this.parentNode.focus();
+			},
+			_Paging: {// paging buttons events
+				slcIndex: function(){ 
+					return (o.pageSelectorType==o.fltTypeSlc) 
+						? o.pagingSlc.options.selectedIndex 
+						: parseInt(o.pagingSlc.value)-1;
+				},
+				nbOpts: function(){ 
+					return (o.pageSelectorType==o.fltTypeSlc) 
+					? parseInt(o.pagingSlc.options.length)-1 
+					: (o.nbPages-1);
+				},
+				next: function(){
+					if(o.Evt._Paging.nextEvt) o.Evt._Paging.nextEvt();
+					var nextIndex = (o.Evt._Paging.slcIndex()<o.Evt._Paging.nbOpts()) 
+						? o.Evt._Paging.slcIndex()+1 : 0;
+					o.ChangePage(nextIndex);
+				},
+				nextEvt: null, //used by sort adapter
+				prev: function(){
+					if(o.Evt._Paging.prevEvt) o.Evt._Paging.prevEvt();
+					var prevIndex = o.Evt._Paging.slcIndex()>0 
+						? o.Evt._Paging.slcIndex()-1 : o.Evt._Paging.nbOpts();
+					o.ChangePage(prevIndex);
+				},
+				prevEvt: null, //used by sort adapter
+				last: function(){
+					if(o.Evt._Paging.lastEvt) o.Evt._Paging.lastEvt();
+					o.ChangePage(o.Evt._Paging.nbOpts());
+				},
+				lastEvt: null, //used by sort adapter
+				first: function(){
+					if(o.Evt._Paging.firstEvt)  o.Evt._Paging.firstEvt();
+					o.ChangePage(0);
+				},
+				firstEvt: null, //used by sort adapter
+				_detectKey: function(e)
+				{
+					var evt=(e)?e:(window.event)?window.event:null;
+					if(evt)
+					{
+						var key=(evt.charCode)?evt.charCode:
+							((evt.keyCode)?evt.keyCode:((evt.which)?evt.which:0));
+						if(key=='13'){ 
+							if(o.sorted){ o.Filter(); o.ChangePage(o.Evt._Paging.slcIndex()); }
+							else o.ChangePage();								
+							this.blur(); 
+						}
+					}//if evt
+				}
+			},
+			_EnableSlc: function()
+			/*====================================================
+				- onclick event slc parent node (enables filters)
+				IE only
+			=====================================================*/
+			{
+				this.firstChild.disabled = false;							
+				this.firstChild.focus();							
+				this.onclick = null;
+			},
+			_Clear: function()
+			/*====================================================
+				- clears filters
+			=====================================================*/
+			{
+				o.ClearFilters();
+			},
+			_EnableSort: function()
+			/*====================================================
+				- enables table sorting
+			=====================================================*/
+			{
+				if(tf_isImported(o.sortConfig.adapterSrc))
+					o.sortConfig.initialize.call(null,o);
+				else
+					o.IncludeFile(
+						o.sortConfig.name+'_adapter',
+						o.sortConfig.adapterSrc,
+						function(){ o.sortConfig.initialize.call(null,o); }
+					);
+			}
+		};
+		
+		/*** TF extensions ***/
+		this.Ext = {
+			list: {},
+			add: function(extName, extDesc, extPath, extCallBack)
+			{
+				var file = extPath.split('/')[extPath.split('/').length-1];
+				var re = new RegExp(file);
+				var path = extPath.replace(re,'');
+				o.Ext.list[extName] = { 
+					name: extName,
+					description: extDesc,
+					file: file,
+					path: path,
+					callback: extCallBack
+				};
+			}
+		};
+		
+    }//if tbl!=null		
+}
+
+TF.prototype = {
+	
+	AddGrid: function()
+	/*====================================================
+		- adds row with filtering grid bar and sets grid 
+		behaviours and layout
+	=====================================================*/
+	{
+		if(this.hasGrid) return;
+		this.refRow = this.startRow==undefined ? 2 : (this.startRow+1);
+		if(this.gridLayout) this.refRow = this.startRow==undefined ? 0 : this.startRow;
+		this.headersRow = (this.filtersRowIndex==0) ? 1 : 0;
+		try{ this.nbCells = this.GetCellsNb(this.refRow) }
+		catch(e){ this.nbCells = this.GetCellsNb(0) }
+
+		var f = this.fObj==undefined ? {} : this.fObj;
+		var n = (this.singleSearchFlt) ? 1 : this.nbCells, inpclass;
+		
+		if(this.gridLayout)
+		{
+			this.isExternalFlt = true;
+			this.SetGridLayout();
+			//Once grid generated 1st filterable row is 0 again
+			this.refRow = (tf_isIE || tf_isIE7) ? (this.refRow+1) : 0;
+		}
+		
+		if(this.loader) this.SetLoader();
+	
+		if(this.hasResultsPerPage)
+		{ 
+			this.resultsPerPage = f['results_per_page']!=undefined   
+				? f['results_per_page'] : this.resultsPerPage;
+			if(this.resultsPerPage.length<2)
+				this.hasResultsPerPage = false;
+			else
+				this.pagingLength = this.resultsPerPage[1][0];
+		}
+		
+		if(!this.fltGrid)
+		{//filters grid is not genetared
+			this.refRow = (this.refRow-1);
+			if(this.gridLayout) this.refRow = 0;
+			this.nbFilterableRows = this.GetRowsNb();
+			this.nbVisibleRows = this.nbFilterableRows;
+			this.nbRows = this.nbFilterableRows;
+		} else {
+			if(this.isFirstLoad)
+			{
+				if(!this.gridLayout){
+					var fltrow;
+					var thead = tf_Tag(this.tbl,'thead');
+					if( thead.length>0 )
+						fltrow = thead[0].insertRow(this.filtersRowIndex);
+					else
+						fltrow = this.tbl.insertRow(this.filtersRowIndex);
+					
+					if(this.fixedHeaders) this.SetFixedHeaders();
+					
+					fltrow.className = this.fltsRowCssClass;
+					//Disable for grid_layout
+					if( this.isExternalFlt && !this.gridLayout ) fltrow.style.display = 'none';
+				}
+				
+				this.nbFilterableRows = this.GetRowsNb();
+				this.nbVisibleRows = this.nbFilterableRows;
+				this.nbRows = this.tbl.rows.length;
+				
+				for(var i=0; i<n; i++)// this loop adds filters
+				{
+					var fltcell = tf_CreateElm(this.fltCellTag);
+					if(this.singleSearchFlt) fltcell.colSpan = this.nbCells;
+					if(!this.gridLayout) fltrow.appendChild( fltcell );
+					inpclass = (i==n-1 && this.displayBtn) ? this.fltSmallCssClass : this.fltCssClass;
+					
+					if( this['col'+i]==undefined )
+						this['col'+i] = (f['col_'+i]==undefined) 
+							? this.fltTypeInp : f['col_'+i].tf_LCase();
+							
+					if(this.singleSearchFlt)
+					{//only 1 input for single search
+						this['col'+i] = this.fltTypeInp;
+						inpclass = this.singleFltCssClass;
+					}
+	
+					if(this['col'+i]==this.fltTypeSlc || this['col'+i]==this.fltTypeMulti)
+					{//selects					
+						var slc = tf_CreateElm( this.fltTypeSlc,
+							['id',this.prfxFlt+i+'_'+this.id],
+							['ct',i],['filled','0'] );
+						if(this['col'+i]==this.fltTypeMulti)
+						{
+							slc.multiple = this.fltTypeMulti;
+							slc.title = this.multipleSlcTooltip;
+						}
+						slc.className = (this['col'+i].tf_LCase()==this.fltTypeSlc) 
+							? inpclass : this.fltMultiCssClass;// for ie<=6
+						
+						if( this.isExternalFlt && this.externalFltTgtIds && tf_Id(this.externalFltTgtIds[i]) )
+						{//filter is appended in desired element
+							tf_Id( this.externalFltTgtIds[i] ).appendChild(slc);
+							this.externalFltEls.push(slc);
+						} else {
+							fltcell.appendChild(slc);
+						}
+						
+						this.fltIds.push(this.prfxFlt+i+'_'+this.id);
+						
+						if(!this.fillSlcOnDemand) this.PopulateSelect(i);
+						
+						slc.onkeypress = this.Evt._DetectKey;
+						slc.onchange = this.Evt._OnSlcChange;
+						slc.onfocus = this.Evt._OnSlcFocus;
+						slc.onblur = this.Evt._OnSlcBlur;
+						
+						if(this.fillSlcOnDemand)
+						{//1st option is created here since PopulateSelect isn't invoked
+							var opt0 = tf_CreateOpt(this.displayAllText,'');
+							slc.appendChild( opt0 );						
+						}
+						
+						/* 	Code below for IE: it prevents select options to
+							slide out before select it-self is populated.
+							This is an unexpeted behavior for users since at
+							1st click options are empty. Work around: 
+							select is disabled and by clicking on element 
+							(parent td), users enable drop-down and select is
+							populated at same time.  */
+						if( this.fillSlcOnDemand && tf_isIE)
+						{
+							slc.disabled = true;
+							slc.title = this.activateSlcTooltip;
+							slc.parentNode.onclick = this.Evt._EnableSlc;
+							if( this['col'+i]==this.fltTypeMulti)
+								this.__deferMultipleSelection(slc,0);
+						}
+					}
+					
+					else if( this['col'+i]==this.fltTypeCheckList )
+					{// checklist
+						var divCont = tf_CreateElm('div',
+										['id',this.prfxCheckListDiv+i+'_'+this.id],
+										['ct',i],['filled','0'] );
+						divCont.className = this.checkListDivCssClass;
+						
+						if( this.isExternalFlt && this.externalFltTgtIds 
+							&& tf_Id(this.externalFltTgtIds[i]) )
+						{//filter is appended in desired element
+							tf_Id( this.externalFltTgtIds[i] ).appendChild(divCont);
+							this.externalFltEls.push(divCont);
+						} else {
+							fltcell.appendChild(divCont);
+						}
+						
+						this.checkListDiv[i] = divCont;
+						this.fltIds.push(this.prfxFlt+i+'_'+this.id);
+						if(!this.fillSlcOnDemand) this.PopulateCheckList(i);
+						
+						divCont.onclick = this.Evt._OnCheckListFocus;
+						
+						if(this.fillSlcOnDemand)
+						{
+							divCont.onclick = this.Evt._OnCheckListClick;
+							divCont.appendChild(tf_CreateText(this.activateCheckListTxt));
+						}
+					}
+					
+					else
+					{
+						var inptype;
+						(this['col'+i]==this.fltTypeInp) ? inptype='text' : inptype='hidden';//show/hide input	
+						var inp = tf_CreateElm( this.fltTypeInp,['id',this.prfxFlt+i+'_'+this.id],['type',inptype],['ct',i] );					
+						inp.className = inpclass;// for ie<=6
+						inp.onfocus = this.Evt._OnInpFocus;
+						
+						if( this.isExternalFlt && this.externalFltTgtIds && tf_Id(this.externalFltTgtIds[i]) )
+						{//filter is appended in desired element
+							tf_Id( this.externalFltTgtIds[i] ).appendChild(inp);
+							this.externalFltEls.push(inp);
+						} else {
+							fltcell.appendChild(inp);
+						}
+						
+						this.fltIds.push(this.prfxFlt+i+'_'+this.id);
+						
+						inp.onkeypress = this.Evt._DetectKey;
+						inp.onkeydown = this.Evt._OnKeyDown;
+						inp.onkeyup = this.Evt._OnKeyUp;
+						inp.onblur = this.Evt._OnInpBlur;
+						
+						if(this.rememberGridValues)
+						{
+							var flts = tf_ReadCookie(this.fltsValuesCookie); //reads the cookie
+							var reg = new RegExp(',','g');
+							var flts_values = flts.split(reg); //creates an array with filters' values
+							if (flts_values[i]!=' ')
+								this.SetFilterValue(i,flts_values[i],false);					
+						}
+					}
+					
+					if(i==n-1 && this.displayBtn)// this adds validation button
+					{
+						var btn = tf_CreateElm( this.fltTypeInp,['id',this.prfxValButton+i+'_'+this.id],
+												['type','button'], ['value',this.btnText] );
+						btn.className = this.btnCssClass;
+						
+						if( this.isExternalFlt && this.externalFltTgtIds && tf_Id(this.externalFltTgtIds[i]) ) 
+						//filter is appended in desired element
+							tf_Id( this.externalFltTgtIds[i] ).appendChild(btn);
+						else
+							fltcell.appendChild(btn);
+						
+						btn.onclick = this.Evt._OnBtnClick;				
+					}//if
+					
+				}// for i
+				
+			} else {
+				this.__resetGrid();			
+			}//if isFirstLoad
+		}//if this.fltGrid
+		
+		/* Filter behaviours */
+		if(this.rowsCounter) this.SetRowsCounter();
+		if(this.statusBar) this.SetStatusBar();
+		if(this.fixedHeaders && !this.isFirstLoad) this.SetFixedHeaders();
+		if(this.paging)	this.SetPaging();
+		if(this.hasResultsPerPage && this.paging) this.SetResultsPerPage();
+		if(this.btnReset) this.SetResetBtn();
+		
+		if(this.hasColWidth && !this.gridLayout) this.SetColWidths();
+		
+		if( this.alternateBgs && this.isStartBgAlternate )
+			this.SetAlternateRows(); //1st time only if no paging and rememberGridValues
+		
+		if(this.hasColOperation && this.fltGrid)
+		{
+			this.colOperation = f.col_operation;
+			this.SetColOperation();
+		}
+		
+		if(this.sort) this.SetSort();
+		
+		/* Deprecated Loads external script */
+		if(this.hasBindScript)
+		{
+			if(this.bindScript['src']!=undefined)
+			{
+				var scriptPath = this.bindScript['src'];
+				var scriptName = (this.bindScript['name']!=undefined)
+									? this.bindScript['name'] : '';
+				this.IncludeFile(scriptName,scriptPath,this.bindScript['target_fn']);
+			}
+		}//if bindScript
+		/* */
+		
+		this.isFirstLoad = false;
+		this.hasGrid = true;
+		
+		if( this.rememberGridValues ||
+			this.rememberPageLen ||
+			this.rememberPageNb )
+			this.ResetValues();
+		
+		this.ShowLoader('none');
+		
+		if(this.onFiltersLoaded)
+			this.onFiltersLoaded.call(null,this);
+
+		/* Loads extensions */
+		this.LoadExtensions();
+		/* */
+	},// AddGrid
+	
+	EvtManager: function( evt,s )
+	/*====================================================
+		- TF events manager
+		- Params: 
+			- event name (string)
+			- config object (optional literal object)
+	=====================================================*/
+	{
+		var o = this;
+		var slcIndex = (s!=undefined && s.slcIndex!=undefined) ? s.slcIndex : null;
+		var slcExternal = (s!=undefined && s.slcExternal!=undefined) ? s.slcExternal : false;
+		var slcId = (s!=undefined && s.slcId!=undefined) ? s.slcId : null;
+		var pgIndex = (s!=undefined && s.pgIndex!=undefined) ? s.pgIndex : null;
+		function efx(){
+			if(evt!=undefined)
+			switch( evt )
+			{
+				case o.Evt.name.filter:
+					(o.isModFilterFn) 
+						? o.modFilterFn.call(null,o)
+						: o._Filter();
+				break;
+				case o.Evt.name.populateselect:
+					(o.refreshFilters) 
+						? o._PopulateSelect(slcIndex,true) 
+						: o._PopulateSelect(slcIndex,false,slcExternal,slcId);
+				break;
+				case o.Evt.name.populatechecklist:
+					o._PopulateCheckList(slcIndex,slcExternal,slcId);
+				break;
+				case o.Evt.name.changepage:
+					o._ChangePage(pgIndex);
+				break;
+				case o.Evt.name.clear:
+					o._ClearFilters(); 
+					o._Filter();
+				break;
+				case o.Evt.name.changeresultsperpage:
+					o._ChangeResultsPerPage();
+				break;
+				case o.Evt.name.resetvalues:
+					o._ResetValues();					
+					o._Filter();
+				break;
+				case o.Evt.name.resetpage:
+					o._ResetPage(o.pgNbCookie);
+				break;
+				case o.Evt.name.resetpagelength:
+					o._ResetPageLength(o.pgLenCookie);
+				break;
+				case o.Evt.name.sort:
+					void(0);
+				break;
+				case o.Evt.name.loadextensions:
+					o._LoadExtensions();
+				break;
+				default: //to be used by extensions events when needed
+					o['_'+evt].call(null,o,s);
+				break;
+			}
+			o.StatusMsg('');
+			o.ShowLoader('none');
+		}
+		
+		if(this.loader || this.status || this.statusBar)
+		{
+			this.ShowLoader('');
+			this.StatusMsg(o['msg'+evt]);
+			window.setTimeout(efx,this.execDelay);
+		} else efx();
+	},
+	
+	LoadExtensions: function()
+	{
+		this.EvtManager(this.Evt.name.loadextensions);
+	},
+	
+	_LoadExtensions: function()
+	/*====================================================
+		- loads TF extensions
+	=====================================================*/
+	{
+		if(!this.hasExtensions) return;
+		if((typeof this.extensions.name).tf_LCase() == 'object' && 
+				(typeof this.extensions.src).tf_LCase() == 'object')
+		{
+			var ext = this.extensions;
+			for(var e=0; e<ext.name.length; e++)
+			{
+				var extPath = ext.src[e];
+				var extName = ext.name[e];
+				var extInit = (ext.initialize && ext.initialize[e]) ? ext.initialize[e] : null;
+				var extDesc = (ext.description && ext.description[e] ) ? ext.description[e] : null;
+				
+				//Registers extension 
+				this.Ext.add(extName, extDesc, extPath, extInit);
+				
+				if(tf_isImported(extPath) && extInit)
+				{
+					try{ extInit.call(null,this); }
+					catch(e){
+						var o = this;
+						function fn(){extInit.call(null,o);}
+						if(!tf_isIE) tf_addEvent(window,'load',fn); 
+						else{
+							function testReady(){
+								if (document.readyState == "complete") 
+								{
+									fn(); clearInterval(s);
+								}
+							}
+							var s = setInterval(testReady,10);
+						}		
+					}
+				}
+				else
+					this.IncludeFile(extName,extPath,extInit);
+			}
+		}
+	},
+	
+	RemoveGrid: function()
+	/*====================================================
+		- removes a filter grid
+	=====================================================*/
+	{
+		if( this.fltGrid && this.hasGrid )
+		{
+			var row = this.tbl.rows;
+			
+			this.RemovePaging();
+			this.RemoveStatusBar();
+			this.RemoveRowsCounter();
+			this.RemoveResetBtn();
+			this.RemoveResultsPerPage();
+			this.RemoveExternalFlts();
+			this.RemoveFixedHeaders();
+			this.RemoveTopDiv();
+			this.UnhighlightAll();
+			this.RemoveSort();
+			this.RemoveLoader();
+			
+			for(var j=this.refRow; j<this.nbRows; j++)
+			{//this loop shows all rows and removes validRow attribute			
+				row[j].style.display = '';
+				try
+				{ 
+					if( row[j].hasAttribute('validRow') ) 
+						row[j].removeAttribute('validRow');
+				} //ie<=6 doesn't support hasAttribute method
+				catch(e){
+					for( var x = 0; x < row[j].attributes.length; x++ ) 
+					{
+						if( row[j].attributes[x].nodeName.tf_LCase()=='validrow' ) 
+							row[j].removeAttribute('validRow');
+					}//for x
+				}//catch(e)
+				
+				//removes alterning colors
+				this.RemoveRowBg(j);
+				
+			}//for j
+	
+			if(this.fltGrid && !this.gridLayout)
+			{
+				this.fltGridEl = row[this.filtersRowIndex];			
+				this.tbl.deleteRow(this.filtersRowIndex);
+			}
+			this.activeFlt = null;
+			this.isStartBgAlternate = true;
+			this.hasGrid = false;
+			this.RemoveGridLayout();
+	
+		}//if this.fltGrid
+	},
+	
+	SetGridLayout: function()
+	/*====================================================
+		- generates a grid with fixed headers
+	=====================================================*/
+	{
+		if(!this.gridLayout) return;
+		if(!this.hasColWidth){// in case column widths are not set default width 100px
+			this.colWidth = [];
+			for(var k=0; k<this.nbCells; k++){
+				var colW, cell = this.tbl.rows[this.gridHeadRowIndex].cells[k];
+				if(cell.width!='') colW = cell.width;
+				else if(cell.style.width!='') colW = parseInt(cell.style.width);
+				else colW = this.gridDefaultColWidth;
+				this.colWidth[k] = colW;
+			}
+			this.hasColWidth = true;
+		}
+		this.SetColWidths(this.gridHeadRowIndex);
+		
+		var tblW;//initial table width
+		if(this.tbl.width!='') tblW = this.tbl.width;
+		else if(this.tbl.style.width!='') tblW = parseInt(this.tbl.style.width);
+		else tblW = this.tbl.clientWidth;
+		
+		//Main container: it will contain all the elements
+		this.tblMainCont = tf_CreateElm('div',['id', this.prfxMainTblCont + this.id]);
+		this.tblMainCont.className = this.gridMainContCssClass;
+		if(this.gridWidth) this.tblMainCont.style.width = this.gridWidth;
+		this.tbl.parentNode.insertBefore(this.tblMainCont, this.tbl);
+		
+		//Table container: div wrapping content table
+		this.tblCont = tf_CreateElm('div',['id', this.prfxTblCont + this.id]);
+		this.tblCont.className = this.gridContCssClass;
+		if(this.gridWidth) this.tblCont.style.width = this.gridWidth;
+		if(this.gridHeight) this.tblCont.style.height = this.gridHeight;
+		this.tbl.parentNode.insertBefore(this.tblCont, this.tbl);
+		var t = this.tbl.parentNode.removeChild(this.tbl);
+		this.tblCont.appendChild(t);
+		
+		//In case table width is expressed in %
+		if(this.tbl.style.width == '')
+			this.tbl.style.width = (this.__containsStr('%',tblW) 
+									? this.tbl.clientWidth : tblW) + 'px';
+
+		var d = this.tblCont.parentNode.removeChild(this.tblCont);
+		this.tblMainCont.appendChild(d);
+		
+		//Headers table container: div wrapping headers table
+		this.headTblCont = tf_CreateElm('div',['id', this.prfxHeadTblCont + this.id]);
+		this.headTblCont.className = this.gridHeadContCssClass;
+		if(this.gridWidth) this.headTblCont.style.width = this.gridWidth;		
+		
+		//Headers table
+		this.headTbl = tf_CreateElm('table',['id', this.prfxHeadTbl + this.id]);
+		var tH = tf_CreateElm('tHead'); //IE<7 needs it
+		
+		//1st row should be headers row, ids are added if not set
+		//Those ids are used by the sort feature
+		var hRow = this.tbl.rows[this.gridHeadRowIndex];
+		var sortTriggers = [];
+		for(var n=0; n<this.nbCells; n++){
+			var cell = hRow.cells[n];
+			var thId = cell.getAttribute('id');
+			if(!thId || thId==''){ 
+				thId = this.prfxGridTh+n+'_'+this.id 
+				cell.setAttribute('id', thId);
+			}
+			sortTriggers.push(thId);
+		}
+		
+		//Filters row is created
+		var filtersRow = tf_CreateElm('tr');
+		if(this.gridEnableFilters && this.fltGrid){
+			this.externalFltTgtIds = [];
+			for(var j=0; j<this.nbCells; j++)
+			{
+				var fltTdId = this.prfxFlt+j+ this.prfxGridFltTd +this.id;
+				var c = tf_CreateElm(this.fltCellTag, ['id', fltTdId]);
+				filtersRow.appendChild(c);
+				this.externalFltTgtIds[j] = fltTdId;
+			}
+		} 
+		//Headers row are moved from content table to headers table
+		for(var i=0; i<this.gridHeadRows.length; i++)
+		{
+			var headRow = this.tbl.rows[this.gridHeadRows[0]];			
+			tH.appendChild(headRow);
+		}
+		this.headTbl.appendChild(tH);
+		if(this.filtersRowIndex == 0) tH.insertBefore(filtersRow,hRow);
+		if(this.filtersRowIndex == 1) tH.appendChild(filtersRow);
+		
+		this.headTblCont.appendChild(this.headTbl);
+		this.tblCont.parentNode.insertBefore(this.headTblCont, this.tblCont);
+		
+		//THead needs to be removed in content table for sort feature
+		var thead = tf_Tag(this.tbl,'thead');
+		if( thead.length>0 ) this.tbl.removeChild(thead[0]);
+
+		//Headers table style
+		this.headTbl.style.width = this.tbl.style.width;
+		this.headTbl.style.tableLayout = 'fixed';
+		this.tbl.style.tableLayout = 'fixed';
+		this.headTbl.cellPadding = this.tbl.cellPadding;
+		this.headTbl.cellSpacing = this.tbl.cellSpacing;
+		
+		//Headers container width
+		this.headTblCont.style.width = this.tblCont.clientWidth+'px';
+		
+		//content table without headers needs col widths to be reset
+		this.SetColWidths();
+		
+		this.tbl.style.width = '';		
+		if(tf_isIE || tf_isIE7)	this.headTbl.style.width = '';
+		
+		//scroll synchronisation
+		var o = this; //TF object
+		this.tblCont.onscroll = function(){
+			o.headTblCont.scrollLeft = this.scrollLeft;
+			var _o = this; //this = scroll element
+			//New pointerX calc taking into account scrollLeft
+			if(!o.isPointerXOverwritten){
+				try{					
+					TF.Evt.pointerX = function(e)
+					{
+						e = e || window.event;
+						var scrollLeft = tf_StandardBody().scrollLeft + _o.scrollLeft;
+						return (e.pageX + _o.scrollLeft) || (e.clientX + scrollLeft);
+					}					
+					o.isPointerXOverwritten = true;
+				} catch(ee) {
+					o.isPointerXOverwritten = false;
+				}
+			}
+		}
+
+		/*** Default behaviours activation ***/
+		var f = this.fObj==undefined ? {} : this.fObj;
+		
+		//Sort is enabled if not specified in config object
+		if(f.sort != false){
+			this.sort = true;
+			this.sortConfig.asyncSort = true;
+			this.sortConfig.triggerIds = sortTriggers;
+		}
+		
+		if(this.gridEnableColResizer){
+			if(!this.hasExtensions){
+				this.extensions = {
+					name:['ColumnsResizer'],
+					src:['TFExt_ColsResizer/TFExt_ColsResizer.js'], 
+					description:['Columns Resizing'],
+					initialize:[function(o){o.SetColsResizer('ColumnsResizer');}]
+				}
+				this.hasExtensions = true;
+			} else {
+				if(!this.__containsStr('colsresizer',this.extensions.src.toString().tf_LCase())){
+					this.extensions.name.push('ColumnsResizer');
+					this.extensions.src.push('TFExt_ColsResizer/TFExt_ColsResizer.js');
+					this.extensions.description.push('Columns Resizing');
+					this.extensions.initialize.push(function(o){o.SetColsResizer('ColumnsResizer');});
+				}  
+			}
+		}
+		
+		//Default columns resizer properties for grid layout
+		f.col_resizer_cols_headers_table = this.headTbl.getAttribute('id');
+		f.col_resizer_cols_headers_index = this.gridHeadRowIndex;
+		f.col_resizer_width_adjustment = 0;
+		f.col_enable_text_ellipsis = false;
+		
+		//Cols generation for all browsers excepted IE<=7
+		o.tblHasColTag = (tf_Tag(o.tbl,'col').length > 0) ? true : false;
+		if(!tf_isIE && !tf_isIE7){
+			//Col elements are enough to keep column widths after sorting and filtering
+			function createColTags(o)
+			{
+				if(!o) return;
+				for(var k=(o.nbCells-1); k>=0; k--)
+				{
+					var col = tf_CreateElm( 'col', ['id', o.id+'_col_'+k]);
+					o.tbl.firstChild.parentNode.insertBefore(col,o.tbl.firstChild);
+					col.style.width = o.colWidth[k];
+					o.gridColElms[k] = col;
+				}
+				o.tblHasColTag = true;
+			}
+			if(!o.tblHasColTag) createColTags(o);
+			else{
+				var cols = tf_Tag(o.tbl,'col');
+				for(var i=0; i<o.nbCells; i++){
+					cols[i].setAttribute('id', o.id+'_col_'+i);
+					cols[i].style.width = o.colWidth[i];
+					o.gridColElms.push(cols[i]);
+				}
+			}
+		}
+		
+		//IE <= 7 needs an additional row for widths as col element width is not enough...
+		if(tf_isIE || tf_isIE7){
+			var tbody = tf_Tag(o.tbl,'tbody'), r;
+			if( tbody.length>0 ) r = tbody[0].insertRow(0);
+			else r = o.tbl.insertRow(0);
+			r.style.height = '0px';
+			for(var i=0; i<o.nbCells; i++){
+				var col = tf_CreateElm('td', ['id', o.id+'_col_'+i]);
+				col.style.width = o.colWidth[i];
+				o.tbl.rows[1].cells[i].style.width = '';
+				r.appendChild(col);
+				o.gridColElms.push(col);
+			}
+			this.hasGridWidthsRow = true;
+			//Data table row with widths expressed
+			o.leadColWidthsRow = o.tbl.rows[0];
+			o.leadColWidthsRow.setAttribute('validRow','false');
+			
+			var beforeSortFn = tf_isFn(f.on_before_sort) ? f.on_before_sort : null;
+			f.on_before_sort = function(o,colIndex){
+				o.leadColWidthsRow.setAttribute('validRow','false');
+				if(beforeSortFn!=null) beforeSortFn.call(null,o,colIndex);
+			} 
+			
+			var afterSortFn = tf_isFn(f.on_after_sort) ? f.on_after_sort : null;
+			f.on_after_sort = function(o,colIndex){
+				if(o.leadColWidthsRow.rowIndex != 0){
+					var r = o.leadColWidthsRow;
+					if( tbody.length>0 )
+						tbody[0].moveRow(o.leadColWidthsRow.rowIndex, 0);
+					else o.tbl.moveRow(o.leadColWidthsRow.rowIndex, 0);
+				}
+				if(afterSortFn!=null) afterSortFn.call(null,o,colIndex);
+			}	
+		}
+		
+		var afterColResizedFn = tf_isFn(f.on_after_col_resized) ? f.on_after_col_resized : null;
+		f.on_after_col_resized = function(o,colIndex){
+			if(colIndex==undefined) return;
+			var w = o.crWColsRow.cells[colIndex].style.width;
+			var col = o.gridColElms[colIndex];
+			col.style.width = w;
+			
+			var thCW = o.crWColsRow.cells[colIndex].clientWidth;
+			var tdCW = o.crWRowDataTbl.cells[colIndex].clientWidth;
+			
+			if(tf_isIE || tf_isIE7)
+				o.tbl.style.width = o.headTbl.clientWidth+'px';
+			
+			if(thCW != tdCW && !tf_isIE && !tf_isIE7)
+				o.headTbl.style.width = o.tbl.clientWidth+'px'; 
+			
+			if(afterColResizedFn!=null) afterColResizedFn.call(null,o,colIndex);			
+		}	
+		
+		if(this.tbl.clientWidth != this.headTbl.clientWidth)
+			this.tbl.style.width = this.headTbl.clientWidth+'px';
+	},
+	
+	RemoveGridLayout: function()
+	{
+		if(!this.gridLayout) return;		
+		var t = this.tbl.parentNode.removeChild(this.tbl);
+		this.tblMainCont.parentNode.insertBefore(t, this.tblMainCont);
+		this.tblMainCont.parentNode.removeChild( this.tblMainCont );
+		this.tblMainCont = null;
+		this.headTblCont = null;
+		this.headTbl = null;
+		this.tblCont = null;
+		//TO DO: alternative solution for Firefox
+		this.tbl.outerHTML = this.sourceTblHtml;
+		this.tbl = tf_Id(this.id);
+		this.isFirstLoad = true;
+		this.activeFlt = null;
+		this.isStartBgAlternate = true;
+		this.hasGrid = false;
+	},
+	
+	SetTopDiv: function()
+	/*====================================================
+		- Generates div above table where paging,
+		reset button, rows counter label etc. are placed
+	=====================================================*/
+	{
+		if( this.infDiv!=null ) return;
+	
+		/*** container div ***/
+		var infdiv = tf_CreateElm( 'div',['id',this.prfxInfDiv+this.id] );
+		infdiv.className = this.infDivCssClass;// setAttribute method doesn't seem to work on ie<=6
+		if(this.fixedHeaders && this.contDiv)
+			this.contDiv.parentNode.insertBefore(infdiv, this.contDiv);
+		else if(this.gridLayout){
+			this.tblMainCont.appendChild(infdiv);
+			infdiv.className = this.gridInfDivCssClass;
+		}
+		else
+			this.tbl.parentNode.insertBefore(infdiv, this.tbl);
+		this.infDiv = tf_Id( this.prfxInfDiv+this.id );
+		
+		/*** left div containing rows # displayer ***/
+		var ldiv = tf_CreateElm( 'div',['id',this.prfxLDiv+this.id] );
+		ldiv.className = this.lDivCssClass;/*'ldiv'*/;
+		infdiv.appendChild(ldiv);
+		this.lDiv = tf_Id( this.prfxLDiv+this.id );		
+		
+		/*** 	right div containing reset button 
+				+ nb results per page select 	***/	
+		var rdiv = tf_CreateElm( 'div',['id',this.prfxRDiv+this.id] );
+		rdiv.className = this.rDivCssClass/*'rdiv'*/;
+		infdiv.appendChild(rdiv);
+		this.rDiv = tf_Id( this.prfxRDiv+this.id );
+		
+		/*** mid div containing paging elements ***/
+		var mdiv = tf_CreateElm( 'div',['id',this.prfxMDiv+this.id] );
+		mdiv.className = this.mDivCssClass/*'mdiv'*/;						
+		infdiv.appendChild(mdiv);
+		this.mDiv = tf_Id( this.prfxMDiv+this.id );
+	},
+	
+	RemoveTopDiv: function()
+	/*====================================================
+		- Removes div above table where paging,
+		reset button, rows counter label etc. are placed
+	=====================================================*/
+	{
+		if( this.infDiv==null ) return;
+		this.infDiv.parentNode.removeChild( this.infDiv );
+		this.infDiv = null;
+	},
+	
+	SetFixedHeaders: function()
+	/*====================================================
+		- CSS solution making headers fixed
+	=====================================================*/
+	{
+		if((!this.hasGrid && !this.isFirstLoad) || !this.fixedHeaders) return;
+		if(this.contDiv) return;	
+		var thead = tf_Tag(this.tbl,'thead');
+		if( thead.length==0 ) return;
+		var tbody = tf_Tag(this.tbl,'tbody');	
+		if( tbody[0].clientHeight!=0 ) 
+		{//firefox returns tbody height
+			//previous values
+			this.prevTBodyH = tbody[0].clientHeight;
+			this.prevTBodyOverflow = tbody[0].style.overflow;
+			this.prevTBodyOverflowX = tbody[0].style.overflowX;
+			
+			tbody[0].style.height = this.tBodyH+'px';
+			tbody[0].style.overflow = 'auto';
+			tbody[0].style.overflowX = 'hidden';
+		} else { //IE returns 0
+			// cont div is added to emulate fixed headers behaviour
+			var contDiv = tf_CreateElm( 'div',['id',this.prfxContentDiv+this.id] );
+			contDiv.className = this.contDivCssClass;
+			this.tbl.parentNode.insertBefore(contDiv, this.tbl);
+			contDiv.appendChild(this.tbl);
+			this.contDiv = tf_Id(this.prfxContentDiv+this.id);
+			//prevents headers moving during window scroll (IE)
+			this.contDiv.style.position = 'relative';
+			
+			var theadH = 0;
+			var theadTr = tf_Tag(thead[0],'tr');	
+			for(var i=0; i<theadTr.length; i++)
+			{//css below emulates fixed headers on IE<=6
+				theadTr[i].style.cssText += 'position:relative; ' +
+											'top:expression(offsetParent.scrollTop);';
+				theadH += parseInt(theadTr[i].clientHeight);
+			}
+			
+			this.contDiv.style.height = (this.tBodyH+theadH)+'px';
+			
+			var tfoot = tf_Tag(this.tbl,'tfoot');
+			if( tfoot.length==0 ) return;
+			
+			var tfootTr = tf_Tag(tfoot[0],'tr');
+				
+			for(var j=0; j<tfootTr.length; j++)//css below emulates fixed footer on IE<=6
+				tfootTr[j].style.cssText += 'position:relative; overflow-x: hidden; ' +
+											'top: expression(parentNode.parentNode.offsetHeight >= ' +
+											'offsetParent.offsetHeight ? 0 - parentNode.parentNode.offsetHeight + '+ 
+											'offsetParent.offsetHeight + offsetParent.scrollTop : 0);';		
+		}	
+	},
+	
+	RemoveFixedHeaders: function()
+	/*====================================================
+		- Removes fixed headers
+	=====================================================*/
+	{
+		if(!this.hasGrid || !this.fixedHeaders ) return;
+		if( this.contDiv )//IE additional div
+		{
+			this.contDiv.parentNode.insertBefore(this.tbl, this.contDiv);
+			this.contDiv.parentNode.removeChild( this.contDiv );
+			this.contDiv = null;
+			var thead = tf_Tag(this.tbl,'thead');
+			if( thead.length==0 ) return;
+			var theadTr = tf_Tag(thead[0],'tr');
+			if( theadTr.length==0 ) return;
+			for(var i=0; i<theadTr.length; i++)
+				theadTr[i].style.cssText = '';
+			var tfoot = tf_Tag(this.tbl,'tfoot');
+			if( tfoot.length==0 ) return;		
+			var tfootTr = tf_Tag(tfoot[0],'tr');	
+			for(var j=0; j<tfootTr.length; j++)
+			{
+				tfootTr[j].style.position = 'relative';
+				tfootTr[j].style.top = '';
+				tfootTr[j].style.overeflowX = '';
+			}
+		} else {
+			var tbody = tf_Tag(this.tbl,'tbody');
+			if( tbody.length==0 ) return;
+			tbody[0].style.height = this.prevTBodyH+'px';
+			tbody[0].style.overflow = this.prevTBodyOverflow;
+			tbody[0].style.overflowX = this.prevTBodyOverflowX;
+		}
+	},
+	
+	SetPaging: function()
+	/*====================================================
+		- Generates paging elements:
+			- pages drop-down list
+			- previous, next, first, last buttons
+	=====================================================*/
+	{
+		if(!this.hasGrid && !this.isFirstLoad) return;
+		if(!this.paging || (!this.isPagingRemoved && !this.isFirstLoad)) return;
+		var start_row = this.refRow;
+		var nrows = this.nbRows;
+		this.nbPages = Math.ceil( (nrows-start_row)/this.pagingLength );//calculates page nb
+	
+		// Paging drop-down list selector
+		if(this.pageSelectorType == this.fltTypeSlc)
+		{
+			var slcPages = tf_CreateElm( this.fltTypeSlc, ['id',this.prfxSlcPages+this.id] );
+			slcPages.className = this.pgSlcCssClass;
+			slcPages.onchange = this.Evt._OnSlcPagesChange;
+		}
+		// Paging input selector
+		if(this.pageSelectorType == this.fltTypeInp)
+		{
+			var slcPages = tf_CreateElm( 
+				this.fltTypeInp, 
+				['id',this.prfxSlcPages+this.id],
+				['value',this.currentPageNb]
+			);
+			slcPages.className = this.pgInpCssClass;
+			slcPages.onkeypress = this.Evt._Paging._detectKey;
+		}
+		
+		var btnNextSpan, btnPrevSpan, btnLastSpan, btnFirstSpan;// btns containers
+		btnNextSpan = tf_CreateElm('span',['id',this.prfxBtnNextSpan+this.id]);
+		btnPrevSpan = tf_CreateElm('span',['id',this.prfxBtnPrevSpan+this.id]);
+		btnLastSpan = tf_CreateElm('span',['id',this.prfxBtnLastSpan+this.id]);
+		btnFirstSpan = tf_CreateElm('span',['id',this.prfxBtnFirstSpan+this.id]);
+		
+		if(this.hasPagingBtns)
+		{
+			if(this.btnNextPageHtml==null)
+			{// Next button
+				var btn_next = tf_CreateElm( this.fltTypeInp,['id',this.prfxBtnNext+this.id],
+					['type','button'],['value',this.btnNextPageText],['title','Next'] );
+				btn_next.className = this.btnPageCssClass;
+				btn_next.onclick = this.Evt._Paging.next;
+				btnNextSpan.appendChild(btn_next);
+			} else {
+				btnNextSpan.innerHTML = this.btnNextPageHtml;
+				btnNextSpan.onclick = this.Evt._Paging.next;
+			}
+			
+			if(this.btnPrevPageHtml==null)
+			{// Previous button
+				var btn_prev = tf_CreateElm( this.fltTypeInp,['id',this.prfxBtnPrev+this.id],
+					['type','button'],['value',this.btnPrevPageText],['title','Previous'] );
+				btn_prev.className = this.btnPageCssClass;
+				btn_prev.onclick = this.Evt._Paging.prev;
+				btnPrevSpan.appendChild(btn_prev);
+			} else { 
+				btnPrevSpan.innerHTML = this.btnPrevPageHtml;
+				btnPrevSpan.onclick = this.Evt._Paging.prev;
+			}
+			
+			if(this.btnLastPageHtml==null)
+			{// Last button
+				var btn_last = tf_CreateElm( this.fltTypeInp,['id',this.prfxBtnLast+this.id],
+					['type','button'],['value',this.btnLastPageText],['title','Last'] );
+				btn_last.className = this.btnPageCssClass;
+				btn_last.onclick = this.Evt._Paging.last;
+				btnLastSpan.appendChild(btn_last);
+			} else { 
+				btnLastSpan.innerHTML = this.btnLastPageHtml;
+				btnLastSpan.onclick = this.Evt._Paging.last;
+			}
+			
+			if(this.btnFirstPageHtml==null)
+			{// First button
+				var btn_first = tf_CreateElm( this.fltTypeInp,['id',this.prfxBtnFirst+this.id],
+					['type','button'],['value',this.btnFirstPageText],['title','First'] );
+				btn_first.className = this.btnPageCssClass;
+				btn_first.onclick = this.Evt._Paging.first;
+				btnFirstSpan.appendChild(btn_first);
+			} else { 
+				btnFirstSpan.innerHTML = this.btnFirstPageHtml;
+				btnFirstSpan.onclick = this.Evt._Paging.first;
+			}			
+		}//if this.hasPagingBtns
+		
+		// paging elements (buttons+drop-down list) are added to defined element
+		if(this.pagingTgtId==null) this.SetTopDiv();
+		var targetEl = ( this.pagingTgtId==null ) ? this.mDiv : tf_Id( this.pagingTgtId );
+		
+		/***	if paging previously removed this prevents IE memory leak with removeChild 
+				used in RemovePaging method. For more info refer to
+				http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2840253&SiteID=1	***/
+		if ( targetEl.innerHTML!='' ) targetEl.innerHTML = '';
+		/*** ***/
+		
+		targetEl.appendChild(btnPrevSpan);
+		targetEl.appendChild(btnFirstSpan);
+		
+		var pgBeforeSpan = tf_CreateElm( 'span',['id',this.prfxPgBeforeSpan+this.id] );
+		pgBeforeSpan.appendChild( tf_CreateText(' Page ') );
+		pgBeforeSpan.className = this.nbPgSpanCssClass;
+		targetEl.appendChild(pgBeforeSpan);
+		targetEl.appendChild(slcPages);
+		var pgAfterSpan = tf_CreateElm( 'span',['id',this.prfxPgAfterSpan+this.id] );
+		pgAfterSpan.appendChild( tf_CreateText(' of ') );
+		pgAfterSpan.className = this.nbPgSpanCssClass;
+		targetEl.appendChild(pgAfterSpan)
+		var pgspan = tf_CreateElm( 'span',['id',this.prfxPgSpan+this.id] );
+		pgspan.className = this.nbPgSpanCssClass;
+		pgspan.appendChild( tf_CreateText(' '+this.nbPages+' ') );
+		targetEl.appendChild(pgspan);
+		targetEl.appendChild(btnLastSpan);
+		targetEl.appendChild(btnNextSpan);
+	
+		this.pagingSlc = tf_Id(this.prfxSlcPages+this.id); //to be easily re-used
+		
+		// if this.rememberGridValues==true this.SetPagingInfo() is called
+		// in ResetGridValues() method
+		if( !this.rememberGridValues || this.isPagingRemoved )
+			this.SetPagingInfo();
+		if( !this.fltGrid )
+		{
+			this.ValidateAllRows();
+			this.SetPagingInfo(this.validRowsIndex);
+		}
+			
+		this.pagingBtnEvents = this.Evt._Paging;
+		this.isPagingRemoved = false;
+	},
+	
+	RemovePaging: function()
+	/*====================================================
+		- Removes paging elements
+	=====================================================*/
+	{
+		if(!this.hasGrid) return;
+		if( this.pagingSlc==null ) return;
+		var btnNextSpan, btnPrevSpan, btnLastSpan, btnFirstSpan;// btns containers
+		var pgBeforeSpan, pgAfterSpan, pgspan;
+		btnNextSpan = tf_Id(this.prfxBtnNextSpan+this.id);
+		btnPrevSpan = tf_Id(this.prfxBtnPrevSpan+this.id);
+		btnLastSpan = tf_Id(this.prfxBtnLastSpan+this.id);
+		btnFirstSpan = tf_Id(this.prfxBtnFirstSpan+this.id);
+		pgBeforeSpan = tf_Id(this.prfxPgBeforeSpan+this.id);//span containing 'Page' text
+		pgAfterSpan = tf_Id(this.prfxPgAfterSpan+this.id);//span containing 'of' text
+		pgspan = tf_Id(this.prfxPgSpan+this.id);//span containing nb of pages
+		
+		this.pagingSlc.parentNode.removeChild(this.pagingSlc);
+		
+		if( btnNextSpan!=null )
+			btnNextSpan.parentNode.removeChild( btnNextSpan );
+	
+		if( btnPrevSpan!=null )
+			btnPrevSpan.parentNode.removeChild( btnPrevSpan );
+	
+		if( btnLastSpan!=null )
+			btnLastSpan.parentNode.removeChild( btnLastSpan );
+	
+		if( btnFirstSpan!=null )
+			btnFirstSpan.parentNode.removeChild( btnFirstSpan );
+	
+		if( pgBeforeSpan!=null )
+			pgBeforeSpan.parentNode.removeChild( pgBeforeSpan );
+	
+		if( pgAfterSpan!=null )
+			pgAfterSpan.parentNode.removeChild( pgAfterSpan );
+	
+		if( pgspan!=null )
+			pgspan.parentNode.removeChild( pgspan );
+		
+		this.pagingBtnEvents = null;	
+		this.pagingSlc = null;
+		this.isPagingRemoved = true;
+	},
+	
+	SetRowsCounter: function()
+	/*====================================================
+		- Generates rows counter label
+	=====================================================*/
+	{
+		if(!this.hasGrid && !this.isFirstLoad) return;
+		if( this.rowsCounterSpan!=null ) return;
+		var countDiv = tf_CreateElm( 'div',['id',this.prfxCounter+this.id] ); //rows counter container
+		countDiv.className = this.totRowsCssClass;
+		var countSpan = tf_CreateElm( 'span',['id',this.prfxTotRows+this.id] ); //rows counter label
+		var countText = tf_CreateElm( 'span',['id',this.prfxTotRowsTxt+this.id] );
+		countText.appendChild( tf_CreateText(this.rowsCounterText) );
+		
+		// counter is added to defined element
+		if(this.rowsCounterTgtId==null) this.SetTopDiv();
+		var targetEl = ( this.rowsCounterTgtId==null ) ? this.lDiv : tf_Id( this.rowsCounterTgtId );
+		
+		//IE only: clears all for sure
+		if(this.rowsCounterDiv && tf_isIE)
+			this.rowsCounterDiv.outerHTML = '';
+		
+		if( this.rowsCounterTgtId==null )
+		{//default container: 'lDiv'
+			countDiv.appendChild(countText);
+			countDiv.appendChild(countSpan);
+			targetEl.appendChild(countDiv);
+		}
+		else
+		{// custom container, no need to append statusDiv
+			targetEl.appendChild(countText);
+			targetEl.appendChild(countSpan);
+		}
+		this.rowsCounterDiv = tf_Id( this.prfxCounter+this.id );
+		this.rowsCounterSpan = tf_Id( this.prfxTotRows+this.id );
+		
+		this.RefreshNbRows();	
+	},
+	
+	RemoveRowsCounter: function()
+	/*====================================================
+		- Removes rows counter label
+	=====================================================*/
+	{
+		if(!this.hasGrid) return;
+		if( this.rowsCounterSpan==null ) return;
+		
+		if(this.rowsCounterTgtId==null && this.rowsCounterDiv)
+		{
+			//IE only: clears all for sure
+			if(tf_isIE) this.rowsCounterDiv.outerHTML = '';
+			else
+				this.rowsCounterDiv.parentNode.removeChild( 
+					this.rowsCounterDiv
+				);
+		} else {
+			tf_Id( this.rowsCounterTgtId ).innerHTML = '';
+		}
+		this.rowsCounterSpan = null;
+		this.rowsCounterDiv = null;
+	},
+	
+	SetStatusBar: function()
+	/*====================================================
+		- Generates status bar label
+	=====================================================*/
+	{
+		if(!this.hasGrid && !this.isFirstLoad) return;
+		var statusDiv = tf_CreateElm( 'div',['id',this.prfxStatus+this.id] ); //status bar container
+		statusDiv.className = this.statusBarCssClass;
+		var statusSpan = tf_CreateElm( 'span',['id',this.prfxStatusSpan+this.id] ); //status bar label
+		var statusSpanText = tf_CreateElm( 'span',['id',this.prfxStatusTxt+this.id] );//preceding text
+		statusSpanText.appendChild( tf_CreateText(this.statusBarText) );
+	
+		// target element container
+		if(this.statusBarTgtId==null) this.SetTopDiv();
+		var targetEl = ( this.statusBarTgtId==null ) ? this.lDiv : tf_Id( this.statusBarTgtId );
+		
+		if(this.statusBarDiv && tf_isIE)
+			this.statusBarDiv.outerHTML = '';
+		
+		if( this.statusBarTgtId==null )
+		{//default container: 'lDiv'
+			statusDiv.appendChild(statusSpanText);
+			statusDiv.appendChild(statusSpan);
+			targetEl.appendChild(statusDiv);
+		}
+		else
+		{// custom container, no need to append statusDiv
+			targetEl.appendChild(statusSpanText);
+			targetEl.appendChild(statusSpan);
+		}
+
+		this.statusBarDiv = tf_Id( this.prfxStatus+this.id );
+		this.statusBarSpan = tf_Id( this.prfxStatusSpan+this.id );
+		this.statusBarSpanText = tf_Id( this.prfxStatusTxt+this.id );
+	},
+	
+	RemoveStatusBar: function()
+	/*====================================================
+		- Removes status bar div
+	=====================================================*/
+	{
+		if(!this.hasGrid) return;
+		if(this.statusBarDiv)
+		{
+			this.statusBarDiv.innerHTML = '';
+			this.statusBarDiv.parentNode.removeChild( 
+				this.statusBarDiv
+			);
+			this.statusBarSpan = null;
+			this.statusBarSpanText = null;
+			this.statusBarDiv = null;
+		}
+	},
+	
+	SetResultsPerPage: function()
+	/*====================================================
+		- Generates results per page select + label
+	=====================================================*/
+	{
+		if(!this.hasGrid && !this.isFirstLoad) return;
+		if( this.resultsPerPageSlc!=null || this.resultsPerPage==null ) return;
+		var slcR = tf_CreateElm( this.fltTypeSlc,['id',this.prfxSlcResults+this.id] );
+		slcR.className = this.resultsSlcCssClass;
+		var slcRText = this.resultsPerPage[0], slcROpts = this.resultsPerPage[1];
+		var slcRSpan = tf_CreateElm( 'span',['id',this.prfxSlcResultsTxt+this.id] );
+		slcRSpan.className = this.resultsSpanCssClass;
+		
+		// results per page select is added to defined element
+		if(this.resultsPerPageTgtId==null) this.SetTopDiv();
+		var targetEl = ( this.resultsPerPageTgtId==null ) ? this.rDiv : tf_Id( this.resultsPerPageTgtId );
+		slcRSpan.appendChild(tf_CreateText(slcRText));
+		targetEl.appendChild(slcRSpan);
+		targetEl.appendChild(slcR);
+		
+		this.resultsPerPageSlc = tf_Id(this.prfxSlcResults+this.id);
+		
+		for(var r=0; r<slcROpts.length; r++)
+		{
+			var currOpt = new Option(slcROpts[r],slcROpts[r],false,false);
+			this.resultsPerPageSlc.options[r] = currOpt;
+		}
+		slcR.onchange = this.Evt._OnSlcResultsChange;
+	},
+	
+	RemoveResultsPerPage: function()
+	/*====================================================
+		- Removes results per page select + label
+	=====================================================*/
+	{
+		if(!this.hasGrid) return;
+		if( this.resultsPerPageSlc==null || this.resultsPerPage==null ) return;
+		var slcR, slcRSpan;
+		slcR = this.resultsPerPageSlc;
+		slcRSpan = tf_Id( this.prfxSlcResultsTxt+this.id );
+		if( slcR!=null )
+			slcR.parentNode.removeChild( slcR );
+		if( slcRSpan!=null )
+			slcRSpan.parentNode.removeChild( slcRSpan );
+		this.resultsPerPageSlc = null;
+	},
+	
+	SetResetBtn: function()
+	/*====================================================
+		- Generates reset button
+	=====================================================*/
+	{
+		if(!this.hasGrid && !this.isFirstLoad) return;
+		if( this.btnResetEl!=null ) return;
+		var resetspan = tf_CreateElm('span',['id',this.prfxResetSpan+this.id]);
+		
+		// reset button is added to defined element
+		if(this.btnResetTgtId==null) this.SetTopDiv();
+		var targetEl = ( this.btnResetTgtId==null ) ? this.rDiv : tf_Id( this.btnResetTgtId );
+		targetEl.appendChild(resetspan);
+			
+		if(this.btnResetHtml==null)
+		{	
+			var fltreset = tf_CreateElm( 'a', ['href','javascript:void(0);'] );
+			fltreset.className = this.btnResetCssClass;
+			fltreset.appendChild(tf_CreateText(this.btnResetText));
+			resetspan.appendChild(fltreset);
+			fltreset.onclick = this.Evt._Clear;
+		} else {
+			resetspan.innerHTML = this.btnResetHtml;
+			var resetEl = resetspan.firstChild;
+			resetEl.onclick = this.Evt._Clear;
+		}
+		this.btnResetEl = tf_Id(this.prfxResetSpan+this.id).firstChild;	
+	},
+	
+	RemoveResetBtn: function()
+	/*====================================================
+		- Removes reset button
+	=====================================================*/
+	{
+		if(!this.hasGrid) return;
+		if( this.btnResetEl==null ) return;
+		var resetspan = tf_Id(this.prfxResetSpan+this.id);
+		if( resetspan!=null )
+			resetspan.parentNode.removeChild( resetspan );
+		this.btnResetEl = null;	
+	},
+	
+	RemoveExternalFlts: function()
+	/*====================================================
+		- removes external filters
+	=====================================================*/
+	{
+		if( !this.isExternalFlt && !this.externalFltTgtIds ) return;
+		for(var ct=0; ct<this.externalFltTgtIds.length; ct++ )
+			if( tf_Id(this.externalFltTgtIds[ct]) )
+				tf_Id(this.externalFltTgtIds[ct]).innerHTML = '';
+	},
+	
+	SetSort: function()
+	/*====================================================
+		- Sets sorting feature by loading 
+		WebFX Sortable Table 1.12 by Erik Arvidsson
+		and TF adapter by Max Guglielmi
+	=====================================================*/
+	{
+		if(tf_isImported(this.sortConfig.src))
+			this.Evt._EnableSort();
+		else
+			this.IncludeFile(
+				this.sortConfig.name, 
+				this.sortConfig.src, 
+				this.Evt._EnableSort
+			);
+	},
+	
+	RemoveSort: function()
+	/*====================================================
+		- removes sorting feature
+	=====================================================*/
+	{
+		if(!this.sort) return;
+		this.sort = false;
+	},
+	
+	PopulateSelect: function(colIndex,isExternal,extSlcId)
+	{ 
+		this.EvtManager(
+			this.Evt.name.populateselect,
+			{ slcIndex:colIndex, slcExternal:isExternal, slcId:extSlcId }
+		); 
+	},
+	_PopulateSelect: function(colIndex,isRefreshed,isExternal,extSlcId)
+	/*====================================================
+		- populates drop-down filters
+	=====================================================*/
+	{
+		isExternal = (isExternal==undefined) ? false : isExternal;
+		var slcId = this.fltIds[colIndex];
+		if( tf_Id(slcId)==null && !isExternal ) return;
+		if( tf_Id(extSlcId)==null && isExternal ) return;
+		var slc = (!isExternal) ? tf_Id(slcId) : tf_Id(extSlcId);
+		var o = this, row = this.tbl.rows;
+		var fillMethod = this.slcFillingMethod.tf_LCase();
+		var optArray = [], slcInnerHtml = '', opt0;
+		var isCustomSlc = (this.hasCustomSlcOptions  //custom select test
+							&& this.customSlcOptions.cols.tf_Has(colIndex));
+		var optTxt = []; //custom selects text
+		var activeFlt;
+		if(isRefreshed && this.activeFilterId){
+			activeFlt = this.activeFilterId.split('_')[0];
+			activeFlt = activeFlt.split(this.prfxFlt)[1];
+		}
+
+		/*** remember grid values ***/
+		var flts_values = [], fltArr = [];
+		if(this.rememberGridValues)
+		{
+			flts_values = tf_CookieValueArray(this.fltsValuesCookie);			
+			fltArr = (flts_values[colIndex]!=undefined) 
+						? flts_values[colIndex].split(' '+this.orOperator+' ') 
+						: flts_values[colIndex] = [];			
+		}
+
+		for(var k=this.refRow; k<this.nbRows; k++)
+		{
+			// always visible rows don't need to appear on selects as always valid
+			if( this.hasVisibleRows && this.visibleRows.tf_Has(k) && !this.paging ) 
+				continue;
+
+			var cell = tf_Tag(row[k],'td');
+			var nchilds = cell.length;
+
+			if(nchilds == this.nbCells && !isCustomSlc)
+			{// checks if row has exact cell #
+				for(var j=0; j<nchilds; j++)// this loop retrieves cell data
+				{
+					if((colIndex==j && !isRefreshed) || 
+						(colIndex==j && isRefreshed && ((row[k].style.display == '' && !this.paging) || 
+						( this.paging && (!this.validRowsIndex || (this.validRowsIndex && this.validRowsIndex.tf_Has(k)))
+							&& ((activeFlt==undefined || activeFlt==colIndex)  || (activeFlt!=colIndex && this.validRowsIndex.tf_Has(k) ))) )))
+					{
+						var cell_data = this.GetCellData(j, cell[j]);
+						var cell_string = cell_data.tf_MatchCase(this.matchCase);//Váry Péter's patch
+						// checks if celldata is already in array
+						var isMatched = false;
+						isMatched = optArray.tf_Has(cell_string,this.matchCase);
+						
+						if(!isMatched)
+							optArray.push(cell_data);						
+					}//if colIndex==j
+				}//for j
+			}//if
+		}//for k
+		
+		//Retrieves custom values
+		if(isCustomSlc)
+		{
+			var customValues = this.__getCustomValues(colIndex);
+			optArray = customValues[0];
+			optTxt = customValues[1];
+		}
+		
+		if(this.sortSlc && !isCustomSlc)
+			optArray.sort(this.matchCase ? null : tf_IgnoreCaseSort);
+		
+		if(this.sortNumAsc && this.sortNumAsc.tf_Has(colIndex))
+		{//asc sort
+			try{
+				optArray.sort( tf_NumSortAsc ); 
+				if(isCustomSlc) optTxt.sort( tf_NumSortAsc );
+			} catch(e) {
+				optArray.sort(); 
+				if(isCustomSlc) optTxt.sort();
+			}//in case there are alphanumeric values
+		}
+		if(this.sortNumDesc && this.sortNumDesc.tf_Has(colIndex))
+		{//desc sort
+			try{
+				optArray.sort( tf_NumSortDesc ); 
+				if(isCustomSlc) optTxt.sort( tf_NumSortDesc );
+			} catch(e) {
+				optArray.sort(); 
+				if(isCustomSlc) optTxt.sort();
+			}//in case there are alphanumeric values
+		}
+		
+		AddOpts();//populates drop-down
+		
+		function AddOpt0()
+		{// adds 1st option
+			if( fillMethod == 'innerhtml' )
+				slcInnerHtml += '<option value="">'+o.displayAllText+'</option>';
+			else {
+				var opt0 = tf_CreateOpt(o.displayAllText,'');			
+				slc.appendChild(opt0);
+			}
+		}
+		
+		function AddOpts()
+		{// populates select
+			var slcValue = slc.value;
+			slc.innerHTML = '';
+			AddOpt0();			
+			
+			for(var y=0; y<optArray.length; y++)
+			{			
+				if( fillMethod == 'innerhtml' )
+				{
+					var slcAttr = '';
+					var slcCustomTxt = (isCustomSlc) ? optTxt[y] : optArray[y];
+					if( o.fillSlcOnDemand && slcValue==optArray[y] )
+						slcAttr = 'selected="selected"';
+					slcInnerHtml += '<option value="'+optArray[y]+'" '
+										+slcAttr+'>'+slcCustomTxt+'</option>';
+				} else {
+					var opt;
+					//fill select on demand
+					if(o.fillSlcOnDemand && slcValue==optArray[y] && o['col'+colIndex]==o.fltTypeSlc)
+						opt = tf_CreateOpt( (isCustomSlc) ? optTxt[y] : optArray[y],
+											optArray[y],
+											true );
+					else{
+						if( o['col'+colIndex]!=o.fltTypeMulti )
+							opt = tf_CreateOpt( (isCustomSlc) ? optTxt[y] : optArray[y],
+												optArray[y],
+												(flts_values[colIndex]!=' ' && optArray[y]==flts_values[colIndex]) 
+												? true : false 	);
+						else
+						{
+							opt = tf_CreateOpt( (isCustomSlc) ? optTxt[y] : optArray[y],
+												optArray[y],
+												(fltArr.tf_Has(optArray[y].tf_MatchCase(o.matchCase),o.matchCase)) 
+												? true : false 	);
+						}
+					}
+					slc.appendChild(opt);
+				}
+			}// for y
+
+			if( fillMethod == 'innerhtml' )
+				slc.innerHTML += slcInnerHtml;
+				
+			slc.setAttribute('filled','1');
+		}// fn AddOpt
+	},
+	
+	PopulateCheckList: function(colIndex, isExternal, extFltId)
+	{
+		this.EvtManager(
+			this.Evt.name.populatechecklist,
+			{ slcIndex:colIndex, slcExternal:isExternal, slcId:extFltId }
+		); 
+	},
+	_PopulateCheckList: function(colIndex, isExternal, extFltId)
+	/*====================================================
+		- populates checklist filters
+	=====================================================*/
+	{
+		isExternal = (isExternal==undefined) ? false : isExternal;
+		var divFltId = this.prfxCheckListDiv+colIndex+'_'+this.id;
+		if( tf_Id(divFltId)==null && !isExternal ) return;
+		if( tf_Id(extFltId)==null && isExternal ) return;
+		var flt = (!isExternal) ? this.checkListDiv[colIndex] : tf_Id(extFltId);
+		var ul = tf_CreateElm('ul',['id',this.fltIds[colIndex]],['colIndex',colIndex]);
+		ul.className = this.checkListCssClass;
+		ul.onchange = this.Evt._OnSlcChange;
+		var o = this, row = this.tbl.rows;
+		var optArray = [];
+		var isCustomSlc = (this.hasCustomSlcOptions  //custom select test
+							&& this.customSlcOptions.cols.tf_Has(colIndex));
+		var optTxt = []; //custom selects text
+		var activeFlt;
+		if(this.refreshFilters && this.activeFilterId){
+			activeFlt = this.activeFilterId.split('_')[0];
+			activeFlt = activeFlt.split(this.prfxFlt)[1];
+		}		
+		
+		for(var k=this.refRow; k<this.nbRows; k++)
+		{
+			// always visible rows don't need to appear on selects as always valid
+			if( this.hasVisibleRows && this.visibleRows.tf_Has(k) && !this.paging ) 
+				continue;
+
+			var cells = tf_Tag(row[k],'td');
+			var ncells = cells.length;
+
+			if(ncells == this.nbCells && !isCustomSlc)
+			{// checks if row has exact cell #
+				for(var j=0; j<ncells; j++)
+				{// this loop retrieves cell data
+					if((colIndex==j && !this.refreshFilters) || 
+						(colIndex==j && this.refreshFilters && ((row[k].style.display == '' && !this.paging) || 
+						( this.paging && ((activeFlt==undefined || activeFlt==colIndex ) ||(activeFlt!=colIndex && this.validRowsIndex.tf_Has(k))) ))))
+					{
+						var cell_data = this.GetCellData(j, cells[j]);
+						var cell_string = cell_data.tf_MatchCase(this.matchCase);//Váry Péter's patch
+						// checks if celldata is already in array
+						var isMatched = false;
+						isMatched = optArray.tf_Has(cell_string,this.matchCase);
+						
+						if(!isMatched)
+							optArray.push(cell_data);
+					}
+				}
+			}
+		}
+		
+		//Retrieves custom values
+		if(isCustomSlc)
+		{
+			var customValues = this.__getCustomValues(colIndex);
+			optArray = customValues[0];
+			optTxt = customValues[1];
+		}
+		
+		if(this.sortSlc && !isCustomSlc)
+			optArray.sort(this.matchCase ? null : tf_IgnoreCaseSort);
+		
+		if(this.sortNumAsc && this.sortNumAsc.tf_Has(colIndex))
+		{//asc sort
+			try{
+				optArray.sort( tf_NumSortAsc ); 
+				if(isCustomSlc) optTxt.sort( tf_NumSortAsc );
+			} catch(e) {
+				optArray.sort(); 
+				if(isCustomSlc) optTxt.sort();
+			}//in case there are alphanumeric values
+		}
+		if(this.sortNumDesc && this.sortNumDesc.tf_Has(colIndex))
+		{//desc sort
+			try{
+				optArray.sort( tf_NumSortDesc ); 
+				if(isCustomSlc) optTxt.sort( tf_NumSortDesc );
+			} catch(e) {
+				optArray.sort(); 
+				if(isCustomSlc) optTxt.sort();
+			}//in case there are alphanumeric values
+		}
+
+		AddChecks();
+			
+		function AddCheck0()
+		{// adds 1st option
+			var li0 = tf_CreateCheckItem(o.fltIds[colIndex]+'_0', '', o.displayAllText);
+			li0.className = o.checkListItemCssClass;
+			ul.appendChild(li0);
+			li0.check.onclick = function(){  
+				o.__setCheckListValues(this); 
+								
+				if(o.refreshFilters){
+					//o.activeFilterId = '';
+					//o.RefreshFiltersGrid();
+				}
+				else
+				ul.onchange.call(null);
+			};
+			
+			if(tf_isIE)
+			{//IE: label looses check capability
+				li0.label.onclick = function(){ li0.check.click(); };
+			}
+		}
+		
+		function AddChecks()
+		{		
+			AddCheck0();
+			
+			var flts_values = [], fltArr = []; //remember grid values
+			if(tf_CookieValueByIndex(o.fltsValuesCookie, colIndex)!=undefined)
+				fltArr = tf_CookieValueByIndex(o.fltsValuesCookie, colIndex).split(' '+o.orOperator+' ');
+
+			for(var y=0; y<optArray.length; y++)
+			{
+				var li = tf_CreateCheckItem(
+					o.fltIds[colIndex]+'_'+(y+1), 
+					optArray[y], 
+					(isCustomSlc) ? optTxt[y] : optArray[y]
+				);
+				li.className = o.checkListItemCssClass;
+				ul.appendChild(li);
+				li.check.onclick = function(){ o.__setCheckListValues(this); ul.onchange.call(null); };
+				
+				/*** remember grid values ***/
+				if(o.rememberGridValues)
+				{
+					if(fltArr.tf_Has(optArray[y].tf_MatchCase(o.matchCase),o.matchCase))
+					{
+						li.check.checked = true;
+						o.__setCheckListValues(li.check);
+					}			
+				}
+				
+				if(tf_isIE)
+				{//IE: label looses check capability
+					li.label.onclick = function(){ this.firstChild.click(); };	
+				}
+			}
+		}
+		
+		if(this.fillSlcOnDemand)
+			flt.innerHTML = '';
+		flt.appendChild(ul);
+		flt.setAttribute('filled','1');
+		
+		/*** remember grid values IE only, items remain un-checked ***/
+		if(o.rememberGridValues && tf_isIE)
+		{
+			var slcIndexes = ul.getAttribute('indexes');
+			if(slcIndexes != null)
+			{
+				var indSplit = slcIndexes.split(',');//items indexes
+				for(var n=0; n<indSplit.length; n++)
+				{
+					var cChk = tf_Id(this.fltIds[colIndex]+'_'+indSplit[n]); //checked item
+					if(cChk) cChk.checked = true;
+				}
+			}
+		}
+	},
+	
+	Filter: function()
+	{
+		this.EvtManager(this.Evt.name.filter); 
+	},
+	_Filter: function()
+	/*====================================================
+		- Filtering fn
+		- retrieves data from each td in every single tr
+		and compares to search string for current
+		column
+		- tr is hidden if all search strings are not 
+		found
+	=====================================================*/
+	{
+		if( !this.fltGrid || (!this.hasGrid && !this.isFirstLoad) ) return;
+		//invokes eventual onbefore method
+		if(this.onBeforeFilter) this.onBeforeFilter.call(null,this);
+		var row = this.tbl.rows;	
+		f = this.fObj!=undefined ? this.fObj : [];
+		var hiddenrows = 0;
+		this.validRowsIndex = [];
+		var o = this;		
+		
+		// removes keyword highlighting
+		this.UnhighlightAll();
+
+		// search args re-init
+		this.searchArgs = this.GetFiltersValue(); 
+		
+		var num_cell_data, nbFormat;
+		var re_le = new RegExp(this.leOperator), re_ge = new RegExp(this.geOperator);
+		var re_l = new RegExp(this.lwOperator), re_g = new RegExp(this.grOperator);
+		var re_d = new RegExp(this.dfOperator), re_lk = new RegExp(tf_RegexpEscape(this.lkOperator));
+		var re_eq = new RegExp(this.eqOperator), re_st = new RegExp(this.stOperator);
+		var re_en = new RegExp(this.enOperator), re_an = new RegExp(this.anOperator);
+		var re_cr = new RegExp(this.curExp);
+		
+		function highlight(str,ok,cell){//keyword highlighting
+			if( o.highlightKeywords && ok ){
+				str = str.replace(re_lk,'');
+				str = str.replace(re_eq,'');
+				str = str.replace(re_st,'');
+				str = str.replace(re_en,'');
+				var w = str;
+				if(re_le.test(str) || re_ge.test(str) || re_l.test(str) || re_g.test(str) || re_d.test(str))	
+					w = tf_GetNodeText(cell);
+				if(w!='')
+					tf_HighlightWord( cell,w,o.highlightCssClass );
+			}
+		}
+		
+		//looks for search argument in current row
+		function hasArg(sA,cell_data,j)
+		{
+			var occurence;
+			//Search arg operator tests
+			var hasLO = re_l.test(sA), hasLE = re_le.test(sA);
+			var hasGR = re_g.test(sA), hasGE = re_ge.test(sA);
+			var hasDF = re_d.test(sA), hasEQ = re_eq.test(sA);
+			var hasLK = re_lk.test(sA), hasAN = re_an.test(sA);
+			var hasST = re_st.test(sA), hasEN = re_en.test(sA);
+			
+			//Search arg dates tests
+			var isLDate = ( hasLO && tf_isValidDate(sA.replace(re_l,''),dtType) );
+			var isLEDate = ( hasLE && tf_isValidDate(sA.replace(re_le,''),dtType) );
+			var isGDate = ( hasGR && tf_isValidDate(sA.replace(re_g,''),dtType) );
+			var isGEDate = ( hasGE && tf_isValidDate(sA.replace(re_ge,''),dtType) );
+			var isDFDate = ( hasDF && tf_isValidDate(sA.replace(re_d,''),dtType) );
+			var isEQDate = ( hasEQ && tf_isValidDate(sA.replace(re_eq,''),dtType) );
+						
+			if( tf_isValidDate(cell_data,dtType) )
+			{//dates
+				var dte1 = tf_formatDate(cell_data,dtType);
+				if(isLDate) 
+				{// lower date
+					var dte2 = tf_formatDate(sA.replace(re_l,''),dtType);
+					occurence = (dte1 < dte2);
+				}
+				else if(isLEDate) 
+				{// lower equal date
+					var dte2 = tf_formatDate(sA.replace(re_le,''),dtType);
+					occurence = (dte1 <= dte2);
+				}
+				else if(isGEDate) 
+				{// greater equal date
+					var dte2 = tf_formatDate(sA.replace(re_ge,''),dtType);
+					occurence = (dte1 >= dte2);
+				}
+				else if(isGDate) 
+				{// greater date
+					var dte2 = tf_formatDate(sA.replace(re_g,''),dtType);
+					occurence = (dte1 > dte2);
+				}
+				else if(isDFDate) 
+				{// different date
+					var dte2 = tf_formatDate(sA.replace(re_d,''),dtType);
+					occurence = (dte1.toString() != dte2.toString());
+				}
+				else if(isEQDate) 
+				{// equal date
+					var dte2 = tf_formatDate(sA.replace(re_eq,''),dtType);
+					occurence = (dte1.toString() == dte2.toString());
+				}
+				else if(re_lk.test(sA)) // searched keyword with * operator doesn't have to be a date
+				{// like date
+					occurence = o.__containsStr( sA.replace(re_lk,''),cell_data,null,false);
+				}
+				else if(tf_isValidDate(sA,dtType))
+				{
+					var dte2 = tf_formatDate(sA,dtType);
+					occurence = (dte1.toString() == dte2.toString());
+				}
+			}
+			
+			else 
+			{						
+				//first numbers need to be formated
+				if(o.hasColNbFormat && o.colNbFormat[j]!=null)
+				{
+					num_cell_data = tf_removeNbFormat(cell_data,o.colNbFormat[j]);
+					nbFormat = o.colNbFormat[j];
+				} else {
+					if(o.thousandsSeparator==',' && o.decimalSeparator=='.')
+					{
+						num_cell_data = tf_removeNbFormat(cell_data,'us');
+						nbFormat = 'us';
+					} else {
+						num_cell_data = tf_removeNbFormat(cell_data,'eu');
+						nbFormat = 'eu';
+					}
+				}
+				
+				// first checks if there is any operator (<,>,<=,>=,!,*,=,{,})
+				if(hasLE) //lower equal
+					occurence = num_cell_data <= tf_removeNbFormat(sA.replace(re_le,''),nbFormat);
+				
+				else if(hasGE) //greater equal
+					occurence = num_cell_data >= tf_removeNbFormat(sA.replace(re_ge,''),nbFormat);
+				
+				else if(hasLO) //lower
+					occurence = num_cell_data < tf_removeNbFormat(sA.replace(re_l,''),nbFormat);
+					
+				else if(hasGR) //greater
+					occurence = num_cell_data > tf_removeNbFormat(sA.replace(re_g,''),nbFormat);							
+					
+				else if(hasDF) //different
+					occurence = o.__containsStr( sA.replace(re_d,''),cell_data ) ? false : true;
+			
+				else if(hasLK) //like
+					occurence = o.__containsStr( sA.replace(re_lk,''),cell_data,null,false);
+				
+				else if(hasEQ) //equal
+					occurence = o.__containsStr( sA.replace(re_eq,''),cell_data,null,true);
+				
+				else if(hasST) //starts with
+					occurence = cell_data.indexOf(sA.replace(re_st,''))==0 ? true : false;
+				
+				else if(hasEN) //ends with
+				{
+					var searchArg = sA.replace(re_en,'');
+					occurence = cell_data.lastIndexOf(searchArg,cell_data.length-1)==(cell_data.length-1)-(searchArg.length-1)
+						&& cell_data.lastIndexOf(searchArg,cell_data.length-1) > -1
+						? true : false;
+				}
+				
+				else
+					occurence = o.__containsStr( sA,cell_data,(f['col_'+j]==undefined) ? this.fltTypeInp : f['col_'+j] );
+				
+			}//else
+			return occurence;
+		}//fn
+		
+		for(var k=this.refRow; k<this.nbRows; k++)
+		{
+			/*** if table already filtered some rows are not visible ***/
+			if(row[k].style.display == 'none') row[k].style.display = '';
+					
+			var cell = tf_Tag(row[k],'td');
+			var nchilds = cell.length;			
+			
+			// checks if row has exact cell #
+			if(nchilds != this.nbCells) continue;
+	
+			var occurence = [];
+			var isRowValid = (this.searchType=='include') ? true : false;
+			var singleFltRowValid = false; //only for single filter search
+			
+			for(var j=0; j<nchilds; j++)
+			{// this loop retrieves cell data
+				var sA = this.searchArgs[(this.singleSearchFlt) ? 0 : j]; //searched keyword
+				var dtType = (this.hasColDateType) ? this.colDateType[j] : this.defaultDateType;
+				if(sA=='') continue;
+				
+				var cell_data = this.GetCellData(j, cell[j]).tf_MatchCase(this.matchCase);
+	
+				var sAOrSplit = sA.split(this.orOperator);//multiple search parameter operator ||
+				var hasMultiOrSA = (sAOrSplit.length>1) ? true : false;//multiple search || parameter boolean
+				var sAAndSplit = sA.split('&&');//multiple search parameter operator &&
+				var hasMultiAndSA = (sAAndSplit.length>1) ? true : false;//multiple search && parameter boolean
+
+				if(hasMultiOrSA || hasMultiAndSA)
+				{//multiple sarch parameters
+					var cS, occur = false;
+					var s = (hasMultiOrSA) ? sAOrSplit : sAAndSplit;
+					for(var w=0; w<s.length; w++)
+					{
+						cS = s[w].tf_Trim();
+						occur = hasArg(cS,cell_data,j);
+						highlight(cS,occur,cell[j]);
+						if(hasMultiOrSA && occur) break;
+						if(hasMultiAndSA && !occur) break;
+					}
+					occurence[j] = occur;
+				}
+				else {//single search parameter		
+					occurence[j] = hasArg(sA.tf_Trim(),cell_data,j);
+					highlight(sA,occurence[j],cell[j]);
+				}//else single param
+				
+				if(!occurence[j]) isRowValid = (this.searchType=='include') ? false : true;
+				if(this.singleSearchFlt && occurence[j]) singleFltRowValid = true;
+				
+			}//for j
+			
+			if(this.singleSearchFlt && singleFltRowValid) isRowValid = true;
+			
+			if(!isRowValid)
+			{
+				this.SetRowValidation(k,false);
+				// always visible rows need to be counted as valid
+				if( this.hasVisibleRows && this.visibleRows.tf_Has(k) && !this.paging)
+					this.validRowsIndex.push(k);
+				else
+					hiddenrows++;
+			} else {
+				this.SetRowValidation(k,true);
+				this.validRowsIndex.push(k);
+				this.SetRowBg(k,this.validRowsIndex.length);
+				if(this.onRowValidated) this.onRowValidated.call(null,this,k);
+			}
+			
+		}// for k
+		
+		this.nbVisibleRows = this.validRowsIndex.length;
+		this.nbHiddenRows = hiddenrows;
+		this.isStartBgAlternate = false;
+		if( this.rememberGridValues ) this.RememberFiltersValue(this.fltsValuesCookie);
+		if(!this.paging) this.ApplyGridProps();//applies filter props after filtering process
+		if(this.paging){ 
+			this.startPagingRow = 0; 
+			this.currentPageNb = 1;
+			this.SetPagingInfo(this.validRowsIndex); 
+		}//starts paging process
+		//invokes eventual onafter function
+		if(this.onAfterFilter) this.onAfterFilter.call(null,this);
+	},
+	
+	SetPagingInfo: function( validRows )
+	/*====================================================
+		- calculates page # according to valid rows
+		- refreshes paging select according to page #
+		- Calls GroupByPage method
+	=====================================================*/
+	{
+		var row = this.tbl.rows;
+		var mdiv = ( this.pagingTgtId==null ) ? this.mDiv : tf_Id( this.pagingTgtId );
+		var pgspan = tf_Id(this.prfxPgSpan+this.id);
+		
+		if( validRows!=undefined ) this.validRowsIndex = validRows;//stores valid rows index
+		else 
+		{
+			this.validRowsIndex = [];//re-sets valid rows index
+	
+			for(var j=this.refRow; j<this.nbRows; j++)//counts rows to be grouped 
+			{
+				var isRowValid = row[j].getAttribute('validRow');
+				if(isRowValid=='true' || isRowValid==null )
+						this.validRowsIndex.push(j);
+			}//for j
+		}
+	
+		this.nbPages = Math.ceil( this.validRowsIndex.length/this.pagingLength );//calculates nb of pages
+		pgspan.innerHTML = this.nbPages; //refresh page nb span 
+		if(this.pageSelectorType==this.fltTypeSlc) 
+			this.pagingSlc.innerHTML = '';//select clearing shortcut
+		
+		if( this.nbPages>0 )
+		{
+			mdiv.style.visibility = 'visible';
+			if(this.pageSelectorType==this.fltTypeSlc)
+				for(var z=0; z<this.nbPages; z++)
+				{
+					var currOpt = new Option((z+1),z*this.pagingLength,false,false);
+					this.pagingSlc.options[z] = currOpt;
+				}
+			else this.pagingSlc.value = this.currentPageNb; //input type
+			
+		} else {/*** if no results paging select and buttons are hidden ***/
+			mdiv.style.visibility = 'hidden';
+		}
+		this.GroupByPage( this.validRowsIndex );
+	},
+	
+	GroupByPage: function( validRows )
+	/*====================================================
+		- Displays current page rows
+	=====================================================*/
+	{
+		var row = this.tbl.rows;
+		var paging_end_row = parseInt( this.startPagingRow ) + parseInt( this.pagingLength );
+		
+		if( validRows!=undefined ) this.validRowsIndex = validRows;//stores valid rows index
+	
+		for(h=0; h<this.validRowsIndex.length; h++)
+		{//this loop shows valid rows of current page
+			if( h>=this.startPagingRow && h<paging_end_row )
+			{
+				var r = row[ this.validRowsIndex[h] ];
+				if(r.getAttribute('validRow')=='true' || r.getAttribute('validRow')==undefined)
+					r.style.display = '';
+				this.SetRowBg(this.validRowsIndex[h],h);
+			} else {
+				row[ this.validRowsIndex[h] ].style.display = 'none';
+				this.RemoveRowBg(this.validRowsIndex[h]);
+			}
+		}
+		
+		this.nbVisibleRows = this.validRowsIndex.length;
+		this.isStartBgAlternate = false;
+		this.ApplyGridProps();//re-applies filter behaviours after filtering process
+	},
+	
+	ApplyGridProps: function()
+	/*====================================================
+		- checks methods that should be called
+		after filtering and/or paging process
+	=====================================================*/
+	{
+		if( this.activeFlt && this.activeFlt.nodeName.tf_LCase()==this.fltTypeSlc )
+		{// blurs active filter (IE)
+			this.activeFlt.blur(); 
+			if(this.activeFlt.parentNode) this.activeFlt.parentNode.focus(); 
+		}
+		
+		if( this.visibleRows ) this.SetVisibleRows();//shows rows always visible
+		if( this.colOperation ) this.SetColOperation();//makes operation on a col
+		if( this.refreshFilters ) this.RefreshFiltersGrid();//re-populates drop-down filters
+		var nr = (!this.paging && this.hasVisibleRows) 
+					? (this.nbVisibleRows - this.visibleRows.length) : this.nbVisibleRows;
+		if( this.rowsCounter ) this.RefreshNbRows( nr );//refreshes rows counter
+	},
+	
+	RefreshNbRows: function(p)
+	/*====================================================
+		- Shows total number of filtered rows
+	=====================================================*/
+	{
+		if(this.rowsCounterSpan == null) return;
+		var totTxt;
+		if(!this.paging)
+		{
+			if(p!=undefined && p!='') totTxt=p;
+			else totTxt = (this.nbFilterableRows - this.nbHiddenRows - (this.hasVisibleRows ? this.visibleRows.length : 0) );
+		} else {
+			var paging_start_row = parseInt(this.startPagingRow)+((this.nbVisibleRows>0) ? 1 : 0);//paging start row
+			var paging_end_row = (paging_start_row+this.pagingLength)-1 <= this.nbVisibleRows 
+				? (paging_start_row+this.pagingLength)-1 : this.nbVisibleRows;
+			totTxt = paging_start_row+'-'+paging_end_row+' / '+this.nbVisibleRows;
+		} 
+		this.rowsCounterSpan.innerHTML = totTxt;
+	},
+	
+	ChangePage: function( index )
+	{
+		this.EvtManager(this.Evt.name.changepage,{ pgIndex:index });
+	},
+	_ChangePage: function( index )
+	/*====================================================
+		- Changes page
+		- Param:
+			- index: option index of paging select 
+			(numeric value)
+	=====================================================*/
+	{
+		if( !this.paging ) return;
+		if( index==undefined ) 
+			index = (this.pageSelectorType==this.fltTypeSlc) ? 
+				this.pagingSlc.options.selectedIndex : (this.pagingSlc.value-1);
+		if( index>=0 && index<=(this.nbPages-1) )
+		{
+			this.currentPageNb = parseInt(index)+1;
+			if(this.pageSelectorType==this.fltTypeSlc)
+				this.pagingSlc.options[index].selected = true;
+			else
+				this.pagingSlc.value = this.currentPageNb;
+
+			if( this.rememberPageNb ) this.RememberPageNb( this.pgNbCookie );
+			this.startPagingRow = (this.pageSelectorType==this.fltTypeSlc)
+				? this.pagingSlc.value : (index*this.pagingLength);
+			this.GroupByPage();
+		}
+	},
+	
+	ChangeResultsPerPage: function()
+	{
+		this.EvtManager(this.Evt.name.changeresultsperpage);
+	},
+	_ChangeResultsPerPage: function()
+	/*====================================================
+		- calculates rows to be displayed in a page
+		- method called by nb results per page select
+	=====================================================*/
+	{
+		if( !this.paging ) return;
+		var slcR = this.resultsPerPageSlc;
+		var slcPagesSelIndex = (this.pageSelectorType==this.fltTypeSlc) 
+			? this.pagingSlc.selectedIndex : parseInt(this.pagingSlc.value-1);
+		this.pagingLength = parseInt(slcR.options[slcR.selectedIndex].value);
+		this.startPagingRow = this.pagingLength*slcPagesSelIndex;
+
+		if( !isNaN(this.pagingLength) )
+		{
+			if( this.startPagingRow>=this.nbFilterableRows )
+				this.startPagingRow = (this.nbFilterableRows-this.pagingLength);
+			this.SetPagingInfo();
+
+			if(this.pageSelectorType==this.fltTypeSlc)
+			{
+				var slcIndex = (this.pagingSlc.options.length-1<=slcPagesSelIndex ) 
+								? (this.pagingSlc.options.length-1) : slcPagesSelIndex;
+				this.pagingSlc.options[slcIndex].selected = true;
+			}
+			if( this.rememberPageLen ) this.RememberPageLength( this.pgLenCookie );
+		}//if isNaN
+	},
+	
+	Sort: function()
+	{
+		this.EvtManager(this.Evt.name.sort);
+	},
+	
+	GetColValues: function(colindex,num,exclude)
+	/*====================================================
+		- returns an array containing cell values of
+		a column
+		- needs following args:
+			- column index (number)
+			- a boolean set to true if we want only 
+			numbers to be returned
+			- array containing rows index to be excluded
+			from returned values
+	=====================================================*/
+	{
+		if( !this.fltGrid ) return;
+		var row = this.tbl.rows;
+		var colValues = [];
+	
+		for(var i=this.refRow; i<this.nbRows; i++)//iterates rows
+		{
+			var isExludedRow = false;
+			if(exclude!=undefined && (typeof exclude).tf_LCase()=='object')
+			{ // checks if current row index appears in exclude array
+				isExludedRow = exclude.tf_Has(i); //boolean
+			}
+			var cell = tf_Tag(row[i],'td');
+			var nchilds = cell.length;
+			
+			if(nchilds == this.nbCells && !isExludedRow)
+			{// checks if row has exact cell # and is not excluded
+				for(var j=0; j<nchilds; j++)// this loop retrieves cell data
+				{
+					if(j==colindex && row[i].style.display=='' )
+					{
+						var cell_data = this.GetCellData(j, cell[j]).tf_LCase();
+						var nbFormat = this.colNbFormat ? this.colNbFormat[colindex] : null;
+						(num) ? colValues.push( tf_removeNbFormat(cell_data,nbFormat) ) 
+								: colValues.push( cell_data );
+					}//if j==k
+				}//for j
+			}//if nchilds == this.nbCells
+		}//for i
+		return colValues;	
+	},
+	
+	GetFilterValue: function(index)
+	/*====================================================
+		- Returns value of a specified filter
+		- Params:
+			- index: filter column index (numeric value)
+	=====================================================*/
+	{
+		if( !this.fltGrid ) return;
+		var fltValue;
+		var flt = tf_Id(this.fltIds[index]);
+		if(flt==null) return fltValue='';
+		
+		if( this['col'+index]!=this.fltTypeMulti && 
+			this['col'+index]!=this.fltTypeCheckList )
+			fltValue = flt.value;
+		else if(this['col'+index] == this.fltTypeMulti)
+		{//mutiple select
+			fltValue = '';
+			for(var j=0; j<flt.options.length; j++) 
+				if(flt.options[j].selected)
+					fltValue = fltValue.concat(
+								flt.options[j].value+' ' +
+								this.orOperator + ' '
+								);
+			//removes last operator ||
+			fltValue = fltValue.substr(0,fltValue.length-4);
+		}
+		else if(this['col'+index]==this.fltTypeCheckList)
+		{//checklist
+			if(flt.getAttribute('value')!=null)
+			{
+				fltValue = flt.getAttribute('value');
+				//removes last operator ||
+				fltValue = fltValue.substr(0,fltValue.length-3);
+			} else fltValue = '';
+		}			
+		return fltValue;
+	},
+	
+	GetFiltersValue: function()
+	/*====================================================
+		- Returns the value of every single filter
+	=====================================================*/
+	{
+		if( !this.fltGrid ) return;
+		var searchArgs = [];
+		for(var i=0; i<this.fltIds.length; i++)
+			searchArgs.push(
+				this.GetFilterValue(i).tf_MatchCase(this.matchCase).tf_Trim()
+			);
+		return searchArgs;
+	},
+	
+	GetFilterId: function(index)
+	/*====================================================
+		- Returns filter id of a specified column
+		- Params:
+			- index: column index (numeric value)
+	=====================================================*/
+	{
+		if( !this.fltGrid ) return;
+		return this.fltIds[i];
+	},
+	
+	GetFiltersByType: function(type,bool)
+	/*====================================================
+		- returns an array containing ids of filters of a 
+		specified type (inputs or selects)
+		- Note that hidden filters are also returned
+		- Needs folllowing args:
+			- filter type string ('input','select',
+			'multiple')
+			- optional boolean: if set true method
+			returns column indexes otherwise filters ids
+	=====================================================*/
+	{
+		if( !this.fltGrid ) return;
+		var arr = [];
+		for(var i=0; i<this.fltIds.length; i++)
+		{
+			var fltType = this['col'+i];
+			if(fltType == type.tf_LCase())
+			{
+				var a = (bool) ? i : this.fltIds[i];
+				arr.push(a);
+			}
+		}
+		return arr;
+	},
+	
+	GetCellsNb: function( rowIndex )
+	/*====================================================
+		- returns number of cells in a row
+		- if rowIndex param is passed returns number of 
+		cells of specified row (number)
+	=====================================================*/
+	{
+		var tr = (rowIndex == undefined) ? this.tbl.rows[0] : this.tbl.rows[rowIndex];
+		var n = tf_GetChildElms(tr);
+		return n.childNodes.length;
+	},
+	
+	GetRowsNb: function()
+	/*====================================================
+		- returns total nb of filterable rows starting 
+		from reference row if defined
+	=====================================================*/
+	{
+		var s = this.refRow==undefined ? 0 : this.refRow;
+		var ntrs = this.tbl.rows.length;
+		return parseInt(ntrs-s);
+	},
+	
+	GetCellData: function(i, cell)
+	/*====================================================
+		- returns text content of a given cell
+		- Params:
+			- i: index of the column (number)
+			- cell: td DOM object
+	=====================================================*/
+	{
+		if(i==undefined || cell==null) return "";
+		//First checks for customCellData event
+		if(this.customCellData && this.customCellDataCols.tf_Has(i))
+			return this.customCellData.call(null,this,cell,i);
+		else
+			return tf_GetNodeText(cell);
+	},
+	
+	GetTableData: function()
+	/*====================================================
+		- returns an array containing table data:
+		[rowindex,[value1,value2,value3...]]
+	=====================================================*/
+	{
+		var row = this.tbl.rows;
+		for(var k=this.refRow; k<this.nbRows; k++)
+		{
+			var rowData, cellData;
+			rowData = [k,[]];
+			var cells = tf_Tag(row[k],'td');
+			for(var j=0; j<cells.length; j++)
+			{// this loop retrieves cell data
+				var cell_data = this.GetCellData(j, cells[j]);
+				rowData[1].push( cell_data );
+			}
+			this.tblData.push( rowData )
+		}
+		return this.tblData;
+	},
+	
+	GetFilteredData: function()
+	/*====================================================
+		- returns an array containing filtered data:
+		[rowindex,[value1,value2,value3...]]
+	=====================================================*/
+	{
+		if(!this.validRowsIndex) return [];
+		var row = this.tbl.rows;
+		var filteredData = [];
+		for(var i=0; i<this.validRowsIndex.length; i++)
+		{
+			var rowData, cellData;
+			rowData = [this.validRowsIndex[i],[]];
+			var cells = tf_Tag(row[this.validRowsIndex[i]],'td');
+			for(var j=0; j<cells.length; j++)
+			{
+				var cell_data = this.GetCellData(j, cells[j]);
+				rowData[1].push( cell_data );
+			}
+			filteredData.push(rowData);
+		}
+		return filteredData;
+	},
+	
+	GetFilteredDataCol: function(colIndex)
+	/*====================================================
+		- returns an array containing filtered data of a
+		specified column. 
+		- Params:
+			- colIndex: index of the column (number)
+		- returned array:
+		[value1,value2,value3...]
+	=====================================================*/
+	{
+		if(colIndex==undefined) return [];
+		var data =  this.GetFilteredData();
+		var colData = [];
+		for(var i=0; i<data.length; i++)
+		{
+			var r = data[i];
+			var d = r[1]; //cols values of current row
+			var c = d[colIndex]; //data of searched column
+			colData.push(c);
+		}
+		return colData;
+	},
+	
+	GetRowDisplay: function(row)
+	{
+		if( !this.fltGrid && typeof row.tf_LCase!='object' ) return;
+		return row.style.display;
+	},
+	
+	SetRowValidation: function( rowIndex,isValid )
+	/*====================================================
+		- Validates/unvalidates row by setting 'validRow' 
+		attribute and shows/hides row
+		- Params:
+			- rowIndex: index of the row (number)
+			- isValid: boolean
+	=====================================================*/
+	{
+		var row = this.tbl.rows[rowIndex];
+		if( !row || (typeof isValid).tf_LCase()!='boolean' ) return;
+	
+		// always visible rows are valid
+		if( this.hasVisibleRows && this.visibleRows.tf_Has(rowIndex) && !this.paging )
+			isValid = true;
+		
+		var displayFlag = (isValid) ? '' : 'none';
+		var validFlag = (isValid) ? 'true' : 'false';		
+		row.style.display = displayFlag;
+		
+		if( this.paging ) 
+			row.setAttribute('validRow',validFlag);
+	},
+	
+	ValidateAllRows: function()
+	/*====================================================
+		- Validates all filterable rows
+	=====================================================*/
+	{
+		if( !this.hasGrid ) return;
+		this.validRowsIndex = [];
+		for(var k=this.refRow; k<this.nbFilterableRows; k++)
+		{
+			this.SetRowValidation(k,true);
+			this.validRowsIndex.push(k);
+		}
+	},
+	
+	SetFilterValue: function(index,searcharg,doFilter)
+	/*====================================================
+		- Inserts value in a specified filter
+		- Params:
+			- index: filter column index (numeric value)
+			- searcharg: search string
+			- doFilter: optional boolean for multiple
+			selects: executes filtering when multiple 
+			select populated... IE only!
+	=====================================================*/
+	{
+		if( (!this.fltGrid && !this.isFirstLoad) || tf_Id(this.fltIds[index])==null ) return;
+		var slc = tf_Id(this.fltIds[index]);
+		var execFilter = (doFilter==undefined) ? true : doFilter;
+		searcharg = (searcharg==undefined) ? '' : searcharg;
+		
+		if( this['col'+index]!=this.fltTypeMulti && 
+			this['col'+index]!=this.fltTypeCheckList )
+			slc.value = searcharg;
+			
+		else if(this['col'+index] == this.fltTypeMulti)
+		{//multiple selects
+			var s = searcharg.split(' '+this.orOperator+' ');
+			var ct = 0; //keywords counter
+			for(var j=0; j<slc.options.length; j++) 
+			{
+				if(s=='') slc.options[j].selected = false;
+				if(slc.options[j].value=='') slc.options[j].selected = false;
+				if(slc.options[j].value!='' && s.tf_Has(slc.options[j].value,true))
+				{
+					if(tf_isIE)
+					{// IE multiple selection work-around
+						//when last value reached filtering can be executed
+						var filter = (ct==(s.length-1) && execFilter) ? true : false;
+						this.__deferMultipleSelection(slc,j,filter);
+						ct++;
+					}					
+					else
+						slc.options[j].selected = true;
+				}//if
+			}//for j
+		}
+		
+		else if(this['col'+index]==this.fltTypeCheckList)
+		{//checklist
+			searcharg = searcharg.tf_MatchCase(this.matchCase);
+			var s = searcharg.split(' '+this.orOperator+' ');
+			var fltValue = slc.setAttribute('value','');
+			var fltIndex = slc.setAttribute('indexes','');
+			for(var k=0; k<tf_Tag(slc,'li').length; k++) 
+			{
+				var li = tf_Tag(slc,'li')[k];
+				var lbl = tf_Tag(li,'label')[0];
+				var chk = tf_Tag(li,'input')[0];
+				var lblTxt = tf_GetNodeText(lbl).tf_MatchCase(this.matchCase);
+				if(lblTxt!='' && s.tf_Has(lblTxt,true))
+				{
+					chk.checked = true;
+					this.__setCheckListValues(chk);
+				}
+				else{ 
+					chk.checked = false;
+					this.__setCheckListValues(chk);
+				}
+			}
+		}
+	},
+
+	SetColWidths: function(rowIndex)
+	/*====================================================
+		- sets coluun widths in pixels
+	=====================================================*/
+	{
+		if( !this.fltGrid || !this.hasColWidth ) return;
+		var o = this, rIndex;
+		if(rowIndex==undefined) rIndex = this.tbl.rows[0].style.display!='none' ? 0 : 1;
+		else rIndex = rowIndex;
+		setWidths( this.tbl.rows[rIndex] );
+
+		function setWidths( row )
+		{
+			if( !o && (o.nbCells!=o.colWidth.length) ) return;
+			if( o.nbCells==row.cells.length )
+				for(var k=0; k<o.nbCells; k++)
+					row.cells[k].style.width = o.colWidth[k];
+		}
+	},
+	
+	SetVisibleRows: function()
+	/*====================================================
+		- makes a row always visible
+		- Note this works only if paging is false
+	=====================================================*/
+	{
+		if( this.hasGrid && this.hasVisibleRows && !this.paging )
+		{
+			for(var i=0; i<this.visibleRows.length; i++)
+			{
+				if(this.visibleRows[i]<=this.nbRows)//row index cannot be > nrows
+					this.SetRowValidation(this.visibleRows[i],true);
+			}//for i
+		}//if hasGrid
+	},
+	
+	SetRowBg: function(rIndex,index)
+	/*====================================================
+		- sets row background color
+		- Params:
+			- rIndex: row index (numeric value)
+			- index: valid row collection index needed to
+			calculate bg color
+	=====================================================*/
+	{
+		if(!this.alternateBgs || isNaN(rIndex)) return;
+		var rows = this.tbl.rows;
+		var i = (index==undefined) ? rIndex : index;
+		this.RemoveRowBg(rIndex);
+		tf_addClass(
+			rows[rIndex],
+			(i%2 == 0) ? this.rowBgEvenCssClass : this.rowBgOddCssClass
+		);
+	},
+	
+	RemoveRowBg: function(index)
+	/*====================================================
+		- removes row background color
+		- Params:
+			- index: row index (numeric value)
+	=====================================================*/
+	{
+		if(isNaN(index)) return;
+		var rows = this.tbl.rows;
+		tf_removeClass(rows[index],this.rowBgOddCssClass);
+		tf_removeClass(rows[index],this.rowBgEvenCssClass);
+	},
+	
+	SetAlternateRows: function()
+	/*====================================================
+		- alternates row colors for better readability
+	=====================================================*/
+	{
+		if( !this.hasGrid && !this.isFirstLoad ) return;
+		var rows = this.tbl.rows;
+		var noValidRowsIndex = this.validRowsIndex==null;
+		var beginIndex = (noValidRowsIndex) ? this.refRow : 0; //1st index
+		var indexLen = (noValidRowsIndex) // nb indexes
+			? (this.nbFilterableRows+beginIndex) : this.validRowsIndex.length;
+
+		for(var j=beginIndex; j<indexLen; j++)//alternates bg color
+		{
+			var rIndex = (noValidRowsIndex) ? j : this.validRowsIndex[j];
+			this.SetRowBg(rIndex);
+		}
+	},
+	
+	RemoveAlternateRows: function()
+	/*====================================================
+		- removes alternate row colors
+	=====================================================*/
+	{
+		if(!this.hasGrid) return;
+		var row = this.tbl.rows;
+		for(var i=this.refRow; i<this.nbRows; i++)
+			this.RemoveRowBg(i);
+		this.isStartBgAlternate = true;
+	},
+	
+	SetColOperation: function()
+	/*====================================================
+		- Calculates values of a column
+		- params are stored in 'colOperation' table's
+		attribute
+			- colOperation['id'] contains ids of elements 
+			showing result (array)
+			- colOperation['col'] contains index of 
+			columns (array)
+			- colOperation['operation'] contains operation
+			type (array, values: sum, mean)
+			- colOperation['write_method'] array defines 
+			which method to use for displaying the 
+			result (innerHTML, setValue, createTextNode).
+			Note that innerHTML is the default value.
+			- colOperation['tot_row_index'] defines in 
+			which row results are displayed (integers array)
+			
+		- changes made by nuovella: 
+		(1) optimized the routine (now it will only 
+		process each column once),
+		(2) added calculations for the median, lower and 
+		upper quartile.
+	=====================================================*/
+	{
+		if( !this.isFirstLoad && !this.hasGrid ) return;
+		
+		if(this.onBeforeOperation) this.onBeforeOperation.call(null,this);
+		
+		var labelId = this.colOperation['id'];
+		var colIndex = this.colOperation['col'];
+		var operation = this.colOperation['operation'];
+		var outputType = this.colOperation['write_method'];
+		var totRowIndex = this.colOperation['tot_row_index'];
+		var excludeRow = this.colOperation['exclude_row'];
+		var decimalPrecision = this.colOperation['decimal_precision']!=undefined
+								? this.colOperation['decimal_precision'] : 2;
+		
+		//nuovella: determine unique list of columns to operate on
+		var ucolIndex =[]; 
+		var ucolMax=0;
+		
+		ucolIndex[ucolMax]=colIndex[0];
+		
+		for(var i=1; i<colIndex.length; i++)
+		{
+			saved=0;
+			//see if colIndex[i] is already in the list of unique indexes
+			for(var j=0; j<=ucolMax; j++ )
+			{
+				if (ucolIndex[j]==colIndex[i])
+					saved=1;
+			}
+			if (saved==0)
+			{//if not saved then, save the index;
+				ucolMax++;
+				ucolIndex[ucolMax]=colIndex[i];
+			}
+		}// for i
+		
+		if( (typeof labelId).tf_LCase()=='object' 
+			&& (typeof colIndex).tf_LCase()=='object' 
+			&& (typeof operation).tf_LCase()=='object' )
+		{
+			var row = this.tbl.rows;
+			var colvalues = [];
+			
+			for(var ucol=0; ucol<=ucolMax; ucol++)
+			{
+				//this retrieves col values 
+				//use ucolIndex because we only want to pass through this loop once for each column
+				//get the values in this unique column
+				colvalues.push( this.GetColValues(ucolIndex[ucol],true,excludeRow) );
+				
+			   //next: calculate all operations for this column
+			   var result, nbvalues=0,  temp;
+			   var meanValue=0, sumValue=0, minValue=null, maxValue=null, q1Value=null, medValue=null, q3Value=null;
+			   var meanFlag=0, sumFlag=0, minFlag=0, maxFlag=0, q1Flag=0, medFlag=0, q3Flag=0;
+			   var theList=[];
+			   var opsThisCol=[], decThisCol=[], labThisCol=[], oTypeThisCol=[];
+			   var mThisCol=-1;
+				
+				for(var i=0; i<colIndex.length; i++)
+				{
+					 if (colIndex[i]==ucolIndex[ucol])
+					 {
+						mThisCol++;
+						opsThisCol[mThisCol]=operation[i].tf_LCase();
+						decThisCol[mThisCol]=decimalPrecision[i];
+						labThisCol[mThisCol]=labelId[i]; 
+						oTypeThisCol = (outputType != undefined && (typeof outputType).tf_LCase()=='object') 
+											? outputType[i] : null;
+						
+						switch( opsThisCol[mThisCol] )
+						{			
+							case 'mean':
+								meanFlag=1;
+							break;
+							case 'sum':
+								sumFlag=1;
+							break;
+							case 'min':
+								minFlag=1;
+							break;
+							case 'max':
+								maxFlag=1;
+							break;
+							case 'median':
+								medFlag=1;	
+								break;
+							case 'q1':
+								q1Flag=1;
+							break;
+							case 'q3':
+								q3Flag=1;
+							break;
+						}
+					}		
+				}
+				
+				for(var j=0; j<colvalues[ucol].length; j++ )
+				{
+					if ((q1Flag==1)||(q3Flag==1) || (medFlag==1))
+					{//sort the list for calculation of median and quartiles
+						if (j<colvalues[ucol].length -1)
+						{
+							for(k=j+1;k<colvalues[ucol].length; k++) {
+				  
+								if( eval(colvalues[ucol][k]) < eval(colvalues[ucol][j]))
+								{
+									temp = colvalues[ucol][j];            
+									colvalues[ucol][j] = colvalues[ucol][k];              
+									colvalues[ucol][k] = temp;            
+								}
+							}
+						}
+					}
+					var cvalue = parseFloat(colvalues[ucol][j]);
+					theList[j]=parseFloat( cvalue );
+	
+					if( !isNaN(cvalue) )
+					{
+						nbvalues++;
+						if ((sumFlag==1)|| (meanFlag==1)) sumValue += parseFloat( cvalue );
+						if (minFlag==1) 
+						{
+							if (minValue==null)
+							{
+								minValue = parseFloat( cvalue );
+							}
+							else minValue= parseFloat( cvalue )<minValue? parseFloat( cvalue ): minValue;
+						}
+						if (maxFlag==1) {
+							if (maxValue==null)
+							{maxValue = parseFloat( cvalue );}
+						else {maxValue= parseFloat( cvalue )>maxValue? parseFloat( cvalue ): maxValue;}
+						}
+					}
+				}//for j
+				if (meanFlag==1) meanValue = sumValue/nbvalues;
+				if (medFlag==1)
+				{
+						var aux = 0;
+						if(nbvalues%2 == 1) 
+						{
+							aux = Math.floor(nbvalues/2);
+							medValue = theList[aux];   
+						}
+					else medValue = (theList[nbvalues/2]+theList[((nbvalues/2)-1)])/2;
+				}
+				if (q1Flag==1)
+				{	
+					var posa=0.0;
+					posa = Math.floor(nbvalues/4);
+					if (4*posa == nbvalues) {q1Value = (theList[posa-1] + theList[posa])/2;}
+					else {q1Value = theList[posa];}
+				}
+				if (q3Flag==1)
+				{
+					var posa=0.0;
+					var posb=0.0;
+					posa = Math.floor(nbvalues/4);
+					if (4*posa == nbvalues)
+					{
+						posb = 3*posa;
+						q3Value = (theList[posb] + theList[posb-1])/2;  
+					}
+					else
+						q3Value = theList[nbvalues-posa-1];
+				}
+				
+				for(var i=0; i<=mThisCol; i++ )
+				{
+				   switch( opsThisCol[i] )
+				   {			
+						case 'mean':
+							result=meanValue;
+						break;
+						case 'sum':
+							result=sumValue;
+						break;
+						case 'min':
+							result=minValue;
+						break;
+						case 'max':
+							result=maxValue;
+						break;
+						case 'median':
+							result=medValue;	
+							break;
+						case 'q1':
+							result=q1Value;
+						break;
+						case 'q3':
+							result=q3Value;
+						break;
+				  }		
+					
+				var precision = decThisCol[i]!=undefined && !isNaN( decThisCol[i] )
+									? decThisCol[i] : 2;
+
+				if(oTypeThisCol!=null && result)
+				{//if outputType is defined
+					result = result.toFixed( precision );
+					if( tf_Id( labThisCol[i] )!=undefined )
+					{
+						switch( oTypeThisCol.tf_LCase() )
+						{
+							case 'innerhtml':							
+								if (isNaN(result) || !isFinite(result) || (nbvalues==0)) 
+									tf_Id( labThisCol[i] ).innerHTML = '.';
+								else
+									tf_Id( labThisCol[i] ).innerHTML = result;
+							break;
+							case 'setvalue':
+								tf_Id( labThisCol[i] ).value = result;
+							break;
+							case 'createtextnode':
+								var oldnode = tf_Id( labThisCol[i] ).firstChild;
+								var txtnode = tf_CreateText( result );
+								tf_Id( labThisCol[i] ).replaceChild( txtnode,oldnode );
+							break;
+						}//switch
+					}
+				} else {
+					try
+					{      
+						if (isNaN(result) || !isFinite(result) || (nbvalues==0)) 
+							tf_Id( labThisCol[i] ).innerHTML = '.';
+						else
+							 tf_Id( labThisCol[i] ).innerHTML = result.toFixed( precision );
+					} catch(e){ }//catch
+				}//else
+			 }//for i
+			//eventual row(s) with result are always visible
+			if(totRowIndex!=undefined && row[totRowIndex[ucol]]) 
+				row[totRowIndex[ucol]].style.display = '';
+			}//for ucol
+		}//if typeof
+		
+		if(this.onAfterOperation) this.onAfterOperation.call(null,this);
+	},
+	
+	SetPage: function( cmd )
+	/*====================================================
+		- If paging set true shows page according to
+		param value (string or number):
+			- strings: 'next','previous','last','first' or
+			- number: page number
+	=====================================================*/
+	{
+		if( this.hasGrid && this.paging )
+		{
+			var btnEvt = this.pagingBtnEvents, cmdtype = typeof cmd;
+			if(cmdtype=='string')
+			{
+				switch(cmd.tf_LCase())
+				{
+					case 'next':
+						btnEvt.next();
+					break;
+					case 'previous':
+						btnEvt.prev();
+					break;
+					case 'last':
+						btnEvt.last();
+					break;
+					case 'first':
+						btnEvt.first();
+					break;
+					default:
+						btnEvt.next();
+					break;
+				}//switch
+			}
+			if(cmdtype=='number') this.ChangePage( (cmd-1) );
+		}// this.hasGrid 
+	},
+	
+	RefreshFiltersGrid: function()
+	/*====================================================
+		- retrieves select, multiple and checklist filters
+		- calls method repopulating filters
+	=====================================================*/
+	{
+		var slcA1 = this.GetFiltersByType( this.fltTypeSlc,true );
+		var slcA2 = this.GetFiltersByType( this.fltTypeMulti,true );
+		var slcA3 = this.GetFiltersByType( this.fltTypeCheckList,true );
+		var slcIndex = slcA1.concat(slcA2);
+		slcIndex = slcIndex.concat(slcA3);
+
+		if( this.activeFilterId!=null )//for paging
+		{
+			var activeFlt = this.activeFilterId.split('_')[0];
+			activeFlt = activeFlt.split(this.prfxFlt)[1];
+			var slcSelectedValue;
+			for(var i=0; i<slcIndex.length; i++)
+			{
+				var curSlc = tf_Id(this.fltIds[slcIndex[i]]);
+				slcSelectedValue = this.GetFilterValue( slcIndex[i] );
+				//if(activeFlt==slcIndex[i] && slcA3.tf_Has(slcIndex[i]) && slcSelectedValue!=this.displayAllText) continue;
+				if(activeFlt!=slcIndex[i] || (this.paging && slcA1.tf_Has(slcIndex[i]) && activeFlt==slcIndex[i] ) || 
+					( !this.paging && (slcA3.tf_Has(slcIndex[i]) || slcA2.tf_Has(slcIndex[i]) ) /*&& activeFlt==slcIndex[i]*/) || 
+					slcSelectedValue==this.displayAllText )
+					//(this.paging && (!slcA3.tf_Has(slcIndex[i]) && !slcA2.tf_Has(slcIndex[i]) && activeFlt==slcIndex[i]) ) )
+				{
+					if(slcA3.tf_Has(slcIndex[i]))
+						this.checkListDiv[slcIndex[i]].innerHTML = '';
+					else curSlc.innerHTML = '';
+					
+					if(this.fillSlcOnDemand) { //1st option needs to be inserted
+						var opt0 = tf_CreateOpt(this.displayAllText,'');
+						curSlc.appendChild( opt0 );
+					}
+					
+					if(slcA3.tf_Has(slcIndex[i]))
+						this._PopulateCheckList(slcIndex[i]);
+					else
+						this._PopulateSelect(slcIndex[i],true);
+						
+					this.SetFilterValue(slcIndex[i],slcSelectedValue);
+				}
+			}// for i
+		}
+	},
+	
+	RememberFiltersValue: function( name )
+	/*==============================================
+		- stores filters' values in a cookie
+		when Filter() method is called
+		- Params:
+			- name: cookie name (string)
+		- credits to Florent Hirchy
+	===============================================*/
+	{
+		var flt_values = [];
+		for(var i=0; i<this.fltIds.length; i++)
+		{//creates an array with filters' values
+			value = this.GetFilterValue(i);
+			if (value == '') value = ' ';
+			flt_values.push(value);
+		}
+		flt_values.push(this.fltIds.length); //adds array size
+		tf_WriteCookie(
+			name,
+			flt_values,
+			this.cookieDuration
+		); //writes cookie  
+	},
+	
+	RememberPageNb: function( name )
+	/*==============================================
+		- stores page number value in a cookie
+		when ChangePage method is called
+		- Params:
+			- name: cookie name (string)
+	===============================================*/
+	{
+		tf_WriteCookie(
+			name,
+			this.currentPageNb,
+			this.cookieDuration
+		); //writes cookie  
+	},
+	
+	RememberPageLength: function( name )
+	/*==============================================
+		- stores page length value in a cookie
+		when ChangePageLength method is called
+		- Params:
+			- name: cookie name (string)
+	===============================================*/
+	{
+		tf_WriteCookie(
+			name,
+			this.resultsPerPageSlc.selectedIndex,
+			this.cookieDuration
+		); //writes cookie
+	},
+	
+	ResetValues: function()
+	{ 
+		this.EvtManager(this.Evt.name.resetvalues); 
+	},
+	
+	_ResetValues: function()
+	/*==============================================
+		- re-sets grid values when page is 
+		re-loaded. It invokes ResetGridValues,
+		ResetPage and ResetPageLength methods
+		- Params:
+			- name: cookie name (string)
+	===============================================*/
+	{
+		if(this.rememberGridValues && this.fillSlcOnDemand) //only fillSlcOnDemand
+			this.ResetGridValues(this.fltsValuesCookie);
+		if(this.rememberPageLen) this.ResetPageLength( this.pgLenCookie );
+		if(this.rememberPageNb) this.ResetPage( this.pgNbCookie );		
+	},	
+	
+	ResetGridValues: function( name )
+	/*==============================================
+		- re-sets filters' values when page is 
+		re-loaded if load on demand is enabled
+		- Params:
+			- name: cookie name (string)
+		- credits to Florent Hirchy
+	===============================================*/
+	{
+		if(!this.fillSlcOnDemand) return;
+		var flts = tf_ReadCookie(name); //reads the cookie
+		var reg = new RegExp(',','g');	
+		var flts_values = flts.split(reg); //creates an array with filters' values
+		var slcFltsIndex = this.GetFiltersByType(this.fltTypeSlc, true);
+		var multiFltsIndex = this.GetFiltersByType(this.fltTypeMulti, true);
+		
+		if(flts_values[(flts_values.length-1)] == this.fltIds.length)
+		{//if the number of columns is the same as before page reload
+			for(var i=0; i<(flts_values.length - 1); i++)
+			{			
+				if (flts_values[i]==' ') continue;				
+				if(this['col'+i]==this.fltTypeSlc || this['col'+i]==this.fltTypeMulti)
+				{// if fillSlcOnDemand, drop-down needs to contain stored value(s) for filtering
+					var slc = tf_Id( this.fltIds[i] );
+					slc.options[0].selected = false;
+					
+					if( slcFltsIndex.tf_Has(i) )
+					{//selects
+						var opt = tf_CreateOpt(flts_values[i],flts_values[i],true);
+						slc.appendChild(opt);
+						this.hasStoredValues = true;
+					}
+					if(multiFltsIndex.tf_Has(i))
+					{//multiple select
+						var s = flts_values[i].split(' '+this.orOperator+' ');
+						for(j=0; j<s.length; j++)
+						{
+							if(s[j]=='') continue;
+							var opt = tf_CreateOpt(s[j],s[j],true);
+							slc.appendChild(opt);
+							this.hasStoredValues = true;
+							
+							if(tf_isIE)
+							{// IE multiple selection work-around
+								this.__deferMultipleSelection(slc,j,false);
+								hasStoredValues = false;
+							}
+						}
+					}// if multiFltsIndex
+				}
+				else if(this['col'+i]==this.fltTypeCheckList)
+				{
+					var divChk = this.checkListDiv[i];
+					divChk.title = divChk.innerHTML;
+					divChk.innerHTML = '';
+					
+					var ul = tf_CreateElm('ul',['id',this.fltIds[i]],['colIndex',i]);
+					ul.className = this.checkListCssClass;
+
+					var li0 = tf_CreateCheckItem(this.fltIds[i]+'_0', '', this.displayAllText);
+					li0.className = this.checkListItemCssClass;
+					ul.appendChild(li0);
+
+					divChk.appendChild(ul);
+					
+					var s = flts_values[i].split(' '+this.orOperator+' ');
+					for(j=0; j<s.length; j++)
+					{
+						if(s[j]=='') continue;
+						var li = tf_CreateCheckItem(this.fltIds[i]+'_'+(j+1), s[j], s[j]);
+						li.className = this.checkListItemCssClass;
+						ul.appendChild(li);
+						li.check.checked = true;
+						this.__setCheckListValues(li.check);
+						this.hasStoredValues = true;
+					}					
+				}
+			}//end for
+			
+			if(!this.hasStoredValues && this.paging) this.SetPagingInfo();
+		}//end if
+	},
+	
+	ResetPage: function( name )
+	{
+		this.EvtManager(this.Evt.name.resetpage);
+	},
+	_ResetPage: function( name )
+	/*==============================================
+		- re-sets page nb at page re-load
+		- Params:
+			- name: cookie name (string)
+	===============================================*/
+	{
+		var pgnb = tf_ReadCookie(name); //reads the cookie
+		if( pgnb!='' ) 
+			this.ChangePage((pgnb-1));
+	},
+	
+	ResetPageLength: function( name )
+	{
+		this.EvtManager(this.Evt.name.resetpagelength);
+	},
+	_ResetPageLength: function( name )
+	/*==============================================
+		- re-sets page length at page re-load
+		- Params:
+			- name: cookie name (string)
+	===============================================*/
+	{
+		if(!this.paging) return;
+		var pglenIndex = tf_ReadCookie(name); //reads the cookie
+		
+		if( pglenIndex!='' )
+		{
+			this.resultsPerPageSlc.options[pglenIndex].selected = true;
+			this.ChangeResultsPerPage();
+		}
+	},
+	
+	SetLoader: function()
+	/*====================================================
+		- generates loader div
+	=====================================================*/
+	{
+		if( this.loaderDiv!=null ) return;
+		var containerDiv = tf_CreateElm( 'div',['id',this.prfxLoader+this.id] );
+		containerDiv.className = this.loaderCssClass;// for ie<=6
+		//containerDiv.style.display = 'none';
+		var targetEl = (this.loaderTgtId==null) 
+			? (this.gridLayout ? this.tblCont : this.tbl.parentNode) : tf_Id( this.loaderTgtId );
+		if(this.loaderTgtId==null) targetEl.insertBefore(containerDiv, this.tbl);
+		else targetEl.appendChild( containerDiv );
+		this.loaderDiv = tf_Id(this.prfxLoader+this.id);
+		if(this.loaderHtml==null) 
+			this.loaderDiv.appendChild( tf_CreateText(this.loaderText) );
+		else this.loaderDiv.innerHTML = this.loaderHtml;
+	},
+	
+	RemoveLoader: function()
+	/*====================================================
+		- removes loader div
+	=====================================================*/
+	{
+		if( this.loaderDiv==null ) return;
+		var targetEl = (this.loaderTgtId==null) 
+			? (this.gridLayout ? this.tblCont : this.tbl.parentNode) : tf_Id( this.loaderTgtId );
+		targetEl.removeChild(this.loaderDiv);
+		this.loaderDiv = null;
+	},
+	
+	ShowLoader: function(p)
+	/*====================================================
+		- displays/hides loader div
+	=====================================================*/
+	{
+		if(!this.loader || !this.loaderDiv) return;
+		if(this.loaderDiv.style.display==p) return;
+		var o = this;
+
+		function displayLoader(){ 
+			if(!o.loaderDiv) return;
+			if(o.onShowLoader && p!='none') 
+				o.onShowLoader.call(null,o);
+			o.loaderDiv.style.display = p;
+			if(o.onHideLoader && p=='none') 
+				o.onHideLoader.call(null,o);
+		}
+
+		var t = (p=='none') ? this.loaderCloseDelay : 1;
+		window.setTimeout(displayLoader,t);
+	},
+	
+	StatusMsg: function(t)
+	/*====================================================
+		- sets status messages
+	=====================================================*/
+	{
+		if(t==undefined) this.StatusMsg('');
+		if(this.status) this.WinStatusMsg(t);
+		if(this.statusBar) this.StatusBarMsg(t);
+	},
+	
+	StatusBarMsg: function(t)
+	/*====================================================
+		- sets status bar messages
+	=====================================================*/
+	{
+		if(!this.statusBar || !this.statusBarSpan) return;
+		var o = this;
+		function setMsg(){
+			o.statusBarSpan.innerHTML = t;
+		}
+		var d = (t=='') ? (this.statusBarCloseDelay) : 1;
+		window.setTimeout(setMsg,d);
+	},
+	
+	WinStatusMsg: function(t)
+	/*====================================================
+		- sets window status messages
+	=====================================================*/
+	{
+		if(!this.status) return;
+		window.status = t;
+	},
+	
+	ClearFilters: function()
+	{ 
+		this.EvtManager(this.Evt.name.clear); 
+	},	
+	_ClearFilters: function()
+	/*====================================================
+		- clears grid filters
+	=====================================================*/
+	{
+		if( !this.fltGrid ) return;
+		for(var i=0; i<this.fltIds.length; i++)
+			this.SetFilterValue(i,'');
+		if(this.refreshFilters){
+			this.activeFilterId = '';	
+			this.RefreshFiltersGrid();
+		}
+		if(this.rememberPageLen) tf_RemoveCookie(this.pgLenCookie);
+		if(this.rememberPageNb) tf_RemoveCookie(this.pgNbCookie);
+	},
+	
+	UnhighlightAll: function()
+	/*====================================================
+		- removes keyword highlighting
+	=====================================================*/
+	{
+		if( this.highlightKeywords && this.searchArgs!=null )
+			for(var y=0; y<this.searchArgs.length; y++)
+				tf_UnhighlightWord( 
+					this.tbl,this.searchArgs[y],
+					this.highlightCssClass 
+				);
+	},
+	
+	RefreshGrid: function()
+	/*====================================================
+		- Re-generates filters grid
+	=====================================================*/
+	{
+		this.RemoveGrid();
+		setFilterGrid(this.id, this.startRow, this.fObj);
+	},
+	
+	__resetGrid: function()
+	/*====================================================
+		- Only used by AddGrid() method
+		- Resets filtering grid bar if previously removed
+	=====================================================*/
+	{
+		if( this.isFirstLoad ) return;
+		
+		// grid was removed, grid row element is stored in this.fltGridEl property
+		this.tbl.rows[this.filtersRowIndex].parentNode.insertBefore( 
+			this.fltGridEl,
+			this.tbl.rows[this.filtersRowIndex]
+		);
+		
+		if( this.isExternalFlt )
+		{// filters are appended in external placeholders elements
+			for(var ct=0; ct<this.externalFltTgtIds.length; ct++ )
+				if( tf_Id(this.externalFltTgtIds[ct]) )
+					tf_Id(this.externalFltTgtIds[ct]).appendChild(this.externalFltEls[ct]);
+		}
+		
+		this.nbFilterableRows = this.GetRowsNb();
+		this.nbVisibleRows = this.nbFilterableRows;
+		this.nbRows = this.tbl.rows.length;
+		this.sort = true;
+		
+		/*** 	ie bug work-around, filters need to be re-generated
+				since row is empty; insertBefore method doesn't seem to work properly 
+				with previously generated DOM nodes modified by innerHTML 	***/
+		if( this.tbl.rows[this.filtersRowIndex].innerHTML=='' )
+		{
+			this.tbl.deleteRow(this.filtersRowIndex);
+			this.RemoveGrid();
+			this.RemoveExternalFlts();
+			this.fltIds = [];
+			this.isFirstLoad = true;
+			this.AddGrid();
+			
+		}
+		
+		this.hasGrid = true;
+	},
+	
+	__deferMultipleSelection: function(slc,index,filter)
+	/*====================================================
+		- IE bug: it seems there is no way to make 
+		multiple selections programatically, only last 
+		selection is kept (multiple select previously 
+		populated via DOM)
+		- Turn-around: defer selection with a setTimeout
+		If you find an alternative elegant solution to 
+		this let me know ;-)
+		- For the moment only this solution seems 
+		to work!
+		- Params: 
+			- slc = select object (select obj)
+			- index to be selected (integer)
+			- execute filtering (boolean)
+	=====================================================*/
+	{
+		if(slc.nodeName.tf_LCase() != 'select') return;
+		var doFilter = (filter==undefined) ? false : filter;
+		var o = this;
+		window.setTimeout(
+			function(){
+				slc.options[0].selected = false;
+				
+				if(slc.options[index].value=='') 
+					slc.options[index].selected = false;
+				else
+				slc.options[index].selected = true; 
+				if(doFilter) o.Filter();
+			},
+			.1
+		);
+	},
+	
+	__getCustomValues: function(colIndex)
+	/*====================================================
+		- Returns an array [[values],[texts]] with 
+		custom values for a given filter
+		- Param: column index (integer)
+	=====================================================*/
+	{
+		if(colIndex==undefined) return;
+		var isCustomSlc = (this.hasCustomSlcOptions  //custom select test
+							&& this.customSlcOptions.cols.tf_Has(colIndex));
+		if(!isCustomSlc) return;
+		var optTxt = [], optArray = [];
+		var index = this.customSlcOptions.cols.tf_IndexByValue(colIndex);
+		var slcValues = this.customSlcOptions.values[index];
+		var slcTexts = this.customSlcOptions.texts[index];
+		var slcSort = this.customSlcOptions.sorts[index];
+		for(var r=0; r<slcValues.length; r++)
+		{
+			optArray.push(slcValues[r]);
+			if(slcTexts[r]!=undefined)
+				optTxt.push(slcTexts[r]);
+			else
+				optTxt.push(slcValues[r]);
+		}
+		if(slcSort)
+		{
+			optArray.sort();
+			optTxt.sort();
+		}
+		return [optArray,optTxt];
+	},
+	
+	__setCheckListValues: function(o)
+	/*====================================================
+		- Sets checked items information of a checklist
+	=====================================================*/
+	{
+		if(o==null) return;
+		var chkValue = o.value; //checked item value
+		var chkIndex = parseInt(o.id.split('_')[2]);
+		var filterTag = 'ul', itemTag = 'li';
+		var n = o;
+		
+		//ul tag search
+		while(n.nodeName.tf_LCase() != filterTag)
+			n = n.parentNode;
+
+		if(n.nodeName.tf_LCase() != filterTag) return;
+		
+		var li = n.childNodes[chkIndex];
+		var colIndex = n.getAttribute('colIndex');
+		var fltValue = n.getAttribute('value'); //filter value (ul tag)
+		var fltIndexes = n.getAttribute('indexes'); //selected items (ul tag)
+
+		if(o.checked)		
+		{
+			if(chkValue=='')
+			{//show all item
+				if((fltIndexes!=null && fltIndexes!=''))
+				{
+					var indSplit = fltIndexes.split(this.separator);//items indexes
+					for(var u=0; u<indSplit.length; u++)
+					{//checked items loop
+						var cChk = tf_Id(this.fltIds[colIndex]+'_'+indSplit[u]); //checked item
+						if(cChk)
+						{ 
+							cChk.checked = false;
+							tf_removeClass(
+								n.childNodes[indSplit[u]],
+								this.checkListSlcItemCssClass
+							);
+						}
+					}
+				}
+				n.setAttribute('value', '');
+				n.setAttribute('indexes', '');
+				
+			} else {
+				fltValue = (fltValue) ? fltValue : '';
+				chkValue = (fltValue+' '+chkValue +' '+this.orOperator).tf_Trim();
+				chkIndex = fltIndexes + chkIndex + this.separator;
+				n.setAttribute('value', chkValue );
+				n.setAttribute('indexes', chkIndex);
+				//1st option unchecked
+				if(tf_Id(this.fltIds[colIndex]+'_0'))
+					tf_Id(this.fltIds[colIndex]+'_0').checked = false; 
+			}
+			
+			if(li.nodeName.tf_LCase() == itemTag)
+			{
+				tf_removeClass(n.childNodes[0],this.checkListSlcItemCssClass);
+				tf_addClass(li,this.checkListSlcItemCssClass);
+			}
+		} else { //removes values and indexes
+			if(chkValue!='')
+			{
+				var replaceValue = new RegExp(tf_RegexpEscape(chkValue+' '+this.orOperator));
+				fltValue = fltValue.replace(replaceValue,'');
+				n.setAttribute('value', fltValue);
+				
+				var replaceIndex = new RegExp(tf_RegexpEscape(chkIndex + this.separator));
+				fltIndexes = fltIndexes.replace(replaceIndex,'');
+				n.setAttribute('indexes', fltIndexes);
+			}
+			if(li.nodeName.tf_LCase() == itemTag)
+				tf_removeClass(li,this.checkListSlcItemCssClass);
+		}
+			
+	},
+	
+	__containsStr: function(arg,data,fltType,forceMatch)
+	/*==============================================
+		- Checks if data contains searched arg,
+		returns a boolean
+		- Params:
+			- arg: searched string
+			- data: data string
+			- fltType: filter type (string, 
+			exact match by default for selects - 
+			optional)
+			- forceMatch: boolean forcing exact
+			match (optional)
+	===============================================*/
+	{
+		// Improved by Cedric Wartel (cwl)
+		// automatic exact match for selects and special characters are now filtered
+		var regexp;
+		var modifier = (this.matchCase) ? 'g' : 'gi';
+		var exactMatch = (forceMatch==undefined) ? this.exactMatch : forceMatch;
+		if(exactMatch || (fltType!=this.fltTypeInp && fltType!=undefined))//Váry Péter's patch
+			regexp = new RegExp('(^\\s*)'+tf_RegexpEscape(arg)+'(\\s*$)', modifier);							
+		else
+			regexp = new RegExp(tf_RegexpEscape(arg), modifier);
+		return regexp.test(data);
+	},
+	
+	IncludeFile: function(fileId, filePath, callback, type)
+	{
+		var ftype = (type==undefined) ? 'script' : type;
+		var isImported = tf_isImported(filePath, ftype);
+		if( isImported ) return;
+		
+		var o = this, isLoaded = false, file;			
+		var head = tf_Tag(document,'head')[0];
+		
+		if(ftype.tf_LCase() == 'link')
+			file = tf_CreateElm(
+						'link', ['id',fileId], ['type','text/css'],
+						['rel','stylesheet'], ['href',filePath]
+					);
+		else
+			file = tf_CreateElm(
+						'script', ['id',fileId], 
+						['type','text/javascript'], ['src',filePath]
+					);
+
+		file.onload = file.onreadystatechange = function()
+		{
+			if (!isLoaded && 
+				(!this.readyState || this.readyState == 'loaded' || this.readyState == 'complete')) 
+			{
+				isLoaded = true;
+				if (typeof callback === 'function')
+					callback(o);
+			}
+		}
+		head.appendChild(file);
+	},
+	
+	/*====================================================
+		- Additional public methods for developers
+	=====================================================*/
+	
+	HasGrid: function()
+	/*====================================================
+		- checks if table has a filter grid
+		- returns a boolean
+	=====================================================*/
+	{
+		return this.hasGrid;
+	},
+	
+	GetFiltersId: function()
+	/*====================================================
+		- returns an array containing filters ids
+		- Note that hidden filters are also returned
+	=====================================================*/
+	{
+		if( !this.hasGrid ) return;
+		return this.fltIds;
+	},
+	
+	GetValidRowsIndex: function()
+	/*====================================================
+		- returns an array containing valid rows indexes 
+		(valid rows upon filtering)
+	=====================================================*/
+	{
+		if( !this.hasGrid ) return;
+		return this.validRowsIndex;
+	},
+	
+	GetFiltersRowIndex: function()
+	/*====================================================
+		- Returns the index of the row containing the 
+		filters
+	=====================================================*/
+	{
+		if( !this.hasGrid ) return;
+		return this.filtersRowIndex;
+	},
+	
+	GetHeadersRowIndex: function()
+	/*====================================================
+		- Returns the index of the headers row
+	=====================================================*/
+	{
+		if( !this.hasGrid ) return;
+		return this.headersRow;
+	},
+	
+	GetStartRowIndex: function()
+	/*====================================================
+		- Returns the index of the row from which will 
+		start the filtering process (1st filterable row)
+	=====================================================*/
+	{
+		if( !this.hasGrid ) return;
+		return this.refRow;
+	},
+	
+	GetLastRowIndex: function()
+	/*====================================================
+		- Returns the index of the last row
+	=====================================================*/
+	{
+		if( !this.hasGrid ) return;
+		return (this.nbRows-1);
+	},
+	
+	AddPaging: function(filterTable)
+	/*====================================================
+		- Adds paging feature if filter grid bar is 
+		already set
+		- Param(s):
+			- execFilter: if true table is filtered 
+			(boolean)
+	=====================================================*/
+	{
+		if( !this.hasGrid || this.paging ) return;
+		this.paging = true; 
+		this.isPagingRemoved = true; 
+		this.SetPaging();
+		if(filterTable) this.Filter();
+	}	
+	
+}
+
+/* --- */
+
+/*====================================================
+	- General TF utility fns below
+=====================================================*/
+
+function tf_GetChildElms(n)
+/*====================================================
+	- checks passed node is a ELEMENT_NODE nodeType=1
+	- removes TEXT_NODE nodeType=3  
+=====================================================*/
+{
+	if(n!=undefined && n.nodeType == 1)
+	{
+		var enfants = n.childNodes;
+		for(var i=0; i<enfants.length; i++)
+		{
+			var child = enfants[i];
+			if(child.nodeType == 3)
+			{ 
+				n.removeChild(child);
+				i = -1;
+			}
+		}
+		return n;	
+	}
+}
+
+function tf_GetNodeText(n)
+/*====================================================
+	- returns text + text of child nodes of a node
+=====================================================*/
+{
+	/*if(n.innerText) return n.innerText.tf_Trim();
+	var s = '';
+	var enfants = n.childNodes;
+	for(var i=0; i<enfants.length; i++)
+	{
+		var child = enfants[i];
+		if(child.nodeType == 3) s+= child.data;
+		else s+= tf_GetNodeText(child).tf_Trim();
+	}*/
+	var s = n.textContent || n.innerText || n.innerHTML.replace(/\<[^<>]+>/g, '');
+	return s.replace(/^\s+/, '').replace(/\s+$/, '');
+
+	return s.tf_Trim();
+}
+
+function tf_isObj(varname)
+/*====================================================
+	- checks if var exists and is an object
+	- returns a boolean
+=====================================================*/
+{
+	var isO = false;
+	if( window[varname] && (typeof window[varname]).tf_LCase()=='object' )
+		isO = true;
+	return isO;
+}
+
+function tf_isFn(fn)
+/*====================================================
+	- checks if passed param is a function
+	- returns a boolean
+=====================================================*/
+{
+	var isFn = false;
+	if(fn && (typeof fn).tf_LCase() == 'function')
+		isFn = true;
+	return isFn;
+}
+
+function tf_Id(id)
+/*====================================================
+	- this is just a getElementById shortcut
+=====================================================*/
+{
+	return document.getElementById( id );
+}
+
+function tf_Tag(o,tagname)
+/*====================================================
+	- this is just a getElementsByTagName shortcut
+=====================================================*/
+{
+	return o.getElementsByTagName( tagname );
+}
+
+function tf_RegexpEscape(s)
+/*====================================================
+	- escapes special characters [\^$.|?*+() 
+	for regexp
+	- Many thanks to Cedric Wartel for this fn
+=====================================================*/
+{
+	// traite les caractères spéciaux [\^$.|?*+()
+	//remplace le carctère c par \c
+	function escape(e)
+	{
+		a = new RegExp('\\'+e,'g');
+		s = s.replace(a,'\\'+e);
+	}
+
+	chars = new Array('\\','[','^','$','.','|','?','*','+','(',')');
+	//for(e in chars) escape(chars[e]); // compatibility issue with prototype
+	for(var e=0; e<chars.length; e++) escape(chars[e]);
+	return s;
+}
+
+function tf_CreateElm(tag)
+/*====================================================
+	- creates an html element with its attributes
+	- accepts the following params:
+		- a string defining the html tag
+		to create
+		- an undetermined # of arrays containing the
+		couple 'attribute name','value' ['id','myId']
+=====================================================*/
+{
+	if(tag==undefined || tag==null || tag=='') return;
+	var el = document.createElement( tag );		
+	if(arguments.length>1)
+	{
+		for(var i=0; i<arguments.length; i++)
+		{
+			var argtype = typeof arguments[i];
+			switch( argtype.tf_LCase() )
+			{
+				case 'object':
+					if( arguments[i].length==2 )
+					{						
+						el.setAttribute( arguments[i][0],arguments[i][1] );
+					}//if array length==2
+				break;
+			}//switch
+		}//for i
+	}//if args
+	return el;	
+}
+
+function tf_CreateText(node)
+/*====================================================
+	- this is just a document.createTextNode shortcut
+=====================================================*/
+{
+	return document.createTextNode( node );
+}
+
+function tf_CreateOpt(text,value,isSel)
+/*====================================================
+	- creates an option element and returns it:
+		- text: displayed text (string)
+		- value: option value (string)
+		- isSel: is selected option (boolean)
+=====================================================*/
+{
+	var isSelected = isSel ? true : false;
+	var opt = (isSelected) 
+		? tf_CreateElm('option',['value',value],['selected','true'])
+		: tf_CreateElm('option',['value',value]);
+	opt.appendChild(tf_CreateText(text));
+	return opt;
+}
+
+function tf_CreateCheckItem(chkIndex, chkValue, labelText)
+/*====================================================
+	- creates an checklist item and returns it
+	- accepts the following params:
+		- chkIndex: index of check item (number)
+		- chkValue: check item value (string)
+		- labelText: check item label text (string)
+=====================================================*/
+{
+	if(chkIndex==undefined || chkValue==undefined || labelText==undefined )
+		return;
+	var li = tf_CreateElm('li');
+	var label = tf_CreateElm('label',['for',chkIndex]);
+	var check = tf_CreateElm( 'input',
+					['id',chkIndex],
+					['name',chkIndex],
+					['type','checkbox'],
+					['value',chkValue] );
+	label.appendChild(check);
+	label.appendChild(tf_CreateText(labelText));
+	li.appendChild(label);
+	li.label = label;
+	li.check = check;
+	return li;
+}
+
+function tf_HighlightWord( node,word,cssClass )
+/*====================================================
+	- highlights keyword found in passed node
+	- accepts the following params:
+		- node
+		- word to search
+		- css class name for highlighting
+=====================================================*/
+{
+	// Iterate into this nodes childNodes
+	if(node.hasChildNodes) 
+		for( var i=0; i<node.childNodes.length; i++ )
+			tf_HighlightWord(node.childNodes[i],word,cssClass);
+
+	// And do this node itself
+	if(node.nodeType == 3) 
+	{ // text node
+		var tempNodeVal = node.nodeValue.tf_LCase();
+		var tempWordVal = word.tf_LCase();
+		if(tempNodeVal.indexOf(tempWordVal) != -1) 
+		{
+			var pn = node.parentNode;
+			if(pn.className != cssClass) 
+			{
+				// word has not already been highlighted!
+				var nv = node.nodeValue;
+				var ni = tempNodeVal.indexOf(tempWordVal);
+				// Create a load of replacement nodes
+				var before = tf_CreateText(nv.substr(0,ni));
+				var docWordVal = nv.substr(ni,word.length);
+				var after = tf_CreateText(nv.substr(ni+word.length));
+				var hiwordtext = tf_CreateText(docWordVal);
+				var hiword = tf_CreateElm('span');
+				hiword.className = cssClass;
+				hiword.appendChild(hiwordtext);
+				pn.insertBefore(before,node);
+				pn.insertBefore(hiword,node);
+				pn.insertBefore(after,node);
+				pn.removeChild(node);
+			}
+		}
+	}// if node.nodeType == 3
+}
+
+function tf_UnhighlightWord( node,word,cssClass )
+/*====================================================
+	- removes highlights found in passed node
+	- accepts the following params:
+		- node
+		- word to search
+		- css class name for highlighting
+=====================================================*/
+{
+	// Iterate into this nodes childNodes
+	if(node.hasChildNodes)
+		for( var i=0; i<node.childNodes.length; i++ )
+			tf_UnhighlightWord(node.childNodes[i],word,cssClass);
+
+	// And do this node itself
+	if(node.nodeType == 3) 
+	{ // text node
+		var tempNodeVal = node.nodeValue.tf_LCase();
+		var tempWordVal = word.tf_LCase();
+		if(tempNodeVal.indexOf(tempWordVal) != -1)
+		{
+			var pn = node.parentNode;
+			if(pn.className == cssClass)
+			{
+				var prevSib = pn.previousSibling;
+				var nextSib = pn.nextSibling;
+				nextSib.nodeValue = prevSib.nodeValue + node.nodeValue + nextSib.nodeValue;
+				prevSib.nodeValue = '';
+				node.nodeValue = '';
+			}
+		}
+	}// if node.nodeType == 3
+}
+
+function tf_addEvent(obj,event_name,func_name)
+{
+	if (obj.attachEvent)
+		obj.attachEvent('on'+event_name, func_name);
+	else if(obj.addEventListener)
+		obj.addEventListener(event_name,func_name,true);
+	else
+		obj['on'+event_name] = func_name;
+}
+
+function tf_removeEvent(obj,event_name,func_name)
+{
+	if (obj.detachEvent)
+		obj.detachEvent('on'+event_name,func_name);
+	else if(obj.removeEventListener)
+		obj.removeEventListener(event_name,func_name,true);
+	else
+		obj['on'+event_name] = null;
+}
+
+function tf_NumSortAsc(a, b){ return (a-b); }
+
+function tf_NumSortDesc(a, b){ return (b-a); }
+
+function tf_IgnoreCaseSort(a, b) {
+	var x = a.tf_LCase();
+	var y = b.tf_LCase();
+	return ((x < y) ? -1 : ((x > y) ? 1 : 0));
+}
+
+String.prototype.tf_MatchCase = function (mc) 
+{
+	if (!mc) return this.tf_LCase();
+	else return this.toString();
+}
+
+String.prototype.tf_Trim = function()
+{//optimised by Anthony Maes
+	return this.replace(/(^[\s\xA0]*)|([\s\xA0]*$)/g,'');
+}
+
+String.prototype.tf_LCase = function()
+{
+	return this.toLowerCase();
+}
+
+String.prototype.tf_UCase = function()
+{
+	return this.toUpperCase();
+}
+
+Array.prototype.tf_Has = function(s,mc) 
+{
+	//return this.indexOf(s) >= 0;
+	var sCase = (mc==undefined) ? false : mc;
+	for (i=0; i<this.length; i++)
+		if (this[i].toString().tf_MatchCase(sCase)==s) return true;
+	return false;
+}
+
+Array.prototype.tf_IndexByValue = function(s,mc) 
+{
+	var sCase = (mc==undefined) ? false : mc;
+	for (i=0; i<this.length; i++)
+		if (this[i].toString().tf_MatchCase(sCase)==s) return i;
+	return (-1);
+}
+
+// Is this IE 6? the ultimate browser sniffer ;-)
+//window['tf_isIE'] = (window.innerHeight) ? false : true;
+window['tf_isIE'] = (window.innerHeight) ? false : /msie|MSIE 6/.test(navigator.userAgent) ? true : false;
+window['tf_isIE7'] = (window.innerHeight) ? false : /msie|MSIE 7/.test(navigator.userAgent) ? true : false;
+
+function tf_hasClass(elm,cl) 
+{
+	return elm.className.match(new RegExp('(\\s|^)'+cl+'(\\s|$)'));
+}
+
+function tf_addClass(elm,cl) 
+{
+	if (!tf_hasClass(elm,cl))
+		elm.className += ' '+cl;
+}
+
+function tf_removeClass(elm,cl) 
+{
+	if ( !tf_hasClass(elm,cl) ) return;
+	var reg = new RegExp('(\\s|^)'+cl+'(\\s|$)');
+	elm.className = elm.className.replace(reg,' ');
+}
+
+function tf_isValidDate(dateStr, format) 
+{
+	if (format == null) { format = 'DMY'; }
+	format = format.toUpperCase();
+	if (format.length != 3) { format = 'DMY'; }
+	if ( (format.indexOf('M') == -1) || (format.indexOf('D') == -1) ||
+		(format.indexOf('Y') == -1) ) { format = 'DMY'; }
+	if (format.substring(0, 1) == 'Y') { // If the year is first
+		  var reg1 = /^\d{2}(\-|\/|\.)\d{1,2}\1\d{1,2}$/;
+		  var reg2 = /^\d{4}(\-|\/|\.)\d{1,2}\1\d{1,2}$/;
+	} else if (format.substring(1, 2) == 'Y') { // If the year is second
+		  var reg1 = /^\d{1,2}(\-|\/|\.)\d{2}\1\d{1,2}$/;
+		  var reg2 = /^\d{1,2}(\-|\/|\.)\d{4}\1\d{1,2}$/;
+	} else { // The year must be third
+		  var reg1 = /^\d{1,2}(\-|\/|\.)\d{1,2}\1\d{2}$/;
+		  var reg2 = /^\d{1,2}(\-|\/|\.)\d{1,2}\1\d{4}$/;
+	}
+	// If it doesn't conform to the right format (with either a 2 digit year or 4 digit year), fail
+	if ( (reg1.test(dateStr) == false) && (reg2.test(dateStr) == false) ) { return false; }
+	var parts = dateStr.split(RegExp.$1); // Split into 3 parts based on what the divider was
+	// Check to see if the 3 parts end up making a valid date
+	if (format.substring(0, 1) == 'M') { var mm = parts[0]; } else
+		if (format.substring(1, 2) == 'M') { var mm = parts[1]; } else { var mm = parts[2]; }
+	if (format.substring(0, 1) == 'D') { var dd = parts[0]; } else
+		if (format.substring(1, 2) == 'D') { var dd = parts[1]; } else { var dd = parts[2]; }
+	if (format.substring(0, 1) == 'Y') { var yy = parts[0]; } else
+		if (format.substring(1, 2) == 'Y') { var yy = parts[1]; } else { var yy = parts[2]; }
+	if (parseFloat(yy) <= 50) { yy = (parseFloat(yy) + 2000).toString(); }
+	if (parseFloat(yy) <= 99) { yy = (parseFloat(yy) + 1900).toString(); }
+	var dt = new Date(parseFloat(yy), parseFloat(mm)-1, parseFloat(dd), 0, 0, 0, 0);
+	if (parseFloat(dd) != dt.getDate()) { return false; }
+	if (parseFloat(mm)-1 != dt.getMonth()) { return false; }
+	return true;
+}
+
+function tf_formatDate(dateStr, format)
+{
+	if(format==null) format = 'DMY';
+	var oDate, parts;
+	
+	function y2kDate(yr){
+		if(yr == undefined) return 0;
+		if(yr.length>2) return yr;
+		var y;
+		if(yr <= 99 && yr>50) //>50 belong to 1900
+			y = '19' + yr;
+		if(yr<50 || yr =='00') //<50 belong to 2000
+			y = '20' + yr;
+		return y;
+	}
+	
+	switch(format.toUpperCase())
+	{
+		case 'DMY':
+			parts = dateStr.replace(/^(0?[1-9]|[12][0-9]|3[01])([- \/.])(0?[1-9]|1[012])([- \/.])((\d\d)?\d\d)$/,'$1 $3 $5').split(' ');
+			oDate = new Date(y2kDate(parts[2]),parts[1]-1,parts[0]);
+		break;
+		case 'MDY':
+			parts = dateStr.replace(/^(0?[1-9]|1[012])([- \/.])(0?[1-9]|[12][0-9]|3[01])([- \/.])((\d\d)?\d\d)$/,'$1 $3 $5').split(' ');
+			oDate = new Date(y2kDate(parts[2]),parts[0]-1,parts[1]);
+		break;
+		case 'YMD':
+			parts = dateStr.replace(/^((\d\d)?\d\d)([- \/.])(0?[1-9]|1[012])([- \/.])(0?[1-9]|[12][0-9]|3[01])$/,'$1 $4 $6').split(' ');
+			oDate = new Date(y2kDate(parts[0]),parts[1]-1,parts[2]);
+		break;
+		default: //in case format is not correct
+			parts = dateStr.replace(/^(0?[1-9]|[12][0-9]|3[01])([- \/.])(0?[1-9]|1[012])([- \/.])((\d\d)?\d\d)$/,'$1 $3 $5').split(' ');
+			oDate = new Date(y2kDate(parts[2]),parts[1]-1,parts[0]);
+		break;
+	}
+	return oDate;
+}
+
+function tf_removeNbFormat(data,format)
+{
+	if(data==null) return;
+	if(format==null) format = 'us';
+	var n = data;
+	if( format.tf_LCase()=='us' )
+		n =+ n.replace(/[^\d\.-]/g,'');
+	else
+		n =+ n.replace(/[^\d\,-]/g,'').replace(',','.');
+	return n;
+}
+
+function tf_isImported(filePath,type)
+{
+	var isImported = false; 
+	var importType = (type==undefined) ? 'script' : type;
+	var files = tf_Tag(document,importType);
+	for (var i=0; i<files.length; i++)
+	{
+		if(files[i].src == undefined) continue;
+		if(files[i].src.match(filePath))
+		{
+			isImported = true;	
+			break;
+		}
+	}
+	return isImported;
+}
+
+function tf_WriteCookie(name, value, hours)
+{
+	var expire = '';
+	if(hours != null)
+	{
+		expire = new Date((new Date()).getTime() + hours * 3600000);
+		expire = '; expires=' + expire.toGMTString();
+	}
+	document.cookie = name + '=' + escape(value) + expire;
+}
+
+function tf_ReadCookie(name)
+{
+	var cookieValue = '';
+	var search = name + '=';
+	if(document.cookie.length > 0)
+	{ 
+		offset = document.cookie.indexOf(search);
+		if (offset != -1)
+		{ 
+			offset += search.length;
+			end = document.cookie.indexOf(';', offset);
+			if (end == -1) end = document.cookie.length;
+			cookieValue = unescape(document.cookie.substring(offset, end))
+		}
+	}
+	return cookieValue;
+}
+
+function tf_CookieValueArray(name)
+{
+	var val = tf_ReadCookie(name); //reads the cookie
+	var arr = val.split(','); //creates an array with filters' values
+	return arr;
+}
+
+function tf_CookieValueByIndex(name, index)
+{
+	var val = tf_CookieValueArray(name); //reads the cookie
+	return val[index];
+}
+
+function tf_RemoveCookie(name)
+{
+	tf_WriteCookie(name,'',-1);
+}
+/* --- */
+
+/*====================================================
+	- Backward compatibility fns
+=====================================================*/
+function grabEBI(id){ return tf_Id( id ); }
+function grabTag(obj,tagname){ return tf_Tag(obj,tagname); }
+function tf_GetCellText(n){ return tf_GetNodeText(n); }
+function tf_isObject(varname){ return tf_isObj(varname); }
+/* --- */
--- a/configurationengine/source/scripts/tests/__init__.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/tests/__init__.py	Tue Aug 10 14:29:28 2010 +0300
@@ -27,46 +27,16 @@
     Set up everything so that running "python cone_tool.py" finds the ConE
     and plug-in modules.
     """
-    sys.path.append(SOURCE_ROOT)
-    sys.path.append(os.path.join(SOURCE_ROOT, 'testautomation'))
-    
-    # Import the plugin_utils module from plugins/
-    sys.path.append(PLUGIN_SOURCE_ROOT)
-    import plugin_utils
-    del sys.path[-1]
+    from testautomation import plugin_utils
     
     # Collect all needed plug-in source directories (all in 'common')
     plugin_sources = plugin_utils.find_plugin_sources(os.path.join(PLUGIN_SOURCE_ROOT, 'common'))
     plugin_source_paths = [path for path, _ in plugin_sources]
     
-    paths = []
-    paths.append(SOURCE_ROOT)
-    paths.extend(plugin_source_paths)
-    os.environ['PYTHONPATH'] = os.environ.get('PYTHONPATH', '') + ';' + ';'.join(paths)
-    
     # Generate egg-info for the plug-ins if necessary
-    import build_egg_info
+    from testautomation import build_egg_info
     for path in plugin_source_paths:
         build_egg_info.generate_egg_info(path)
 
 _setup()
 
-# Find all unittest_*.py files in this folder
-import re
-__all__ = filter(lambda name: re.match(r'^unittest_.*\.py$', name) != None, os.listdir(ROOT_PATH))
-# Strip .py endings
-__all__ = map(lambda name: name[:-3], __all__)
-
-def collect_suite():  
-    suite = unittest.TestSuite()
-    for test_module in __all__:
-        # Load the test module dynamically and add it to the test suite
-        module = __import__(test_module)
-        suite.addTests(unittest.TestLoader().loadTestsFromModule(module))
-    return suite
-
-def runtests():
-    unittest.TextTestRunner(verbosity=2).run(collect_suite())
-
-if __name__ == '__main__':
-    runtests()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/generation_test_project/base/implml/impl_override_test.templateml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<templateml xmlns="http://www.s60.com/xml/templateml/1" xmlns:xi="http://www.w3.org/2001/XInclude">
+    <output file="impl_override_test_base_layer.txt" encoding="UTF-8">
+        <template>Base layer ({{ feat_tree.BasicSettingTypesTest.IntSetting._value }})</template>
+    </output>
+</templateml>
--- a/configurationengine/source/scripts/tests/generation_test_project/custom/implml/conditional_container.implml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/tests/generation_test_project/custom/implml/conditional_container.implml	Tue Aug 10 14:29:28 2010 +0300
@@ -17,7 +17,7 @@
         </output>
         </templateml>
     </container>
-    
+
     <container condition="${Condition.String}" value="nomatch">
         <!-- Print out the values to a text file -->
         <templateml xmlns="http://www.s60.com/xml/templateml/1">
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/generation_test_project/custom/implml/impl_override_test.templateml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<templateml xmlns="http://www.s60.com/xml/templateml/1" xmlns:xi="http://www.w3.org/2001/XInclude">
+    <output file="impl_override_test.txt" encoding="UTF-8">
+        <template>Custom layer ({{ feat_tree.BasicSettingTypesTest.IntSetting._value }})</template>
+    </output>
+</templateml>
--- a/configurationengine/source/scripts/tests/generation_test_project/custom/implml/missing_file_in_report_test.implml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/tests/generation_test_project/custom/implml/missing_file_in_report_test.implml	Tue Aug 10 14:29:28 2010 +0300
@@ -24,9 +24,9 @@
         -->
         <container>
             <phase name="post"/>
-            <ruleml xmlns="http://www.s60.com/xml/ruleml/2">
-                <rule>True configures TempFeatureMissingFile.Test1 = {% delete_file('output/content/missing_output_file_test1.txt') %}</rule>
-                <rule>True configures TempFeatureMissingFile.Test2 = {% delete_file('output/content/missing_output_file_test2.txt') %}</rule>
+            <ruleml xmlns="http://www.s60.com/xml/ruleml/3">
+                <rule>True configures ${TempFeatureMissingFile.Test1} = {% delete_file('output/content/missing_output_file_test1.txt') %}</rule>
+                <rule>True configures ${TempFeatureMissingFile.Test2} = {% delete_file('output/content/missing_output_file_test2.txt') %}</rule>
                 
                 <eval_globals>
 def delete_file(file):
--- a/configurationengine/source/scripts/tests/generation_test_project/custom/implml/seq_tempvar.implml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/tests/generation_test_project/custom/implml/seq_tempvar.implml	Tue Aug 10 14:29:28 2010 +0300
@@ -1,19 +1,18 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <container xmlns="http://www.symbianfoundation.org/xml/implml/1"
-           xmlns:ruleml="http://www.s60.com/xml/ruleml/2"
+           xmlns:ruleml="http://www.s60.com/xml/ruleml/3"
            xmlns:content="http://www.s60.com/xml/content/1">
     <!-- Temporary sequence feature for storing the list of files to copy -->
     <tempVariableSequence ref="TempFeature2.FilesToCopy">
         <tempVariable ref="FilePath" type="string"/>
     </tempVariableSequence>
-    <settingRefsOverride refsIrrelevant="true"/>
 
     <container>
         <phase name="pre"/>
         <!-- Rule for setting the contents of the file copy list -->
         <ruleml:ruleml>
             <ruleml:eval_globals file="seq_tempvar.py"/>
-            <ruleml:rule>True configures TempFeature2.FilesToCopy = {% get_file_seq() %}</ruleml:rule>
+            <ruleml:rule>True configures ${TempFeature2.FilesToCopy} = {% get_file_seq() %}</ruleml:rule>
         </ruleml:ruleml>
     </container>
 
--- a/configurationengine/source/scripts/tests/generation_test_project/custom/implml/simple_tempvars.implml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/tests/generation_test_project/custom/implml/simple_tempvars.implml	Tue Aug 10 14:29:28 2010 +0300
@@ -8,10 +8,10 @@
     <tempVariable ref="TempFeature.Unused"   type="boolean"  value="false"/>
     
     <!-- Modify the temporary features -->
-    <ruleml xmlns="http://www.s60.com/xml/ruleml/1">
-        <rule>True configures TempFeature.String = TempFeature.String + " and more testing"</rule>
-        <rule>True configures TempFeature.Int = TempFeature.Int + 1</rule>
-        <rule>True configures TempFeature.Real = TempFeature.Real + 0.25</rule>
+    <ruleml xmlns="http://www.s60.com/xml/ruleml/3">
+        <rule>True configures ${TempFeature.String} = ${TempFeature.String} + " and more testing"</rule>
+        <rule>True configures ${TempFeature.Int} = ${TempFeature.Int} + 1</rule>
+        <rule>True configures ${TempFeature.Real} = ${TempFeature.Real} + 0.25</rule>
     </ruleml>
     
     <!-- Print out the values to a text file -->
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/generation_test_project/what_output.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,17 @@
+multiselection.txt
+name_id_mapping_test.txt
+content\template_string_condition_true.txt
+sis\app1.txt
+impl_override_test.txt
+content\invocation_phase_test_common_ns.txt
+content\invocation_phase_test_contentml_ns.txt
+content\missing_output_file_test1.txt
+content\missing_output_file_test2.txt
+test_subdir\output_subdir_test.txt
+overridden_output\output_rootdir_test.txt
+overridden_output\test_subdir\output_rootdir_test.txt
+content\temp_seq_test\invocation_phase_test_2.txt
+content\temp_seq_test\invocation_phase_test_1.txt
+content\simple_tempvars_test.txt
+content\invocation_phase_test_common_ns.txt
+content\invocation_phase_test_contentml_ns.txt
--- a/configurationengine/source/scripts/tests/runtests.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/tests/runtests.py	Tue Aug 10 14:29:28 2010 +0300
@@ -14,8 +14,6 @@
 # Description: 
 #
 
-import __init__
-from testautomation import testcli
-
 if __name__ == '__main__':
-    testcli.run(__init__.collect_suite())
+    import nose
+    nose.core.run(argv=['collector','--include=unittest', '--verbosity=3'])
--- a/configurationengine/source/scripts/tests/scripttest_common.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/tests/scripttest_common.py	Tue Aug 10 14:29:28 2010 +0300
@@ -21,7 +21,7 @@
 if sys.platform == "win32":
     CONE_SCRIPT = "cone.cmd"
 else:
-    CONE_SCRIPT = "cone.sh"
+    CONE_SCRIPT = "cone"
 
 def get_cmd(action):
     """Return the command used to run the ConE sub-action"""
--- a/configurationengine/source/scripts/tests/template.csv	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/tests/template.csv	Tue Aug 10 14:29:28 2010 +0300
@@ -1,2 +1,2 @@
-{% for feat in rep_data.ref_noimpl %}{{ feat.ref }}
+{% for feat in merged_context.features.get_features(merged_context.get_refs_with_no_output()) %}{{ feat.fqr }}
 {% endfor %}
\ No newline at end of file
--- a/configurationengine/source/scripts/tests/test_template/template2.csv	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/tests/test_template/template2.csv	Tue Aug 10 14:29:28 2010 +0300
@@ -1,2 +1,2 @@
-{% for feat in rep_data.ref_noimpl %}{{ feat.ref }}
+{% for feat in merged_context.features.get_features(merged_context.get_refs_with_no_output()) %}{{ feat.fqr }}
 {% endfor %}
\ No newline at end of file
Binary file configurationengine/source/scripts/tests/test_variant.cpf has changed
--- a/configurationengine/source/scripts/tests/testdata/compare/expected/data_p1r1_vs_p1r4.txt	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/tests/testdata/compare/expected/data_p1r1_vs_p1r4.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -4,7 +4,7 @@
 BasicSettingTypesTest.RealSetting | 3.14 | 3.14567
 BasicSettingTypesTest.SelectionSetting | 1 | 4
 BasicSettingTypesTest.StringSetting | default string | layer 4 string
-Feature2.SequenceSetting | [['1', 'default 1'], ['2', 'default 2']] | [['444', 'layer4 (1)'], ['444', 'layer4 (2)']]
-Feature2.SequenceSetting.IntSubSetting | ['1', '2'] | ['444', '444']
+Feature2.SequenceSetting | [[1, 'default 1'], [2, 'default 2']] | [[444, 'layer4 (1)'], [444, 'layer4 (2)']]
+Feature2.SequenceSetting.IntSubSetting | [1, 2] | [444, 444]
 Feature2.SequenceSetting.StringSubSetting | ['default 1', 'default 2'] | ['layer4 (1)', 'layer4 (2)']
 FileFolderTest.FileSetting.localPath | default_file.txt | layer2_file.txt
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/export/duplicate_root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/2" name="test" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xi="http://www.w3.org/2001/XInclude">
+  <xi:include href="layer1/root.confml"/>
+  <xi:include href="layer2/root.confml"/>
+</configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/export/layer1/confml/duplicate_settings1.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/1" name="test1"  xmlns:xs="http://www.w3.org/2001/XMLSchema">
+    <feature ref="Feature" name="SampleFea">
+        <setting ref="One" name="One" type="string">
+        </setting>
+        <setting ref="Two" name="Two" type="int">
+        </setting>
+        <setting ref="Three" name="Three" type="selection">
+            <option name="1" value="1"/>
+        </setting>
+        <setting ref="NoData" name="No data" type="string">
+        </setting>
+    </feature>
+    
+    
+    <data>
+        <Feature>
+            <One>fo</One>
+            <Two>1</Two>
+            <Three>1</Three>
+        </Feature>
+    </data>
+</configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/export/layer1/content/foo.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,2 @@
+
+fsdafdsa
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/export/layer1/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/2" name="test" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xi="http://www.w3.org/2001/XInclude">
+  <xi:include href="confml/duplicate_settings1.confml"/>
+</configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/export/layer2/confml/duplicate_settings2.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/1" name="test1"  xmlns:xs="http://www.w3.org/2001/XMLSchema">
+    <feature ref="Feature" name="SampleFea">
+        <setting ref="One" name="One new" type="string">
+            <xs:maxLength value="3"/>
+        </setting>
+        <setting ref="Two" name="Two new" type="int">
+            <desc>Testing desc</desc>
+        </setting>
+        <setting ref="Three" name="Three new" type="selection">
+            <option name="FooBar" value="1"/>
+            <option name="Jee" value="2"/>
+            <option name="Man" value="3"/>
+        </setting>
+        <setting ref="NoData" name="No data" type="string">
+        </setting>
+    </feature>
+</configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/export/layer2/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/2" name="test" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xi="http://www.w3.org/2001/XInclude">
+  <xi:include href="confml/duplicate_settings2.confml"/>
+</configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/generate/error_test_project/layer1/implml/rules_with_errors.implml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<container xmlns="http://www.symbianfoundation.org/xml/implml/1">
+    <tempVariable ref="TempFeature.String"   type="string"   value="testing"/>
+    <tempVariable ref="TempFeature.Int"      type="int"      value="500"/>
+    <tempVariable ref="TempFeature.Real"     type="real"     value="1.5"/>
+    <tempVariable ref="TempFeature.Boolean"  type="boolean"  value="true"/>
+    <tempVariable ref="TempFeature.Unused"   type="boolean"  value="false"/>
+    
+    <ruleml xmlns="http://www.s60.com/xml/ruleml/3">
+        <!-- These cause errors -->
+        <rule>configures ${TempFeature.Int} = 6000</rule>
+        <rule>True configures</rule>
+        
+        <!-- These are simply ignored -->
+        <rule/>
+        <rule>foo bar baz ${TempFeature.Int} = 5000</rule>
+        
+        <!-- These should work (they are last in order to make sure that the
+             invalid rules above don't prevent their execution) -->
+        <rule>True configures ${TempFeature.String} = ${TempFeature.String} + " and more testing"</rule>
+        <rule>True configures ${TempFeature.Int} = ${TempFeature.Int} + 1</rule>
+        <rule>True configures ${TempFeature.Real} = ${TempFeature.Real} + 0.25</rule>
+    </ruleml>
+    
+    <templateml xmlns="http://www.s60.com/xml/templateml/1">
+    <output file="rules_with_errors_test.txt" dir="content" encoding="UTF-8">
+<template>
+TempFeature.String:  {{ feat_tree.TempFeature.String._value }}
+TempFeature.Int:     {{ feat_tree.TempFeature.Int._value }}
+TempFeature.Real:    {{ feat_tree.TempFeature.Real._value }}
+TempFeature.Boolean: {{ feat_tree.TempFeature.Boolean._value }}
+</template>
+    </output>
+    </templateml>
+</container>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/generate/error_test_project/layer1/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="ASCII"?>
+<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/1" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="http://www.w3.org/2001/XInclude http://www.s60.com/xml/confml/1#//include" name="Layer 1">
+</confml:configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/generate/error_test_project/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="ASCII"?>
+<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/1" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="http://www.w3.org/2001/XInclude http://www.s60.com/xml/confml/1#//include" name="root">
+  <xi:include href="layer1/root.confml"/>
+</confml:configuration>
\ No newline at end of file
--- a/configurationengine/source/scripts/tests/testdata/generate/expected/content/template_string_condition_true.txt	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/tests/testdata/generate/expected/content/template_string_condition_true.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -1,3 +1,3 @@
 
-TempFeature.String:  testing
+TempFeature.String:  testing and more testing
         
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/generate/expected/impl_override_test.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,1 @@
+Custom layer (555)
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/generate/expected/overridden_output/output_rootdir_test.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,1 @@
+test 1
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/generate/expected/overridden_output/test_subdir/output_rootdir_test.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,1 @@
+test 1
\ No newline at end of file
--- a/configurationengine/source/scripts/tests/testdata/generate/expected_report.html	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/tests/testdata/generate/expected_report.html	Tue Aug 10 14:29:28 2010 +0300
@@ -1,6 +1,7 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
 <html lang="en">
 <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> 
     <title>ConE generation report</title>
     <style type="text/css">
         body {
@@ -110,1589 +111,7009 @@
             font: Tahoma, Verdana, Arial;
             _font-size: 0.8em;
         }
-
+        div.popup  {
+            background-color: #f9fafd;
+            font: #595a5f Tahoma, Verdana, Arial bold;
+            font-size: 0.8em;
+            border-top: 1px #9d9da1;
+            border-bottom: 1px #9d9da1;
+        }
+        div.floater  {
+            text-align: left; 
+            width: 50%; 
+            float: left;
+        }
+        div.floater-right  {
+            text-align: right; 
+            width: 50%; 
+            float: right;
+        }
+        table.log {
+            word-wrap: break-word;
+            border: 1px #EBEBEB;
+            padding: 5px;
+            border-style: solid; 
+            vertical-align: top;
+            font: #595a5f Tahoma, Verdana, Arial;
+            font-size: 0.8em;
+        }
         .currentValue {
             background-color: #e8f2fe;
         }
     </style>
+    <script language="javascript" type="text/javascript">
+    //<![CDATA[
+    /*------------------------------------------------------------------------
+	- HTML Table Filter Generator v1.9.6
+	- By Max Guglielmi (tablefilter.free.fr)
+	- Licensed under the MIT License
+--------------------------------------------------------------------------
+Copyright (c) 2009 Max Guglielmi
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+--------------------------------------------------------------------------
+	- Special credit to: 
+	Cedric Wartel, cnx.claude@free.fr, Florent Hirchy, Váry Péter, 
+	Anthony Maes, Nuovella Williams, Fuggerbit, Venkata Seshagiri Rao 
+	Raya for active contribution and inspiration
+------------------------------------------------------------------------*/
+
+function setFilterGrid(id)
+/*====================================================
+	- Sets filters grid bar
+	- Calls TF Constructor and generates grid bar
+	- Params:
+			- id: table id (string)
+			- refRow (optional): row index (number)
+			- config (optional): configuration 
+			object (literal object)
+=====================================================*/
+{
+	if( arguments.length==0 ) return;
+	eval( 'tf_'+id+' = new TF(arguments[0],arguments[1],arguments[2])' );
+	eval( 'tf_'+id+'.AddGrid();' );
+}
+
+/*===BEGIN removable section===========================
+	- Unobtrusive grid bar generation using 
+	'filterable' class
+	- If you don't use it you can remove safely this 
+	section
+/*=====================================================*/
+tf_addEvent(window, 'load', initFilterGrid);
+
+function initFilterGrid()
+{
+	if (!document.getElementsByTagName) return;
+	var tbls = tf_Tag(document,'table'), config;
+	for (var i=0; i<tbls.length; i++)
+	{
+		var cTbl = tbls[i], cTblId = cTbl.getAttribute('id');
+		if( tf_hasClass(cTbl,'filterable') && cTblId )
+		{
+			if( tf_isObj(cTblId+'_config') )
+				config = eval(cTblId+'_config');
+			else
+				config = undefined;
+			setFilterGrid( cTblId,config );
+		}
+	}// for i
+}
+/*===END removable section===========================*/
+
+var TF = function( id )
+/*====================================================
+	- TF object constructor
+	- Params:
+			- id: table id (string)
+			- refRow (optional): row index (number)
+			- config (optional): configuration 
+			object (literal object)
+=====================================================*/
+{
+	if( arguments.length==0 ) return;
+		
+	this.id = id;
+	this.tbl = tf_Id(id);
+	this.startRow = undefined;
+	this.refRow = null;
+	this.headersRow = null;
+	this.fObj = null;
+	this.nbFilterableRows = null;
+	this.nbRows = null;
+	this.nbCells = null;
+	this.hasGrid = false;
+	
+	if(this.tbl != null && this.tbl.nodeName.tf_LCase() == 'table' && this.GetRowsNb())
+    {
+		if(arguments.length>1)
+        {
+            for(var i=0; i<arguments.length; i++)
+            {
+                var argtype = typeof arguments[i];
+               
+                switch(argtype.tf_LCase())
+                {
+                    case 'number':
+                        this.startRow = arguments[i];
+                    break;
+                    case 'object':
+                        this.fObj = arguments[i];
+                    break;
+                }//switch                           
+            }//for
+        }//if
+		
+		var f = this.fObj;
+		
+		/*** filter types ***/
+		this.fltTypeInp =			'input';
+		this.fltTypeSlc =			'select';
+		this.fltTypeMulti =			'multiple';
+		this.fltTypeCheckList =		'checklist';
+		this.fltTypeNone =			'none';
+		
+		/*** filters' grid properties ***/
+		this.fltGrid = 				f!=undefined && f.grid==false ? false : true; //enables/disables filter grid
+		
+		/*** Grid layout ***/
+		this.gridLayout = 			f!=undefined && f.grid_layout ? true : false; //enables/disables grid layout (fixed headers)
+		this.gridWidth =			f!=undefined && f.grid_width!=undefined ? f.grid_width : null; //defines grid width
+		this.gridHeight =			f!=undefined && f.grid_height!=undefined ? f.grid_height : null; //defines grid height
+		this.gridMainContCssClass = f!=undefined && f.grid_cont_css_class!=undefined //defines css class for main container
+										? f.grid_cont_css_class : 'grd_Cont';
+		this.gridContCssClass =		f!=undefined && f.grid_tbl_cont_css_class!=undefined //defines css class for div containing table
+										? f.grid_tbl_cont_css_class : 'grd_tblCont';
+		this.gridHeadContCssClass = f!=undefined && f.grid_tblHead_cont_css_class!=undefined //defines css class for div containing headers' table
+										? f.grid_tblHead_cont_css_class : 'grd_headTblCont';
+		this.gridInfDivCssClass =	f!=undefined && f.grid_inf_grid_css_class!=undefined //defines css class for div containing rows counter, paging etc.
+										? f.grid_inf_grid_css_class : 'grd_inf';
+		this.gridHeadRowIndex =		f!=undefined && f.grid_headers_row_index!=undefined //defines which row contains column headers
+										? f.grid_headers_row_index : 0; 
+		this.gridHeadRows =			f!=undefined && f.grid_headers_rows!=undefined //array of headers row indexes to be placed in header table
+										? f.grid_headers_rows : [0];
+		this.gridEnableFilters =	f!=undefined && f.grid_enable_default_filters!=undefined 
+										? f.grid_enable_default_filters : true; //generate filters in table headers
+		this.gridDefaultColWidth =	f!=undefined && f.grid_default_col_width!=undefined 
+										? f.grid_default_col_width : '100px'; //default col width						
+		this.gridEnableColResizer =	f!=undefined && f.grid_enable_cols_resizer!=undefined 
+										? f.grid_enable_cols_resizer : true; //enables/disables columns resizer
+		this.hasGridWidthsRow =		false; //flag indicating if the grid has an additional row for column widths (IE<=7)
+		this.gridColElms =			[];
+		this.sourceTblHtml = 		this.tbl.outerHTML; //original table html												
+		/*** ***/
+								
+		this.filtersRowIndex =		f!=undefined && f.filters_row_index!=undefined //defines in which row filters grid bar is generated
+										? f.filters_row_index>1 ? 1 : f.filters_row_index : 0;
+		this.fltCellTag =			f!=undefined && f.filters_cell_tag!=undefined //defines tag of the cells containing filters (td/th)
+										? (f.filters_cell_tag!='th' ? 'td' : 'th') : 'td';		
+		this.fltIds = 				[]; //stores filters ids
+		this.searchArgs =			null; //stores filters values
+		this.tblData =				[]; //stores table data
+		this.validRowsIndex =		null; //stores valid rows indexes (rows visible upon filtering)
+		this.fltGridEl =			null; //stores filters row element
+		this.isFirstLoad =			true; //is first load boolean 
+		this.infDiv =				null; //container div for paging elements, reset btn etc.
+		this.lDiv =					null; //div for rows counter
+		this.rDiv =					null; //div for reset button and results per page select
+		this.mDiv =					null; //div for paging elements
+		this.contDiv =				null; //table container div for fixed headers (IE only)
+		this.infDivCssClass =		f!=undefined && f.inf_div_css_class!=undefined	//defines css class for div containing
+										? f.inf_div_css_class : 'inf';				//paging elements, rows counter etc.
+		this.lDivCssClass =			f!=undefined && f.left_div_css_class!=undefined	//defines css class for left div 
+										? f.left_div_css_class : 'ldiv';
+		this.rDivCssClass =			f!=undefined && f.right_div_css_class!=undefined //defines css class for right div 
+										? f.right_div_css_class : 'rdiv';
+		this.mDivCssClass =			f!=undefined && f.middle_div_css_class!=undefined //defines css class for mid div 
+										? f.middle_div_css_class : 'mdiv';
+		this.contDivCssClass =		f!=undefined && f.content_div_css_class!=undefined 
+										? f.content_div_css_class : 'cont';	//table container div css class
+		
+		/*** filters' grid appearance ***/
+		this.fltsRowCssClass =		f!=undefined && f.flts_row_css_class!=undefined //defines css class for filters row
+										? f.flts_row_css_class : 'fltrow';		
+		this.alternateBgs =			f!=undefined && f.alternate_rows ? true : false; //enables/disbles rows alternating bg colors
+		this.hasColWidth =			f!=undefined && f.col_width ? true : false; //defines widths of columns
+		this.colWidth =				f!=undefined && this.hasColWidth ? f.col_width : null;
+		this.fixedHeaders =			f!=undefined && f.fixed_headers ? true : false; //enables/disables fixed headers
+		this.tBodyH = 				f!=undefined && f.tbody_height ? f.tbody_height : 200; //tbody height if fixed headers enabled
+		this.fltCssClass =			f!=undefined && f.flt_css_class!=undefined //defines css class for filters
+										? f.flt_css_class : 'flt';
+		this.fltMultiCssClass =		f!=undefined && f.flt_multi_css_class!=undefined //defines css class for multiple selects filters
+										? f.flt_multi_css_class : 'flt_multi';
+		this.fltSmallCssClass =		f!=undefined && f.flt_small_css_class!=undefined //defines css class for filters
+										? f.flt_small_css_class : 'flt_s';
+		this.singleFltCssClass =	f!=undefined && f.single_flt_css_class!=undefined //defines css class for single-filter
+										? f.single_flt_css_class : 'single_flt';	
+		this.isStartBgAlternate =	true;
+		this.rowBgEvenCssClass =	f!=undefined && f.even_row_css_class!=undefined //defines css class for even rows
+										? f.even_row_css_class :'even';
+		this.rowBgOddCssClass =		f!=undefined && f.odd_row_css_class!=undefined //defines css class for odd rows
+										? f.odd_row_css_class :'odd';
+		
+		/*** filters' grid behaviours ***/
+		this.enterKey =				f!=undefined && f.enter_key==false ? false : true; //enables/disables enter key
+		this.isModFilterFn = 		f!=undefined && f.mod_filter_fn ? true : false; //enables/disables alternative fn call		
+		this.modFilterFn =			this.isModFilterFn ? f.mod_filter_fn : null;// used by tf_DetectKey fn
+		this.onBeforeFilter =		f!=undefined && tf_isFn(f.on_before_filter) //calls function before filtering starts
+										? f.on_before_filter : null;
+		this.onAfterFilter =		f!=undefined && tf_isFn(f.on_after_filter) //calls function after filtering
+										? f.on_after_filter : null;								
+		this.matchCase =			f!=undefined && f.match_case ? true : false; //enables/disables case sensitivity
+		this.exactMatch =			f!=undefined && f.exact_match ? true : false; //enables/disbles exact match for search
+		this.refreshFilters =		f!=undefined && f.refresh_filters ? true : false; //refreshes drop-down lists upon validation
+		this.activeFlt =			null; //stores active filter element
+		this.activeFilterId =		null; //id of active filter
+		this.hasColOperation =		f!=undefined && f.col_operation ? true : false; //enables/disbles column operation(sum,mean)
+		this.colOperation =			null;
+		this.hasVisibleRows = 		f!=undefined && f.rows_always_visible ? true : false; //enables always visible rows
+		this.visibleRows =			this.hasVisibleRows ? f.rows_always_visible : [];//array containing always visible rows
+		this.searchType =			f!=undefined && f.search_type!=undefined //defines search type: include or exclude
+										? f.search_type : 'include';
+		this.isExternalFlt =		f!=undefined && f.external_flt_grid ? true : false; //enables/disables external filters generation
+		this.externalFltTgtIds =	f!=undefined && f.external_flt_grid_ids!=undefined //array containing ids of external elements containing filters
+										? f.external_flt_grid_ids : null;
+		this.externalFltEls =		[]; //stores filters elements if isExternalFlt is true		
+		this.execDelay =			f!=undefined && f.exec_delay ? parseInt(f.exec_delay) : 100; //delays filtering process if loader true
+		this.status =				f!=undefined && f.status ? true : false; //enables/disables status messages
+		this.onFiltersLoaded =		f!=undefined && tf_isFn(f.on_filters_loaded) //calls function when filters grid loaded
+										? f.on_filters_loaded : null;
+		this.singleSearchFlt =		f!=undefined && f.single_search_filter ? true : false; //enables/disables single filter search
+		this.onRowValidated =		f!=undefined && tf_isFn(f.on_row_validated) //calls function after row is validated
+									 	? f.on_row_validated : null;
+		this.customCellDataCols =	f!=undefined && f.custom_cell_data_cols ? f.custom_cell_data_cols : []; //array defining columns for customCellData event 	
+		this.customCellData =		f!=undefined && tf_isFn(f.custom_cell_data) //calls custom function for retrieving cell data
+									 	? f.custom_cell_data : null;																
+		
+		/*** selects customisation and behaviours ***/
+		this.displayAllText =		f!=undefined && f.display_all_text!=undefined ? f.display_all_text : ''; //defines 1st option text
+		this.onSlcChange = 			f!=undefined && f.on_change==false ? false : true; //enables/disables onChange event on combo-box 
+		this.sortSlc =				f!=undefined && f.sort_select==false ? false : true; //enables/disables select options sorting
+		this.isSortNumAsc =			f!=undefined && f.sort_num_asc ? true : false; //enables/disables ascending numeric options sorting
+		this.sortNumAsc =			this.isSortNumAsc ? f.sort_num_asc : null;
+		this.isSortNumDesc =		f!=undefined && f.sort_num_desc ? true : false; //enables/disables descending numeric options sorting
+		this.sortNumDesc =			this.isSortNumDesc ? f.sort_num_desc : null;
+		this.slcFillingMethod =		f!=undefined && f.slc_filling_method!=undefined //sets select filling method: 'innerHTML' or 
+										? f.slc_filling_method : 'createElement';	//'createElement'
+		this.fillSlcOnDemand =		f!=undefined && f.fill_slc_on_demand ? true : false; //enabled selects are populated on demand
+		this.activateSlcTooltip =	f!=undefined && f.activate_slc_tooltip!=undefined //IE only, tooltip text appearing on select 
+										? f.activate_slc_tooltip : 'Click to activate'; // before it is populated
+		this.multipleSlcTooltip =	f!=undefined && f.multiple_slc_tooltip!=undefined //tooltip text appearing on multiple select 
+										? f.multiple_slc_tooltip : 'Use Ctrl key for multiple selections';
+		this.hasCustomSlcOptions =	f!=undefined && f.custom_slc_options &&
+										(typeof f.custom_slc_options).tf_LCase() == 'object' 
+										? true : false;	
+		this.customSlcOptions =		f!=undefined && f.custom_slc_options!=undefined
+										? f.custom_slc_options : null;
+		this.onBeforeOperation =	f!=undefined && tf_isFn(f.on_before_operation) //calls function before col operation
+										? f.on_before_operation : null;
+		this.onAfterOperation =		f!=undefined && tf_isFn(f.on_after_operation) //calls function after col operation
+										? f.on_after_operation : null;
+		
+		/*** checklist customisation and behaviours ***/
+		this.checkListDiv = 		[]; //checklist container div
+		this.checkListDivCssClass = f!=undefined && f.div_checklist_css_class!=undefined 
+										? f.div_checklist_css_class : 'div_checklist'; //defines css class for div containing checklist filter
+		this.checkListCssClass =	f!=undefined && f.checklist_css_class!=undefined //defines css class for checklist filters
+										? f.checklist_css_class : 'flt_checklist';
+		this.checkListItemCssClass = f!=undefined && f.checklist_item_css_class!=undefined //defines css class for checklist item (li)
+										? f.checklist_item_css_class : 'flt_checklist_item';
+		this.checkListSlcItemCssClass = f!=undefined && f.checklist_selected_item_css_class!=undefined //defines css class for selected checklist item (li)
+										? f.checklist_selected_item_css_class : 'flt_checklist_slc_item';								
+		this.activateCheckListTxt =	f!=undefined && f.activate_checklist_text!=undefined //Load on demand text 
+										? f.activate_checklist_text : 'Click to load data';
+		
+		/*** Filter operators ***/
+		this.orOperator =			f!=undefined && f.or_operator!=undefined ? f.or_operator : '||';
+		this.anOperator =			f!=undefined && f.and_operator!=undefined ? f.and_operator : '&&';
+		this.grOperator = 			f!=undefined && f.greater_operator!=undefined ? f.greater_operator : '>';
+		this.lwOperator =			f!=undefined && f.lower_operator!=undefined ? f.lower_operator : '<';
+		this.leOperator =			f!=undefined && f.lower_equal_operator!=undefined ? f.lower_equal_operator : '<=';
+		this.geOperator =			f!=undefined && f.greater_equal_operator!=undefined ? f.greater_equal_operator : '>=';
+		this.dfOperator =			f!=undefined && f.different_operator!=undefined ? f.different_operator : '!';
+		this.lkOperator =			f!=undefined && f.like_operator!=undefined ? f.like_operator : '*';
+		this.eqOperator =			f!=undefined && f.equal_operator!=undefined ? f.equal_operator : '=';
+		this.stOperator =			f!=undefined && f.start_with_operator!=undefined ? f.start_with_operator : '{';
+		this.enOperator =			f!=undefined && f.end_with_operator!=undefined ? f.end_with_operator : '}';
+		this.curExp =				f!=undefined && f.cur_exp!=undefined ? f.cur_exp : '^[¥£€$]';
+		this.separator = 			f!=undefined && f.separator!=undefined ? f.separator : ',';
+		
+		/*** rows counter ***/
+		this.rowsCounter = 			f!=undefined && f.rows_counter ? true : false; //show/hides rows counter
+		this.rowsCounterTgtId =		f!=undefined && f.rows_counter_target_id!=undefined //id of custom container element
+										? f.rows_counter_target_id : null;
+		this.rowsCounterDiv =		null; //element containing tot nb rows
+		this.rowsCounterSpan =		null; //element containing tot nb rows label
+		this.rowsCounterText =		f!=undefined && f.rows_counter_text!=undefined
+										? f.rows_counter_text : 'Rows: '; //defines rows counter text
+		this.totRowsCssClass =		f!=undefined && f.tot_rows_css_class!=undefined //defines css class rows counter
+										? f.tot_rows_css_class : 'tot';		
+		
+		/*** status bar ***/
+		this.statusBar =			f!=undefined && f.status_bar ? true : false; //show/hides status bar
+		this.statusBarTgtId =		f!=undefined && f.status_bar_target_id!=undefined //id of custom container element
+										? f.status_bar_target_id : null;
+		this.statusBarDiv =			null; //element containing status bar label
+		this.statusBarSpan =		null; //status bar
+		this.statusBarSpanText =	null; //status bar label
+		this.statusBarText =		f!=undefined && f.status_bar_text!=undefined
+										? f.status_bar_text : ''; //defines status bar text
+		this.statusBarCssClass =	f!=undefined && f.status_bar_css_class!=undefined //defines css class status bar
+										? f.status_bar_css_class : 'status';
+		this.statusBarCloseDelay =	250; //delay for status bar clearing			
+		
+		/*** loader ***/
+		this.loader =				f!=undefined && f.loader ? true : false; //enables/disables loader
+		this.loaderTgtId =			f!=undefined && f.loader_target_id!=undefined //id of container element
+										? f.loader_target_id : null;
+		this.loaderDiv =			null; //div containing loader
+		this.loaderText =			f!=undefined && f.loader_text!=undefined ? f.loader_text : 'Loading...'; //defines loader text
+		this.loaderHtml =			f!=undefined && f.loader_html!=undefined ? f.loader_html : null; //defines loader innerHtml
+		this.loaderCssClass = 		f!=undefined && f.loader_css_class!=undefined //defines css class for loader div
+										? f.loader_css_class : 'loader';
+		this.loaderCloseDelay =		200; //delay for hiding loader
+		this.onShowLoader =			f!=undefined && tf_isFn(f.on_show_loader) //calls function before loader is displayed
+										? f.on_show_loader : null;
+		this.onHideLoader =			f!=undefined && tf_isFn(f.on_hide_loader) //calls function after loader is closed
+										? f.on_hide_loader : null;					
+		
+		/*** validation - reset buttons/links ***/
+		this.displayBtn =			f!=undefined && f.btn ? true : false; //show/hides filter's validation button
+		this.btnText =				f!=undefined && f.btn_text!=undefined ? f.btn_text : 'go'; //defines validation button text
+		this.btnCssClass =			f!=undefined && f.btn_css_class!=undefined //defines css class for validation button
+										? f.btn_css_class : 'btnflt';
+		this.btnReset = 			f!=undefined && f.btn_reset ? true : false; //show/hides reset link
+		this.btnResetTgtId =		f!=undefined && f.btn_reset_target_id!=undefined //id of container element
+										? f.btn_reset_target_id : null;
+		this.btnResetEl =			null; //reset button element
+		this.btnResetText =			f!=undefined && f.btn_reset_text!=undefined ? f.btn_reset_text : 'Reset'; //defines reset text
+		this.btnResetHtml = 		f!=undefined && f.btn_reset_html!=undefined ? f.btn_reset_html : null; //defines reset button innerHtml
+		this.btnResetCssClass =		f!=undefined && f.btn_reset_css_class!=undefined //defines css class for reset button
+										? f.btn_reset_css_class :'reset';
+		
+		/*** paging ***/
+		this.paging =				f!=undefined && f.paging ? true : false; //enables/disables table paging
+		this.pagingTgtId =			f!=undefined && f.paging_target_id!=undefined //id of container element
+										? f.paging_target_id : null;		
+		this.pagingLength =			f!=undefined && f.paging_length!=undefined ? f.paging_length : 10; //defines table paging length
+		this.hasResultsPerPage =	f!=undefined && f.results_per_page ? true : false; //enables/disables results per page drop-down
+		this.resultsPerPageTgtId =	f!=undefined && f.results_per_page_target_id!=undefined //id of container element
+										? f.results_per_page_target_id : null;	
+		this.resultsPerPage =		null; //stores results per page text and values			
+		this.pagingSlc =			null; //stores paging select element
+		this.isPagingRemoved =		false; //indicates if paging elements were previously removed
+		this.pgSlcCssClass =		f!=undefined && f.paging_slc_css_class!=undefined
+										? f.paging_slc_css_class :'pgSlc'; //css class for paging select element
+		this.pgInpCssClass =		f!=undefined && f.paging_inp_css_class!=undefined
+										? f.paging_inp_css_class :'pgNbInp'; //css class for paging input element
+		this.resultsPerPageSlc =	null; //results per page select element
+		this.resultsSlcCssClass =	f!=undefined && f.results_slc_css_class!=undefined
+										? f.results_slc_css_class :'rspg'; //defines css class for results per page select
+		this.resultsSpanCssClass =	f!=undefined && f.results_span_css_class!=undefined
+										? f.results_span_css_class :'rspgSpan'; //css class for label preceding results per page select
+		this.nbVisibleRows	=		0; //nb visible rows
+		this.nbHiddenRows =			0; //nb hidden rows
+		this.startPagingRow =		0; //1st row index of current page
+		this.nbPages = 				0; //total nb of pages
+		this.currentPageNb =		1; //current page nb
+		this.btnNextPageText = 		f!=undefined && f.btn_next_page_text!=undefined
+										? f.btn_next_page_text : '>'; //defines next page button text
+		this.btnPrevPageText =		f!=undefined && f.btn_prev_page_text!=undefined
+										? f.btn_prev_page_text : '<'; //defines previous page button text
+		this.btnLastPageText =		f!=undefined && f.btn_last_page_text!=undefined
+										? f.btn_last_page_text : '>|'; //defines last page button text
+		this.btnFirstPageText =		f!=undefined && f.btn_first_page_text!=undefined
+										? f.btn_first_page_text : '|<' ; //defines first page button text
+		this.btnNextPageHtml =		f!=undefined && f.btn_next_page_html!=undefined
+										? f.btn_next_page_html : null; //defines next page button html
+		this.btnPrevPageHtml =		f!=undefined && f.btn_prev_page_html!=undefined
+										? f.btn_prev_page_html : null; //defines previous page button html
+		this.btnFirstPageHtml =		f!=undefined && f.btn_first_page_html!=undefined
+										? f.btn_first_page_html : null; //defines last page button html
+		this.btnLastPageHtml =		f!=undefined && f.btn_last_page_html!=undefined
+										? f.btn_last_page_html : null; //defines previous page button html
+		this.btnPageCssClass =		f!=undefined && f.paging_btn_css_class!=undefined
+										? f.paging_btn_css_class :'pgInp'; //css class for paging buttons (previous,next,etc.)
+		this.nbPgSpanCssClass = 	f!=undefined && f.nb_pages_css_class!=undefined
+										? f.nb_pages_css_class :'nbpg'; //css class for span containing tot nb of pages
+		this.hasPagingBtns =		f!=undefined && f.paging_btns==false ? false : true; //enables/disables paging buttons
+		this.pagingBtnEvents =		null; //stores paging buttons events
+		this.pageSelectorType =		f!=undefined && f.page_selector_type!=undefined
+										? f.page_selector_type : this.fltTypeSlc; //defines previous page button html		
+		
+		/*** webfx sort adapter ***/
+		this.sort =					f!=undefined && f.sort ? true : false; //enables/disables default table sorting
+		this.isSortEnabled =		false; //indicates if sort is set (used in tfAdapter.sortabletable.js)
+		this.sorted =				false; //indicates if tables was sorted
+		this.sortConfig =			f!=undefined && f.sort_config!=undefined 
+										? f.sort_config : {};
+		this.sortConfig.name =		f!=undefined && f.sort_config!=undefined && f.sort_config.name
+										? f.sort_config.name : 'sortabletable';
+		this.sortConfig.src =		f!=undefined && f.sort_config!=undefined && f.sort_config.src
+										? f.sort_config.src : 'sortabletable.js';
+		this.sortConfig.adapterSrc =f!=undefined && f.sort_config!=undefined && f.sort_config.adapter_src
+										? f.sort_config.adapter_src : 'tfAdapter.sortabletable.js';
+		this.sortConfig.initialize =f!=undefined && f.sort_config!=undefined && f.sort_config.initialize
+										? f.sort_config.initialize
+										: function(o){ if(o.SetSortTable) o.SetSortTable(); };
+		this.sortConfig.sortTypes =	f!=undefined && f.sort_config!=undefined && f.sort_config.sort_types
+										? f.sort_config.sort_types : [];
+		this.sortConfig.sortCol =	f!=undefined && f.sort_config!=undefined && f.sort_config.sort_col!=undefined
+										? f.sort_config.sort_col : null;
+		this.sortConfig.asyncSort =	f!=undefined && f.sort_config!=undefined && f.sort_config.async_sort
+										? true : false;
+		this.sortConfig.triggerIds =f!=undefined && f.sort_config!=undefined && f.sort_config.sort_trigger_ids
+										? f.sort_config.sort_trigger_ids : [];									
+		
+		/*** onkeyup event ***/
+		this.onKeyUp =				f!=undefined && f.on_keyup ? true : false; //enables/disables onkeyup event, table is filtered when user stops typing
+		this.onKeyUpDelay =			f!=undefined && f.on_keyup_delay!=undefined ? f.on_keyup_delay : 900; //onkeyup delay timer (msecs)
+		this.isUserTyping = 		null; //typing indicator
+		this.onKeyUpTimer = 		undefined;		
+		
+		/*** keyword highlighting ***/
+		this.highlightKeywords = 	f!=undefined && f.highlight_keywords ? true : false; //enables/disables keyword highlighting
+		this.highlightCssClass =	f!=undefined && f.highlight_css_class!=undefined //defines css class for highlighting
+										? f.highlight_css_class : 'keyword';	
+		
+		/*** data types ***/
+		this.defaultDateType =		f!=undefined && f.default_date_type!=undefined //defines default date type (european DMY)
+										? f.default_date_type : 'DMY';
+		this.thousandsSeparator =	f!=undefined && f.thousands_separator!=undefined //defines default thousands separator 
+										? f.thousands_separator : ','; //US = ',' EU = '.'
+		this.decimalSeparator = 	f!=undefined && f.decimal_separator!=undefined //defines default decimal separator 
+										? f.decimal_separator : '.'; //US & javascript = '.' EU = ','
+		this.hasColNbFormat = 		f!=undefined && f.col_number_format ? true : false; //enables number format per column
+		this.colNbFormat = 			f!=undefined && this.hasColNbFormat ? f.col_number_format : null; //array containing columns nb formats
+		this.hasColDateType = 		f!=undefined && f.col_date_type ? true : false; //enables date type per column
+		this.colDateType =			f!=undefined && this.hasColDateType ? f.col_date_type : null; //array containing columns date type
+		
+		/*** status messages ***/
+		this.msgFilter =			f!=undefined && f.msg_filter!=undefined //filtering
+										? f.msg_filter : 'Filtering data...'; 
+		this.msgPopulate =			f!=undefined && f.msg_populate!=undefined //populating drop-downs
+										? f.msg_populate : 'Populating filter...'; 
+		this.msgPopulateCheckList =	f!=undefined && f.msg_populate_checklist!=undefined //populating drop-downs
+										? f.msg_populate_checklist : 'Populating list...'; 
+		this.msgChangePage =		f!=undefined && f.msg_change_page!=undefined //changing paging page
+										? f.msg_change_page : 'Collecting paging data...';
+		this.msgClear =				f!=undefined && f.msg_clear!=undefined //clearing filters
+										? f.msg_clear : 'Clearing filters...';
+		this.msgChangeResults =		f!=undefined && f.msg_change_results!=undefined //changing nb results/page
+										? f.msg_change_results : 'Changing results per page...';
+		this.msgResetValues =		f!=undefined && f.msg_reset_grid_values!=undefined //re-setting grid values
+										? f.msg_reset_grid_values : 'Re-setting filters values...';
+		this.msgResetPage =			f!=undefined && f.msg_reset_page!=undefined //re-setting page
+										? f.msg_reset_page : 'Re-setting page...';
+		this.msgResetPageLength =	f!=undefined && f.msg_reset_page_length!=undefined //re-setting page length
+										? f.msg_reset_page_length : 'Re-setting page length...';
+		this.msgSort =				f!=undefined && f.msg_sort!=undefined //table sorting
+										? f.msg_sort : 'Sorting data...';
+		this.msgLoadExtensions =	f!=undefined && f.msg_load_extensions!=undefined //table sorting
+										? f.msg_load_extensions : 'Loading extensions...';			
+
+		/*** ids prefixes ***/
+		this.prfxFlt =				'flt'; //filters (inputs - selects)
+		this.prfxValButton =		'btn'; //validation button
+		this.prfxInfDiv =			'inf_'; //container div for paging elements, rows counter etc.
+		this.prfxLDiv =				'ldiv_'; //left div
+		this.prfxRDiv =				'rdiv_'; //right div
+		this.prfxMDiv =				'mdiv_'; //middle div
+		this.prfxContentDiv =		'cont_'; //table container if fixed headers enabled
+		this.prfxCheckListDiv =		'chkdiv_'; //checklist filter container div
+		this.prfxSlcPages =			'slcPages_'; //pages select
+		this.prfxSlcResults = 		'slcResults_'; //results per page select
+		this.prfxSlcResultsTxt =	'slcResultsTxt_'; //label preciding results per page select	
+		this.prfxBtnNextSpan =		'btnNextSpan_'; //span containing next page button
+		this.prfxBtnPrevSpan =		'btnPrevSpan_'; //span containing previous page button
+		this.prfxBtnLastSpan =		'btnLastSpan_'; //span containing last page button
+		this.prfxBtnFirstSpan =		'btnFirstSpan_'; //span containing first page button
+		this.prfxBtnNext =			'btnNext_'; //next button
+		this.prfxBtnPrev =			'btnPrev_'; //previous button
+		this.prfxBtnLast =			'btnLast_'; //last button
+		this.prfxBtnFirst =			'btnFirst_'; //first button
+		this.prfxPgSpan =			'pgspan_'; //span for tot nb pages
+		this.prfxPgBeforeSpan =		'pgbeforespan_'; //span preceding pages select (contains 'Page')
+		this.prfxPgAfterSpan =		'pgafterspan_'; //span following pages select (contains ' of ')
+		this.prfxCounter =			'counter_'; //rows counter div
+		this.prfxTotRows =			'totrows_span_'; //nb displayed rows label
+		this.prfxTotRowsTxt =		'totRowsTextSpan_'; //label preceding nb rows label
+		this.prfxResetSpan =		'resetspan_'; //span containing reset button
+		this.prfxLoader =			'load_'; //loader div
+		this.prfxStatus =			'status_'; //status bar div
+		this.prfxStatusSpan =		'statusSpan_'; //status bar label
+		this.prfxStatusTxt =		'statusText_';//text preceding status bar label
+		this.prfxCookieFltsValues =	'tf_flts_'; //filter values cookie
+		this.prfxCookiePageNb =		'tf_pgnb_'; //page nb cookie
+		this.prfxCookiePageLen = 	'tf_pglen_'; //page length cookie
+		this.prfxMainTblCont =		'gridCont_'; //div containing grid elements if grid_layout true
+		this.prfxTblCont =			'tblCont_'; //div containing table if grid_layout true
+		this.prfxHeadTblCont = 		'tblHeadCont_'; //div containing headers table if grid_layout true
+		this.prfxHeadTbl =			'tblHead_';	//headers' table if grid_layout true
+		this.prfxGridFltTd =		'_td_'; //id of td containing the filter if grid_layout true
+		this.prfxGridTh =			'tblHeadTh_'; //id of th containing column header if grid_layout true				
+
+		/*** cookies ***/
+		this.hasStoredValues =		false;
+		this.rememberGridValues =	f!=undefined && f.remember_grid_values ? true : false; //remembers filters values on page load
+		this.fltsValuesCookie =		this.prfxCookieFltsValues + this.id; //cookie storing filter values
+		this.rememberPageNb =		this.paging && f!=undefined && f.remember_page_number
+										? true : false; //remembers page nb on page load	
+		this.pgNbCookie =			this.prfxCookiePageNb + this.id; //cookie storing page nb
+		this.rememberPageLen =		this.paging && f!=undefined && f.remember_page_length
+										? true : false; //remembers page length on page load
+		this.pgLenCookie =			this.prfxCookiePageLen + this.id; //cookie storing page length
+		this.cookieDuration =		f!=undefined && f.set_cookie_duration 
+										? parseInt(f.set_cookie_duration) :100000; //cookie duration
+		
+		/*** extensions ***/
+		this.hasExtensions =		f!=undefined && f.extensions ? true : false; //imports external script
+		this.extensions =			(this.hasExtensions) ? f.extensions : null;
+
+		/***(deprecated: backward compatibility) ***/
+		this.hasBindScript =		f!=undefined && f.bind_script ? true : false; //imports external script
+		this.bindScript =			(this.hasBindScript) ? f.bind_script : null;
+		
+		/*** TF events ***/
+		var o = this;
+		this.Evt = {
+			name: {
+				filter: 'Filter',
+				populateselect: 'Populate',
+				populatechecklist: 'PopulateCheckList',
+				changepage: 'ChangePage',
+				clear: 'Clear',
+				changeresultsperpage: 'ChangeResults',
+				resetvalues: 'ResetValues',
+				resetpage: 'ResetPage',
+				resetpagelength: 'ResetPageLength',
+				sort: 'Sort',
+				loadextensions: 'LoadExtensions'			
+			},
+			_DetectKey: function(e)
+			/*====================================================
+				- common fn that detects return key for a given
+				element (onkeypress for inputs)
+			=====================================================*/
+			{
+				if(!o.enterKey) return;
+				var evt=(e)?e:(window.event)?window.event:null;
+				if(evt)
+				{
+					var key=(evt.charCode)?evt.charCode:
+						((evt.keyCode)?evt.keyCode:((evt.which)?evt.which:0));
+					if(key=='13')
+					{
+						o.Filter();
+					} else { 
+						o.isUserTyping = true;
+						window.clearInterval(o.onKeyUpTimer);
+						o.onKeyUpTimer = undefined; 
+					}
+				}//if evt
+			},
+			_OnKeyUp: function(e)
+			/*====================================================
+				- onkeyup event for text filters 
+				(onKeyUp property)
+			=====================================================*/
+			{
+				if(!o.onKeyUp) return;
+				var evt=(e)?e:(window.event)?window.event:null;
+				var key=(evt.charCode)?evt.charCode:
+						((evt.keyCode)?evt.keyCode:((evt.which)?evt.which:0));
+				o.isUserTyping = false;
+				
+				if( key!=13 && key!=9 && key!=27 && key!=38 && key!=40 )
+				{
+					function filter()
+					{
+						window.clearInterval(o.onKeyUpTimer);
+						o.onKeyUpTimer = undefined;
+						if( !o.isUserTyping )
+						{
+							o.Filter();
+							o.isUserTyping = null;			
+						}
+					}
+					if(o.onKeyUpTimer==undefined)
+						o.onKeyUpTimer = window.setInterval( filter, o.onKeyUpDelay );
+				} else { 
+					window.clearInterval(o.onKeyUpTimer); 
+					o.onKeyUpTimer = undefined; 
+				}
+			},
+			_OnKeyDown: function(e)
+			/*====================================================
+				- onkeydown event for input filters 
+				(onKeyUp property)
+			=====================================================*/
+			{
+				if(!o.onKeyUp) return;
+				o.isUserTyping = true;
+			},
+			_OnInpBlur: function(e)
+			/*====================================================
+				- onblur event for input filters (onKeyUp property)
+			=====================================================*/
+			{
+				if(!o.onKeyUp) return;
+				o.isUserTyping = false; 
+				window.clearInterval(o.onKeyUpTimer);
+			},
+			_OnInpFocus: function()
+			/*====================================================
+				- onfocus event for input filters
+			=====================================================*/
+			{
+				o.activeFilterId=this.getAttribute('id');
+				o.activeFlt = tf_Id(o.activeFilterId);
+			},
+			_OnSlcFocus: function()
+			/*====================================================
+				- onfocus event for select filters
+			=====================================================*/
+			{
+				o.activeFilterId = this.getAttribute('id');
+				o.activeFlt = tf_Id(o.activeFilterId);
+				if(o.fillSlcOnDemand && this.getAttribute('filled') == '0')
+				{// select is populated when element has focus
+					var ct = this.getAttribute('ct');
+					o.PopulateSelect(ct);
+					if(!tf_isIE) this.setAttribute('filled','1');
+				}
+			},
+			_OnSlcChange: function()
+			/*====================================================
+				- onchange event for select filters
+			=====================================================*/
+			{
+				if(o.onSlcChange) o.Filter();
+			},
+			_OnSlcBlur: function()
+			/*====================================================
+				- onblur event for select filters
+			=====================================================*/
+			{
+			},
+			_OnCheckListClick: function()
+			/*====================================================
+				- onclick event for checklist filters
+			=====================================================*/
+			{
+				if(o.fillSlcOnDemand && this.getAttribute('filled') == '0')
+				{
+					var ct = this.getAttribute('ct');
+					o.PopulateCheckList(ct);
+					o.checkListDiv[ct].onclick = null;
+					o.checkListDiv[ct].title = '';
+				}
+			},
+			_OnCheckListFocus: function()
+			/*====================================================
+				- onclick event for checklist filter container
+			=====================================================*/
+			{
+				o.activeFilterId = this.firstChild.getAttribute('id');
+				o.activeFlt = tf_Id(o.activeFilterId);
+			},
+			_OnBtnClick: function()
+			/*====================================================
+				- onclick event for validation button 
+				(btn property)
+			=====================================================*/
+			{
+				o.Filter();
+			},
+			_OnSlcPagesChange: function()
+			/*====================================================
+				- onchange event for paging select
+			=====================================================*/
+			{
+				if(o.Evt._Paging._OnSlcPagesChangeEvt)
+					o.Evt._Paging._OnSlcPagesChangeEvt();
+				o.ChangePage();
+				this.blur();
+				//ie only: blur is not enough...
+				if(this.parentNode && tf_isIE)
+					this.parentNode.focus();
+			},
+			_OnSlcPagesChangeEvt: null, //used by sort adapter
+			_OnSlcResultsChange: function()
+			/*====================================================
+				- onchange event for results per page select
+			=====================================================*/
+			{
+				o.ChangeResultsPerPage();
+				this.blur();
+				//ie only: blur is not enough...
+				if(this.parentNode && tf_isIE) 
+					this.parentNode.focus();
+			},
+			_Paging: {// paging buttons events
+				slcIndex: function(){ 
+					return (o.pageSelectorType==o.fltTypeSlc) 
+						? o.pagingSlc.options.selectedIndex 
+						: parseInt(o.pagingSlc.value)-1;
+				},
+				nbOpts: function(){ 
+					return (o.pageSelectorType==o.fltTypeSlc) 
+					? parseInt(o.pagingSlc.options.length)-1 
+					: (o.nbPages-1);
+				},
+				next: function(){
+					if(o.Evt._Paging.nextEvt) o.Evt._Paging.nextEvt();
+					var nextIndex = (o.Evt._Paging.slcIndex()<o.Evt._Paging.nbOpts()) 
+						? o.Evt._Paging.slcIndex()+1 : 0;
+					o.ChangePage(nextIndex);
+				},
+				nextEvt: null, //used by sort adapter
+				prev: function(){
+					if(o.Evt._Paging.prevEvt) o.Evt._Paging.prevEvt();
+					var prevIndex = o.Evt._Paging.slcIndex()>0 
+						? o.Evt._Paging.slcIndex()-1 : o.Evt._Paging.nbOpts();
+					o.ChangePage(prevIndex);
+				},
+				prevEvt: null, //used by sort adapter
+				last: function(){
+					if(o.Evt._Paging.lastEvt) o.Evt._Paging.lastEvt();
+					o.ChangePage(o.Evt._Paging.nbOpts());
+				},
+				lastEvt: null, //used by sort adapter
+				first: function(){
+					if(o.Evt._Paging.firstEvt)  o.Evt._Paging.firstEvt();
+					o.ChangePage(0);
+				},
+				firstEvt: null, //used by sort adapter
+				_detectKey: function(e)
+				{
+					var evt=(e)?e:(window.event)?window.event:null;
+					if(evt)
+					{
+						var key=(evt.charCode)?evt.charCode:
+							((evt.keyCode)?evt.keyCode:((evt.which)?evt.which:0));
+						if(key=='13'){ 
+							if(o.sorted){ o.Filter(); o.ChangePage(o.Evt._Paging.slcIndex()); }
+							else o.ChangePage();								
+							this.blur(); 
+						}
+					}//if evt
+				}
+			},
+			_EnableSlc: function()
+			/*====================================================
+				- onclick event slc parent node (enables filters)
+				IE only
+			=====================================================*/
+			{
+				this.firstChild.disabled = false;							
+				this.firstChild.focus();							
+				this.onclick = null;
+			},
+			_Clear: function()
+			/*====================================================
+				- clears filters
+			=====================================================*/
+			{
+				o.ClearFilters();
+			},
+			_EnableSort: function()
+			/*====================================================
+				- enables table sorting
+			=====================================================*/
+			{
+				if(tf_isImported(o.sortConfig.adapterSrc))
+					o.sortConfig.initialize.call(null,o);
+				else
+					o.IncludeFile(
+						o.sortConfig.name+'_adapter',
+						o.sortConfig.adapterSrc,
+						function(){ o.sortConfig.initialize.call(null,o); }
+					);
+			}
+		};
+		
+		/*** TF extensions ***/
+		this.Ext = {
+			list: {},
+			add: function(extName, extDesc, extPath, extCallBack)
+			{
+				var file = extPath.split('/')[extPath.split('/').length-1];
+				var re = new RegExp(file);
+				var path = extPath.replace(re,'');
+				o.Ext.list[extName] = { 
+					name: extName,
+					description: extDesc,
+					file: file,
+					path: path,
+					callback: extCallBack
+				};
+			}
+		};
+		
+    }//if tbl!=null		
+}
+
+TF.prototype = {
+	
+	AddGrid: function()
+	/*====================================================
+		- adds row with filtering grid bar and sets grid 
+		behaviours and layout
+	=====================================================*/
+	{
+		if(this.hasGrid) return;
+		this.refRow = this.startRow==undefined ? 2 : (this.startRow+1);
+		if(this.gridLayout) this.refRow = this.startRow==undefined ? 0 : this.startRow;
+		this.headersRow = (this.filtersRowIndex==0) ? 1 : 0;
+		try{ this.nbCells = this.GetCellsNb(this.refRow) }
+		catch(e){ this.nbCells = this.GetCellsNb(0) }
+
+		var f = this.fObj==undefined ? {} : this.fObj;
+		var n = (this.singleSearchFlt) ? 1 : this.nbCells, inpclass;
+		
+		if(this.gridLayout)
+		{
+			this.isExternalFlt = true;
+			this.SetGridLayout();
+			//Once grid generated 1st filterable row is 0 again
+			this.refRow = (tf_isIE || tf_isIE7) ? (this.refRow+1) : 0;
+		}
+		
+		if(this.loader) this.SetLoader();
+	
+		if(this.hasResultsPerPage)
+		{ 
+			this.resultsPerPage = f['results_per_page']!=undefined   
+				? f['results_per_page'] : this.resultsPerPage;
+			if(this.resultsPerPage.length<2)
+				this.hasResultsPerPage = false;
+			else
+				this.pagingLength = this.resultsPerPage[1][0];
+		}
+		
+		if(!this.fltGrid)
+		{//filters grid is not genetared
+			this.refRow = (this.refRow-1);
+			if(this.gridLayout) this.refRow = 0;
+			this.nbFilterableRows = this.GetRowsNb();
+			this.nbVisibleRows = this.nbFilterableRows;
+			this.nbRows = this.nbFilterableRows;
+		} else {
+			if(this.isFirstLoad)
+			{
+				if(!this.gridLayout){
+					var fltrow;
+					var thead = tf_Tag(this.tbl,'thead');
+					if( thead.length>0 )
+						fltrow = thead[0].insertRow(this.filtersRowIndex);
+					else
+						fltrow = this.tbl.insertRow(this.filtersRowIndex);
+					
+					if(this.fixedHeaders) this.SetFixedHeaders();
+					
+					fltrow.className = this.fltsRowCssClass;
+					//Disable for grid_layout
+					if( this.isExternalFlt && !this.gridLayout ) fltrow.style.display = 'none';
+				}
+				
+				this.nbFilterableRows = this.GetRowsNb();
+				this.nbVisibleRows = this.nbFilterableRows;
+				this.nbRows = this.tbl.rows.length;
+				
+				for(var i=0; i<n; i++)// this loop adds filters
+				{
+					var fltcell = tf_CreateElm(this.fltCellTag);
+					if(this.singleSearchFlt) fltcell.colSpan = this.nbCells;
+					if(!this.gridLayout) fltrow.appendChild( fltcell );
+					inpclass = (i==n-1 && this.displayBtn) ? this.fltSmallCssClass : this.fltCssClass;
+					
+					if( this['col'+i]==undefined )
+						this['col'+i] = (f['col_'+i]==undefined) 
+							? this.fltTypeInp : f['col_'+i].tf_LCase();
+							
+					if(this.singleSearchFlt)
+					{//only 1 input for single search
+						this['col'+i] = this.fltTypeInp;
+						inpclass = this.singleFltCssClass;
+					}
+	
+					if(this['col'+i]==this.fltTypeSlc || this['col'+i]==this.fltTypeMulti)
+					{//selects					
+						var slc = tf_CreateElm( this.fltTypeSlc,
+							['id',this.prfxFlt+i+'_'+this.id],
+							['ct',i],['filled','0'] );
+						if(this['col'+i]==this.fltTypeMulti)
+						{
+							slc.multiple = this.fltTypeMulti;
+							slc.title = this.multipleSlcTooltip;
+						}
+						slc.className = (this['col'+i].tf_LCase()==this.fltTypeSlc) 
+							? inpclass : this.fltMultiCssClass;// for ie<=6
+						
+						if( this.isExternalFlt && this.externalFltTgtIds && tf_Id(this.externalFltTgtIds[i]) )
+						{//filter is appended in desired element
+							tf_Id( this.externalFltTgtIds[i] ).appendChild(slc);
+							this.externalFltEls.push(slc);
+						} else {
+							fltcell.appendChild(slc);
+						}
+						
+						this.fltIds.push(this.prfxFlt+i+'_'+this.id);
+						
+						if(!this.fillSlcOnDemand) this.PopulateSelect(i);
+						
+						slc.onkeypress = this.Evt._DetectKey;
+						slc.onchange = this.Evt._OnSlcChange;
+						slc.onfocus = this.Evt._OnSlcFocus;
+						slc.onblur = this.Evt._OnSlcBlur;
+						
+						if(this.fillSlcOnDemand)
+						{//1st option is created here since PopulateSelect isn't invoked
+							var opt0 = tf_CreateOpt(this.displayAllText,'');
+							slc.appendChild( opt0 );						
+						}
+						
+						/* 	Code below for IE: it prevents select options to
+							slide out before select it-self is populated.
+							This is an unexpeted behavior for users since at
+							1st click options are empty. Work around: 
+							select is disabled and by clicking on element 
+							(parent td), users enable drop-down and select is
+							populated at same time.  */
+						if( this.fillSlcOnDemand && tf_isIE)
+						{
+							slc.disabled = true;
+							slc.title = this.activateSlcTooltip;
+							slc.parentNode.onclick = this.Evt._EnableSlc;
+							if( this['col'+i]==this.fltTypeMulti)
+								this.__deferMultipleSelection(slc,0);
+						}
+					}
+					
+					else if( this['col'+i]==this.fltTypeCheckList )
+					{// checklist
+						var divCont = tf_CreateElm('div',
+										['id',this.prfxCheckListDiv+i+'_'+this.id],
+										['ct',i],['filled','0'] );
+						divCont.className = this.checkListDivCssClass;
+						
+						if( this.isExternalFlt && this.externalFltTgtIds 
+							&& tf_Id(this.externalFltTgtIds[i]) )
+						{//filter is appended in desired element
+							tf_Id( this.externalFltTgtIds[i] ).appendChild(divCont);
+							this.externalFltEls.push(divCont);
+						} else {
+							fltcell.appendChild(divCont);
+						}
+						
+						this.checkListDiv[i] = divCont;
+						this.fltIds.push(this.prfxFlt+i+'_'+this.id);
+						if(!this.fillSlcOnDemand) this.PopulateCheckList(i);
+						
+						divCont.onclick = this.Evt._OnCheckListFocus;
+						
+						if(this.fillSlcOnDemand)
+						{
+							divCont.onclick = this.Evt._OnCheckListClick;
+							divCont.appendChild(tf_CreateText(this.activateCheckListTxt));
+						}
+					}
+					
+					else
+					{
+						var inptype;
+						(this['col'+i]==this.fltTypeInp) ? inptype='text' : inptype='hidden';//show/hide input	
+						var inp = tf_CreateElm( this.fltTypeInp,['id',this.prfxFlt+i+'_'+this.id],['type',inptype],['ct',i] );					
+						inp.className = inpclass;// for ie<=6
+						inp.onfocus = this.Evt._OnInpFocus;
+						
+						if( this.isExternalFlt && this.externalFltTgtIds && tf_Id(this.externalFltTgtIds[i]) )
+						{//filter is appended in desired element
+							tf_Id( this.externalFltTgtIds[i] ).appendChild(inp);
+							this.externalFltEls.push(inp);
+						} else {
+							fltcell.appendChild(inp);
+						}
+						
+						this.fltIds.push(this.prfxFlt+i+'_'+this.id);
+						
+						inp.onkeypress = this.Evt._DetectKey;
+						inp.onkeydown = this.Evt._OnKeyDown;
+						inp.onkeyup = this.Evt._OnKeyUp;
+						inp.onblur = this.Evt._OnInpBlur;
+						
+						if(this.rememberGridValues)
+						{
+							var flts = tf_ReadCookie(this.fltsValuesCookie); //reads the cookie
+							var reg = new RegExp(',','g');
+							var flts_values = flts.split(reg); //creates an array with filters' values
+							if (flts_values[i]!=' ')
+								this.SetFilterValue(i,flts_values[i],false);					
+						}
+					}
+					
+					if(i==n-1 && this.displayBtn)// this adds validation button
+					{
+						var btn = tf_CreateElm( this.fltTypeInp,['id',this.prfxValButton+i+'_'+this.id],
+												['type','button'], ['value',this.btnText] );
+						btn.className = this.btnCssClass;
+						
+						if( this.isExternalFlt && this.externalFltTgtIds && tf_Id(this.externalFltTgtIds[i]) ) 
+						//filter is appended in desired element
+							tf_Id( this.externalFltTgtIds[i] ).appendChild(btn);
+						else
+							fltcell.appendChild(btn);
+						
+						btn.onclick = this.Evt._OnBtnClick;				
+					}//if
+					
+				}// for i
+				
+			} else {
+				this.__resetGrid();			
+			}//if isFirstLoad
+		}//if this.fltGrid
+		
+		/* Filter behaviours */
+		if(this.rowsCounter) this.SetRowsCounter();
+		if(this.statusBar) this.SetStatusBar();
+		if(this.fixedHeaders && !this.isFirstLoad) this.SetFixedHeaders();
+		if(this.paging)	this.SetPaging();
+		if(this.hasResultsPerPage && this.paging) this.SetResultsPerPage();
+		if(this.btnReset) this.SetResetBtn();
+		
+		if(this.hasColWidth && !this.gridLayout) this.SetColWidths();
+		
+		if( this.alternateBgs && this.isStartBgAlternate )
+			this.SetAlternateRows(); //1st time only if no paging and rememberGridValues
+		
+		if(this.hasColOperation && this.fltGrid)
+		{
+			this.colOperation = f.col_operation;
+			this.SetColOperation();
+		}
+		
+		if(this.sort) this.SetSort();
+		
+		/* Deprecated Loads external script */
+		if(this.hasBindScript)
+		{
+			if(this.bindScript['src']!=undefined)
+			{
+				var scriptPath = this.bindScript['src'];
+				var scriptName = (this.bindScript['name']!=undefined)
+									? this.bindScript['name'] : '';
+				this.IncludeFile(scriptName,scriptPath,this.bindScript['target_fn']);
+			}
+		}//if bindScript
+		/* */
+		
+		this.isFirstLoad = false;
+		this.hasGrid = true;
+		
+		if( this.rememberGridValues ||
+			this.rememberPageLen ||
+			this.rememberPageNb )
+			this.ResetValues();
+		
+		this.ShowLoader('none');
+		
+		if(this.onFiltersLoaded)
+			this.onFiltersLoaded.call(null,this);
+
+		/* Loads extensions */
+		this.LoadExtensions();
+		/* */
+	},// AddGrid
+	
+	EvtManager: function( evt,s )
+	/*====================================================
+		- TF events manager
+		- Params: 
+			- event name (string)
+			- config object (optional literal object)
+	=====================================================*/
+	{
+		var o = this;
+		var slcIndex = (s!=undefined && s.slcIndex!=undefined) ? s.slcIndex : null;
+		var slcExternal = (s!=undefined && s.slcExternal!=undefined) ? s.slcExternal : false;
+		var slcId = (s!=undefined && s.slcId!=undefined) ? s.slcId : null;
+		var pgIndex = (s!=undefined && s.pgIndex!=undefined) ? s.pgIndex : null;
+		function efx(){
+			if(evt!=undefined)
+			switch( evt )
+			{
+				case o.Evt.name.filter:
+					(o.isModFilterFn) 
+						? o.modFilterFn.call(null,o)
+						: o._Filter();
+				break;
+				case o.Evt.name.populateselect:
+					(o.refreshFilters) 
+						? o._PopulateSelect(slcIndex,true) 
+						: o._PopulateSelect(slcIndex,false,slcExternal,slcId);
+				break;
+				case o.Evt.name.populatechecklist:
+					o._PopulateCheckList(slcIndex,slcExternal,slcId);
+				break;
+				case o.Evt.name.changepage:
+					o._ChangePage(pgIndex);
+				break;
+				case o.Evt.name.clear:
+					o._ClearFilters(); 
+					o._Filter();
+				break;
+				case o.Evt.name.changeresultsperpage:
+					o._ChangeResultsPerPage();
+				break;
+				case o.Evt.name.resetvalues:
+					o._ResetValues();					
+					o._Filter();
+				break;
+				case o.Evt.name.resetpage:
+					o._ResetPage(o.pgNbCookie);
+				break;
+				case o.Evt.name.resetpagelength:
+					o._ResetPageLength(o.pgLenCookie);
+				break;
+				case o.Evt.name.sort:
+					void(0);
+				break;
+				case o.Evt.name.loadextensions:
+					o._LoadExtensions();
+				break;
+				default: //to be used by extensions events when needed
+					o['_'+evt].call(null,o,s);
+				break;
+			}
+			o.StatusMsg('');
+			o.ShowLoader('none');
+		}
+		
+		if(this.loader || this.status || this.statusBar)
+		{
+			this.ShowLoader('');
+			this.StatusMsg(o['msg'+evt]);
+			window.setTimeout(efx,this.execDelay);
+		} else efx();
+	},
+	
+	LoadExtensions: function()
+	{
+		this.EvtManager(this.Evt.name.loadextensions);
+	},
+	
+	_LoadExtensions: function()
+	/*====================================================
+		- loads TF extensions
+	=====================================================*/
+	{
+		if(!this.hasExtensions) return;
+		if((typeof this.extensions.name).tf_LCase() == 'object' && 
+				(typeof this.extensions.src).tf_LCase() == 'object')
+		{
+			var ext = this.extensions;
+			for(var e=0; e<ext.name.length; e++)
+			{
+				var extPath = ext.src[e];
+				var extName = ext.name[e];
+				var extInit = (ext.initialize && ext.initialize[e]) ? ext.initialize[e] : null;
+				var extDesc = (ext.description && ext.description[e] ) ? ext.description[e] : null;
+				
+				//Registers extension 
+				this.Ext.add(extName, extDesc, extPath, extInit);
+				
+				if(tf_isImported(extPath) && extInit)
+				{
+					try{ extInit.call(null,this); }
+					catch(e){
+						var o = this;
+						function fn(){extInit.call(null,o);}
+						if(!tf_isIE) tf_addEvent(window,'load',fn); 
+						else{
+							function testReady(){
+								if (document.readyState == "complete") 
+								{
+									fn(); clearInterval(s);
+								}
+							}
+							var s = setInterval(testReady,10);
+						}		
+					}
+				}
+				else
+					this.IncludeFile(extName,extPath,extInit);
+			}
+		}
+	},
+	
+	RemoveGrid: function()
+	/*====================================================
+		- removes a filter grid
+	=====================================================*/
+	{
+		if( this.fltGrid && this.hasGrid )
+		{
+			var row = this.tbl.rows;
+			
+			this.RemovePaging();
+			this.RemoveStatusBar();
+			this.RemoveRowsCounter();
+			this.RemoveResetBtn();
+			this.RemoveResultsPerPage();
+			this.RemoveExternalFlts();
+			this.RemoveFixedHeaders();
+			this.RemoveTopDiv();
+			this.UnhighlightAll();
+			this.RemoveSort();
+			this.RemoveLoader();
+			
+			for(var j=this.refRow; j<this.nbRows; j++)
+			{//this loop shows all rows and removes validRow attribute			
+				row[j].style.display = '';
+				try
+				{ 
+					if( row[j].hasAttribute('validRow') ) 
+						row[j].removeAttribute('validRow');
+				} //ie<=6 doesn't support hasAttribute method
+				catch(e){
+					for( var x = 0; x < row[j].attributes.length; x++ ) 
+					{
+						if( row[j].attributes[x].nodeName.tf_LCase()=='validrow' ) 
+							row[j].removeAttribute('validRow');
+					}//for x
+				}//catch(e)
+				
+				//removes alterning colors
+				this.RemoveRowBg(j);
+				
+			}//for j
+	
+			if(this.fltGrid && !this.gridLayout)
+			{
+				this.fltGridEl = row[this.filtersRowIndex];			
+				this.tbl.deleteRow(this.filtersRowIndex);
+			}
+			this.activeFlt = null;
+			this.isStartBgAlternate = true;
+			this.hasGrid = false;
+			this.RemoveGridLayout();
+	
+		}//if this.fltGrid
+	},
+	
+	SetGridLayout: function()
+	/*====================================================
+		- generates a grid with fixed headers
+	=====================================================*/
+	{
+		if(!this.gridLayout) return;
+		if(!this.hasColWidth){// in case column widths are not set default width 100px
+			this.colWidth = [];
+			for(var k=0; k<this.nbCells; k++){
+				var colW, cell = this.tbl.rows[this.gridHeadRowIndex].cells[k];
+				if(cell.width!='') colW = cell.width;
+				else if(cell.style.width!='') colW = parseInt(cell.style.width);
+				else colW = this.gridDefaultColWidth;
+				this.colWidth[k] = colW;
+			}
+			this.hasColWidth = true;
+		}
+		this.SetColWidths(this.gridHeadRowIndex);
+		
+		var tblW;//initial table width
+		if(this.tbl.width!='') tblW = this.tbl.width;
+		else if(this.tbl.style.width!='') tblW = parseInt(this.tbl.style.width);
+		else tblW = this.tbl.clientWidth;
+		
+		//Main container: it will contain all the elements
+		this.tblMainCont = tf_CreateElm('div',['id', this.prfxMainTblCont + this.id]);
+		this.tblMainCont.className = this.gridMainContCssClass;
+		if(this.gridWidth) this.tblMainCont.style.width = this.gridWidth;
+		this.tbl.parentNode.insertBefore(this.tblMainCont, this.tbl);
+		
+		//Table container: div wrapping content table
+		this.tblCont = tf_CreateElm('div',['id', this.prfxTblCont + this.id]);
+		this.tblCont.className = this.gridContCssClass;
+		if(this.gridWidth) this.tblCont.style.width = this.gridWidth;
+		if(this.gridHeight) this.tblCont.style.height = this.gridHeight;
+		this.tbl.parentNode.insertBefore(this.tblCont, this.tbl);
+		var t = this.tbl.parentNode.removeChild(this.tbl);
+		this.tblCont.appendChild(t);
+		
+		//In case table width is expressed in %
+		if(this.tbl.style.width == '')
+			this.tbl.style.width = (this.__containsStr('%',tblW) 
+									? this.tbl.clientWidth : tblW) + 'px';
+
+		var d = this.tblCont.parentNode.removeChild(this.tblCont);
+		this.tblMainCont.appendChild(d);
+		
+		//Headers table container: div wrapping headers table
+		this.headTblCont = tf_CreateElm('div',['id', this.prfxHeadTblCont + this.id]);
+		this.headTblCont.className = this.gridHeadContCssClass;
+		if(this.gridWidth) this.headTblCont.style.width = this.gridWidth;		
+		
+		//Headers table
+		this.headTbl = tf_CreateElm('table',['id', this.prfxHeadTbl + this.id]);
+		var tH = tf_CreateElm('tHead'); //IE<7 needs it
+		
+		//1st row should be headers row, ids are added if not set
+		//Those ids are used by the sort feature
+		var hRow = this.tbl.rows[this.gridHeadRowIndex];
+		var sortTriggers = [];
+		for(var n=0; n<this.nbCells; n++){
+			var cell = hRow.cells[n];
+			var thId = cell.getAttribute('id');
+			if(!thId || thId==''){ 
+				thId = this.prfxGridTh+n+'_'+this.id 
+				cell.setAttribute('id', thId);
+			}
+			sortTriggers.push(thId);
+		}
+		
+		//Filters row is created
+		var filtersRow = tf_CreateElm('tr');
+		if(this.gridEnableFilters && this.fltGrid){
+			this.externalFltTgtIds = [];
+			for(var j=0; j<this.nbCells; j++)
+			{
+				var fltTdId = this.prfxFlt+j+ this.prfxGridFltTd +this.id;
+				var c = tf_CreateElm(this.fltCellTag, ['id', fltTdId]);
+				filtersRow.appendChild(c);
+				this.externalFltTgtIds[j] = fltTdId;
+			}
+		} 
+		//Headers row are moved from content table to headers table
+		for(var i=0; i<this.gridHeadRows.length; i++)
+		{
+			var headRow = this.tbl.rows[this.gridHeadRows[0]];			
+			tH.appendChild(headRow);
+		}
+		this.headTbl.appendChild(tH);
+		if(this.filtersRowIndex == 0) tH.insertBefore(filtersRow,hRow);
+		if(this.filtersRowIndex == 1) tH.appendChild(filtersRow);
+		
+		this.headTblCont.appendChild(this.headTbl);
+		this.tblCont.parentNode.insertBefore(this.headTblCont, this.tblCont);
+		
+		//THead needs to be removed in content table for sort feature
+		var thead = tf_Tag(this.tbl,'thead');
+		if( thead.length>0 ) this.tbl.removeChild(thead[0]);
+
+		//Headers table style
+		this.headTbl.style.width = this.tbl.style.width;
+		this.headTbl.style.tableLayout = 'fixed';
+		this.tbl.style.tableLayout = 'fixed';
+		this.headTbl.cellPadding = this.tbl.cellPadding;
+		this.headTbl.cellSpacing = this.tbl.cellSpacing;
+		
+		//Headers container width
+		this.headTblCont.style.width = this.tblCont.clientWidth+'px';
+		
+		//content table without headers needs col widths to be reset
+		this.SetColWidths();
+		
+		this.tbl.style.width = '';		
+		if(tf_isIE || tf_isIE7)	this.headTbl.style.width = '';
+		
+		//scroll synchronisation
+		var o = this; //TF object
+		this.tblCont.onscroll = function(){
+			o.headTblCont.scrollLeft = this.scrollLeft;
+			var _o = this; //this = scroll element
+			//New pointerX calc taking into account scrollLeft
+			if(!o.isPointerXOverwritten){
+				try{					
+					TF.Evt.pointerX = function(e)
+					{
+						e = e || window.event;
+						var scrollLeft = tf_StandardBody().scrollLeft + _o.scrollLeft;
+						return (e.pageX + _o.scrollLeft) || (e.clientX + scrollLeft);
+					}					
+					o.isPointerXOverwritten = true;
+				} catch(ee) {
+					o.isPointerXOverwritten = false;
+				}
+			}
+		}
+
+		/*** Default behaviours activation ***/
+		var f = this.fObj==undefined ? {} : this.fObj;
+		
+		//Sort is enabled if not specified in config object
+		if(f.sort != false){
+			this.sort = true;
+			this.sortConfig.asyncSort = true;
+			this.sortConfig.triggerIds = sortTriggers;
+		}
+		
+		if(this.gridEnableColResizer){
+			if(!this.hasExtensions){
+				this.extensions = {
+					name:['ColumnsResizer'],
+					src:['TFExt_ColsResizer/TFExt_ColsResizer.js'], 
+					description:['Columns Resizing'],
+					initialize:[function(o){o.SetColsResizer('ColumnsResizer');}]
+				}
+				this.hasExtensions = true;
+			} else {
+				if(!this.__containsStr('colsresizer',this.extensions.src.toString().tf_LCase())){
+					this.extensions.name.push('ColumnsResizer');
+					this.extensions.src.push('TFExt_ColsResizer/TFExt_ColsResizer.js');
+					this.extensions.description.push('Columns Resizing');
+					this.extensions.initialize.push(function(o){o.SetColsResizer('ColumnsResizer');});
+				}  
+			}
+		}
+		
+		//Default columns resizer properties for grid layout
+		f.col_resizer_cols_headers_table = this.headTbl.getAttribute('id');
+		f.col_resizer_cols_headers_index = this.gridHeadRowIndex;
+		f.col_resizer_width_adjustment = 0;
+		f.col_enable_text_ellipsis = false;
+		
+		//Cols generation for all browsers excepted IE<=7
+		o.tblHasColTag = (tf_Tag(o.tbl,'col').length > 0) ? true : false;
+		if(!tf_isIE && !tf_isIE7){
+			//Col elements are enough to keep column widths after sorting and filtering
+			function createColTags(o)
+			{
+				if(!o) return;
+				for(var k=(o.nbCells-1); k>=0; k--)
+				{
+					var col = tf_CreateElm( 'col', ['id', o.id+'_col_'+k]);
+					o.tbl.firstChild.parentNode.insertBefore(col,o.tbl.firstChild);
+					col.style.width = o.colWidth[k];
+					o.gridColElms[k] = col;
+				}
+				o.tblHasColTag = true;
+			}
+			if(!o.tblHasColTag) createColTags(o);
+			else{
+				var cols = tf_Tag(o.tbl,'col');
+				for(var i=0; i<o.nbCells; i++){
+					cols[i].setAttribute('id', o.id+'_col_'+i);
+					cols[i].style.width = o.colWidth[i];
+					o.gridColElms.push(cols[i]);
+				}
+			}
+		}
+		
+		//IE <= 7 needs an additional row for widths as col element width is not enough...
+		if(tf_isIE || tf_isIE7){
+			var tbody = tf_Tag(o.tbl,'tbody'), r;
+			if( tbody.length>0 ) r = tbody[0].insertRow(0);
+			else r = o.tbl.insertRow(0);
+			r.style.height = '0px';
+			for(var i=0; i<o.nbCells; i++){
+				var col = tf_CreateElm('td', ['id', o.id+'_col_'+i]);
+				col.style.width = o.colWidth[i];
+				o.tbl.rows[1].cells[i].style.width = '';
+				r.appendChild(col);
+				o.gridColElms.push(col);
+			}
+			this.hasGridWidthsRow = true;
+			//Data table row with widths expressed
+			o.leadColWidthsRow = o.tbl.rows[0];
+			o.leadColWidthsRow.setAttribute('validRow','false');
+			
+			var beforeSortFn = tf_isFn(f.on_before_sort) ? f.on_before_sort : null;
+			f.on_before_sort = function(o,colIndex){
+				o.leadColWidthsRow.setAttribute('validRow','false');
+				if(beforeSortFn!=null) beforeSortFn.call(null,o,colIndex);
+			} 
+			
+			var afterSortFn = tf_isFn(f.on_after_sort) ? f.on_after_sort : null;
+			f.on_after_sort = function(o,colIndex){
+				if(o.leadColWidthsRow.rowIndex != 0){
+					var r = o.leadColWidthsRow;
+					if( tbody.length>0 )
+						tbody[0].moveRow(o.leadColWidthsRow.rowIndex, 0);
+					else o.tbl.moveRow(o.leadColWidthsRow.rowIndex, 0);
+				}
+				if(afterSortFn!=null) afterSortFn.call(null,o,colIndex);
+			}	
+		}
+		
+		var afterColResizedFn = tf_isFn(f.on_after_col_resized) ? f.on_after_col_resized : null;
+		f.on_after_col_resized = function(o,colIndex){
+			if(colIndex==undefined) return;
+			var w = o.crWColsRow.cells[colIndex].style.width;
+			var col = o.gridColElms[colIndex];
+			col.style.width = w;
+			
+			var thCW = o.crWColsRow.cells[colIndex].clientWidth;
+			var tdCW = o.crWRowDataTbl.cells[colIndex].clientWidth;
+			
+			if(tf_isIE || tf_isIE7)
+				o.tbl.style.width = o.headTbl.clientWidth+'px';
+			
+			if(thCW != tdCW && !tf_isIE && !tf_isIE7)
+				o.headTbl.style.width = o.tbl.clientWidth+'px'; 
+			
+			if(afterColResizedFn!=null) afterColResizedFn.call(null,o,colIndex);			
+		}	
+		
+		if(this.tbl.clientWidth != this.headTbl.clientWidth)
+			this.tbl.style.width = this.headTbl.clientWidth+'px';
+	},
+	
+	RemoveGridLayout: function()
+	{
+		if(!this.gridLayout) return;		
+		var t = this.tbl.parentNode.removeChild(this.tbl);
+		this.tblMainCont.parentNode.insertBefore(t, this.tblMainCont);
+		this.tblMainCont.parentNode.removeChild( this.tblMainCont );
+		this.tblMainCont = null;
+		this.headTblCont = null;
+		this.headTbl = null;
+		this.tblCont = null;
+		//TO DO: alternative solution for Firefox
+		this.tbl.outerHTML = this.sourceTblHtml;
+		this.tbl = tf_Id(this.id);
+		this.isFirstLoad = true;
+		this.activeFlt = null;
+		this.isStartBgAlternate = true;
+		this.hasGrid = false;
+	},
+	
+	SetTopDiv: function()
+	/*====================================================
+		- Generates div above table where paging,
+		reset button, rows counter label etc. are placed
+	=====================================================*/
+	{
+		if( this.infDiv!=null ) return;
+	
+		/*** container div ***/
+		var infdiv = tf_CreateElm( 'div',['id',this.prfxInfDiv+this.id] );
+		infdiv.className = this.infDivCssClass;// setAttribute method doesn't seem to work on ie<=6
+		if(this.fixedHeaders && this.contDiv)
+			this.contDiv.parentNode.insertBefore(infdiv, this.contDiv);
+		else if(this.gridLayout){
+			this.tblMainCont.appendChild(infdiv);
+			infdiv.className = this.gridInfDivCssClass;
+		}
+		else
+			this.tbl.parentNode.insertBefore(infdiv, this.tbl);
+		this.infDiv = tf_Id( this.prfxInfDiv+this.id );
+		
+		/*** left div containing rows # displayer ***/
+		var ldiv = tf_CreateElm( 'div',['id',this.prfxLDiv+this.id] );
+		ldiv.className = this.lDivCssClass;/*'ldiv'*/;
+		infdiv.appendChild(ldiv);
+		this.lDiv = tf_Id( this.prfxLDiv+this.id );		
+		
+		/*** 	right div containing reset button 
+				+ nb results per page select 	***/	
+		var rdiv = tf_CreateElm( 'div',['id',this.prfxRDiv+this.id] );
+		rdiv.className = this.rDivCssClass/*'rdiv'*/;
+		infdiv.appendChild(rdiv);
+		this.rDiv = tf_Id( this.prfxRDiv+this.id );
+		
+		/*** mid div containing paging elements ***/
+		var mdiv = tf_CreateElm( 'div',['id',this.prfxMDiv+this.id] );
+		mdiv.className = this.mDivCssClass/*'mdiv'*/;						
+		infdiv.appendChild(mdiv);
+		this.mDiv = tf_Id( this.prfxMDiv+this.id );
+	},
+	
+	RemoveTopDiv: function()
+	/*====================================================
+		- Removes div above table where paging,
+		reset button, rows counter label etc. are placed
+	=====================================================*/
+	{
+		if( this.infDiv==null ) return;
+		this.infDiv.parentNode.removeChild( this.infDiv );
+		this.infDiv = null;
+	},
+	
+	SetFixedHeaders: function()
+	/*====================================================
+		- CSS solution making headers fixed
+	=====================================================*/
+	{
+		if((!this.hasGrid && !this.isFirstLoad) || !this.fixedHeaders) return;
+		if(this.contDiv) return;	
+		var thead = tf_Tag(this.tbl,'thead');
+		if( thead.length==0 ) return;
+		var tbody = tf_Tag(this.tbl,'tbody');	
+		if( tbody[0].clientHeight!=0 ) 
+		{//firefox returns tbody height
+			//previous values
+			this.prevTBodyH = tbody[0].clientHeight;
+			this.prevTBodyOverflow = tbody[0].style.overflow;
+			this.prevTBodyOverflowX = tbody[0].style.overflowX;
+			
+			tbody[0].style.height = this.tBodyH+'px';
+			tbody[0].style.overflow = 'auto';
+			tbody[0].style.overflowX = 'hidden';
+		} else { //IE returns 0
+			// cont div is added to emulate fixed headers behaviour
+			var contDiv = tf_CreateElm( 'div',['id',this.prfxContentDiv+this.id] );
+			contDiv.className = this.contDivCssClass;
+			this.tbl.parentNode.insertBefore(contDiv, this.tbl);
+			contDiv.appendChild(this.tbl);
+			this.contDiv = tf_Id(this.prfxContentDiv+this.id);
+			//prevents headers moving during window scroll (IE)
+			this.contDiv.style.position = 'relative';
+			
+			var theadH = 0;
+			var theadTr = tf_Tag(thead[0],'tr');	
+			for(var i=0; i<theadTr.length; i++)
+			{//css below emulates fixed headers on IE<=6
+				theadTr[i].style.cssText += 'position:relative; ' +
+											'top:expression(offsetParent.scrollTop);';
+				theadH += parseInt(theadTr[i].clientHeight);
+			}
+			
+			this.contDiv.style.height = (this.tBodyH+theadH)+'px';
+			
+			var tfoot = tf_Tag(this.tbl,'tfoot');
+			if( tfoot.length==0 ) return;
+			
+			var tfootTr = tf_Tag(tfoot[0],'tr');
+				
+			for(var j=0; j<tfootTr.length; j++)//css below emulates fixed footer on IE<=6
+				tfootTr[j].style.cssText += 'position:relative; overflow-x: hidden; ' +
+											'top: expression(parentNode.parentNode.offsetHeight >= ' +
+											'offsetParent.offsetHeight ? 0 - parentNode.parentNode.offsetHeight + '+ 
+											'offsetParent.offsetHeight + offsetParent.scrollTop : 0);';		
+		}	
+	},
+	
+	RemoveFixedHeaders: function()
+	/*====================================================
+		- Removes fixed headers
+	=====================================================*/
+	{
+		if(!this.hasGrid || !this.fixedHeaders ) return;
+		if( this.contDiv )//IE additional div
+		{
+			this.contDiv.parentNode.insertBefore(this.tbl, this.contDiv);
+			this.contDiv.parentNode.removeChild( this.contDiv );
+			this.contDiv = null;
+			var thead = tf_Tag(this.tbl,'thead');
+			if( thead.length==0 ) return;
+			var theadTr = tf_Tag(thead[0],'tr');
+			if( theadTr.length==0 ) return;
+			for(var i=0; i<theadTr.length; i++)
+				theadTr[i].style.cssText = '';
+			var tfoot = tf_Tag(this.tbl,'tfoot');
+			if( tfoot.length==0 ) return;		
+			var tfootTr = tf_Tag(tfoot[0],'tr');	
+			for(var j=0; j<tfootTr.length; j++)
+			{
+				tfootTr[j].style.position = 'relative';
+				tfootTr[j].style.top = '';
+				tfootTr[j].style.overeflowX = '';
+			}
+		} else {
+			var tbody = tf_Tag(this.tbl,'tbody');
+			if( tbody.length==0 ) return;
+			tbody[0].style.height = this.prevTBodyH+'px';
+			tbody[0].style.overflow = this.prevTBodyOverflow;
+			tbody[0].style.overflowX = this.prevTBodyOverflowX;
+		}
+	},
+	
+	SetPaging: function()
+	/*====================================================
+		- Generates paging elements:
+			- pages drop-down list
+			- previous, next, first, last buttons
+	=====================================================*/
+	{
+		if(!this.hasGrid && !this.isFirstLoad) return;
+		if(!this.paging || (!this.isPagingRemoved && !this.isFirstLoad)) return;
+		var start_row = this.refRow;
+		var nrows = this.nbRows;
+		this.nbPages = Math.ceil( (nrows-start_row)/this.pagingLength );//calculates page nb
+	
+		// Paging drop-down list selector
+		if(this.pageSelectorType == this.fltTypeSlc)
+		{
+			var slcPages = tf_CreateElm( this.fltTypeSlc, ['id',this.prfxSlcPages+this.id] );
+			slcPages.className = this.pgSlcCssClass;
+			slcPages.onchange = this.Evt._OnSlcPagesChange;
+		}
+		// Paging input selector
+		if(this.pageSelectorType == this.fltTypeInp)
+		{
+			var slcPages = tf_CreateElm( 
+				this.fltTypeInp, 
+				['id',this.prfxSlcPages+this.id],
+				['value',this.currentPageNb]
+			);
+			slcPages.className = this.pgInpCssClass;
+			slcPages.onkeypress = this.Evt._Paging._detectKey;
+		}
+		
+		var btnNextSpan, btnPrevSpan, btnLastSpan, btnFirstSpan;// btns containers
+		btnNextSpan = tf_CreateElm('span',['id',this.prfxBtnNextSpan+this.id]);
+		btnPrevSpan = tf_CreateElm('span',['id',this.prfxBtnPrevSpan+this.id]);
+		btnLastSpan = tf_CreateElm('span',['id',this.prfxBtnLastSpan+this.id]);
+		btnFirstSpan = tf_CreateElm('span',['id',this.prfxBtnFirstSpan+this.id]);
+		
+		if(this.hasPagingBtns)
+		{
+			if(this.btnNextPageHtml==null)
+			{// Next button
+				var btn_next = tf_CreateElm( this.fltTypeInp,['id',this.prfxBtnNext+this.id],
+					['type','button'],['value',this.btnNextPageText],['title','Next'] );
+				btn_next.className = this.btnPageCssClass;
+				btn_next.onclick = this.Evt._Paging.next;
+				btnNextSpan.appendChild(btn_next);
+			} else {
+				btnNextSpan.innerHTML = this.btnNextPageHtml;
+				btnNextSpan.onclick = this.Evt._Paging.next;
+			}
+			
+			if(this.btnPrevPageHtml==null)
+			{// Previous button
+				var btn_prev = tf_CreateElm( this.fltTypeInp,['id',this.prfxBtnPrev+this.id],
+					['type','button'],['value',this.btnPrevPageText],['title','Previous'] );
+				btn_prev.className = this.btnPageCssClass;
+				btn_prev.onclick = this.Evt._Paging.prev;
+				btnPrevSpan.appendChild(btn_prev);
+			} else { 
+				btnPrevSpan.innerHTML = this.btnPrevPageHtml;
+				btnPrevSpan.onclick = this.Evt._Paging.prev;
+			}
+			
+			if(this.btnLastPageHtml==null)
+			{// Last button
+				var btn_last = tf_CreateElm( this.fltTypeInp,['id',this.prfxBtnLast+this.id],
+					['type','button'],['value',this.btnLastPageText],['title','Last'] );
+				btn_last.className = this.btnPageCssClass;
+				btn_last.onclick = this.Evt._Paging.last;
+				btnLastSpan.appendChild(btn_last);
+			} else { 
+				btnLastSpan.innerHTML = this.btnLastPageHtml;
+				btnLastSpan.onclick = this.Evt._Paging.last;
+			}
+			
+			if(this.btnFirstPageHtml==null)
+			{// First button
+				var btn_first = tf_CreateElm( this.fltTypeInp,['id',this.prfxBtnFirst+this.id],
+					['type','button'],['value',this.btnFirstPageText],['title','First'] );
+				btn_first.className = this.btnPageCssClass;
+				btn_first.onclick = this.Evt._Paging.first;
+				btnFirstSpan.appendChild(btn_first);
+			} else { 
+				btnFirstSpan.innerHTML = this.btnFirstPageHtml;
+				btnFirstSpan.onclick = this.Evt._Paging.first;
+			}			
+		}//if this.hasPagingBtns
+		
+		// paging elements (buttons+drop-down list) are added to defined element
+		if(this.pagingTgtId==null) this.SetTopDiv();
+		var targetEl = ( this.pagingTgtId==null ) ? this.mDiv : tf_Id( this.pagingTgtId );
+		
+		/***	if paging previously removed this prevents IE memory leak with removeChild 
+				used in RemovePaging method. For more info refer to
+				http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2840253&SiteID=1	***/
+		if ( targetEl.innerHTML!='' ) targetEl.innerHTML = '';
+		/*** ***/
+		
+		targetEl.appendChild(btnPrevSpan);
+		targetEl.appendChild(btnFirstSpan);
+		
+		var pgBeforeSpan = tf_CreateElm( 'span',['id',this.prfxPgBeforeSpan+this.id] );
+		pgBeforeSpan.appendChild( tf_CreateText(' Page ') );
+		pgBeforeSpan.className = this.nbPgSpanCssClass;
+		targetEl.appendChild(pgBeforeSpan);
+		targetEl.appendChild(slcPages);
+		var pgAfterSpan = tf_CreateElm( 'span',['id',this.prfxPgAfterSpan+this.id] );
+		pgAfterSpan.appendChild( tf_CreateText(' of ') );
+		pgAfterSpan.className = this.nbPgSpanCssClass;
+		targetEl.appendChild(pgAfterSpan)
+		var pgspan = tf_CreateElm( 'span',['id',this.prfxPgSpan+this.id] );
+		pgspan.className = this.nbPgSpanCssClass;
+		pgspan.appendChild( tf_CreateText(' '+this.nbPages+' ') );
+		targetEl.appendChild(pgspan);
+		targetEl.appendChild(btnLastSpan);
+		targetEl.appendChild(btnNextSpan);
+	
+		this.pagingSlc = tf_Id(this.prfxSlcPages+this.id); //to be easily re-used
+		
+		// if this.rememberGridValues==true this.SetPagingInfo() is called
+		// in ResetGridValues() method
+		if( !this.rememberGridValues || this.isPagingRemoved )
+			this.SetPagingInfo();
+		if( !this.fltGrid )
+		{
+			this.ValidateAllRows();
+			this.SetPagingInfo(this.validRowsIndex);
+		}
+			
+		this.pagingBtnEvents = this.Evt._Paging;
+		this.isPagingRemoved = false;
+	},
+	
+	RemovePaging: function()
+	/*====================================================
+		- Removes paging elements
+	=====================================================*/
+	{
+		if(!this.hasGrid) return;
+		if( this.pagingSlc==null ) return;
+		var btnNextSpan, btnPrevSpan, btnLastSpan, btnFirstSpan;// btns containers
+		var pgBeforeSpan, pgAfterSpan, pgspan;
+		btnNextSpan = tf_Id(this.prfxBtnNextSpan+this.id);
+		btnPrevSpan = tf_Id(this.prfxBtnPrevSpan+this.id);
+		btnLastSpan = tf_Id(this.prfxBtnLastSpan+this.id);
+		btnFirstSpan = tf_Id(this.prfxBtnFirstSpan+this.id);
+		pgBeforeSpan = tf_Id(this.prfxPgBeforeSpan+this.id);//span containing 'Page' text
+		pgAfterSpan = tf_Id(this.prfxPgAfterSpan+this.id);//span containing 'of' text
+		pgspan = tf_Id(this.prfxPgSpan+this.id);//span containing nb of pages
+		
+		this.pagingSlc.parentNode.removeChild(this.pagingSlc);
+		
+		if( btnNextSpan!=null )
+			btnNextSpan.parentNode.removeChild( btnNextSpan );
+	
+		if( btnPrevSpan!=null )
+			btnPrevSpan.parentNode.removeChild( btnPrevSpan );
+	
+		if( btnLastSpan!=null )
+			btnLastSpan.parentNode.removeChild( btnLastSpan );
+	
+		if( btnFirstSpan!=null )
+			btnFirstSpan.parentNode.removeChild( btnFirstSpan );
+	
+		if( pgBeforeSpan!=null )
+			pgBeforeSpan.parentNode.removeChild( pgBeforeSpan );
+	
+		if( pgAfterSpan!=null )
+			pgAfterSpan.parentNode.removeChild( pgAfterSpan );
+	
+		if( pgspan!=null )
+			pgspan.parentNode.removeChild( pgspan );
+		
+		this.pagingBtnEvents = null;	
+		this.pagingSlc = null;
+		this.isPagingRemoved = true;
+	},
+	
+	SetRowsCounter: function()
+	/*====================================================
+		- Generates rows counter label
+	=====================================================*/
+	{
+		if(!this.hasGrid && !this.isFirstLoad) return;
+		if( this.rowsCounterSpan!=null ) return;
+		var countDiv = tf_CreateElm( 'div',['id',this.prfxCounter+this.id] ); //rows counter container
+		countDiv.className = this.totRowsCssClass;
+		var countSpan = tf_CreateElm( 'span',['id',this.prfxTotRows+this.id] ); //rows counter label
+		var countText = tf_CreateElm( 'span',['id',this.prfxTotRowsTxt+this.id] );
+		countText.appendChild( tf_CreateText(this.rowsCounterText) );
+		
+		// counter is added to defined element
+		if(this.rowsCounterTgtId==null) this.SetTopDiv();
+		var targetEl = ( this.rowsCounterTgtId==null ) ? this.lDiv : tf_Id( this.rowsCounterTgtId );
+		
+		//IE only: clears all for sure
+		if(this.rowsCounterDiv && tf_isIE)
+			this.rowsCounterDiv.outerHTML = '';
+		
+		if( this.rowsCounterTgtId==null )
+		{//default container: 'lDiv'
+			countDiv.appendChild(countText);
+			countDiv.appendChild(countSpan);
+			targetEl.appendChild(countDiv);
+		}
+		else
+		{// custom container, no need to append statusDiv
+			targetEl.appendChild(countText);
+			targetEl.appendChild(countSpan);
+		}
+		this.rowsCounterDiv = tf_Id( this.prfxCounter+this.id );
+		this.rowsCounterSpan = tf_Id( this.prfxTotRows+this.id );
+		
+		this.RefreshNbRows();	
+	},
+	
+	RemoveRowsCounter: function()
+	/*====================================================
+		- Removes rows counter label
+	=====================================================*/
+	{
+		if(!this.hasGrid) return;
+		if( this.rowsCounterSpan==null ) return;
+		
+		if(this.rowsCounterTgtId==null && this.rowsCounterDiv)
+		{
+			//IE only: clears all for sure
+			if(tf_isIE) this.rowsCounterDiv.outerHTML = '';
+			else
+				this.rowsCounterDiv.parentNode.removeChild( 
+					this.rowsCounterDiv
+				);
+		} else {
+			tf_Id( this.rowsCounterTgtId ).innerHTML = '';
+		}
+		this.rowsCounterSpan = null;
+		this.rowsCounterDiv = null;
+	},
+	
+	SetStatusBar: function()
+	/*====================================================
+		- Generates status bar label
+	=====================================================*/
+	{
+		if(!this.hasGrid && !this.isFirstLoad) return;
+		var statusDiv = tf_CreateElm( 'div',['id',this.prfxStatus+this.id] ); //status bar container
+		statusDiv.className = this.statusBarCssClass;
+		var statusSpan = tf_CreateElm( 'span',['id',this.prfxStatusSpan+this.id] ); //status bar label
+		var statusSpanText = tf_CreateElm( 'span',['id',this.prfxStatusTxt+this.id] );//preceding text
+		statusSpanText.appendChild( tf_CreateText(this.statusBarText) );
+	
+		// target element container
+		if(this.statusBarTgtId==null) this.SetTopDiv();
+		var targetEl = ( this.statusBarTgtId==null ) ? this.lDiv : tf_Id( this.statusBarTgtId );
+		
+		if(this.statusBarDiv && tf_isIE)
+			this.statusBarDiv.outerHTML = '';
+		
+		if( this.statusBarTgtId==null )
+		{//default container: 'lDiv'
+			statusDiv.appendChild(statusSpanText);
+			statusDiv.appendChild(statusSpan);
+			targetEl.appendChild(statusDiv);
+		}
+		else
+		{// custom container, no need to append statusDiv
+			targetEl.appendChild(statusSpanText);
+			targetEl.appendChild(statusSpan);
+		}
+
+		this.statusBarDiv = tf_Id( this.prfxStatus+this.id );
+		this.statusBarSpan = tf_Id( this.prfxStatusSpan+this.id );
+		this.statusBarSpanText = tf_Id( this.prfxStatusTxt+this.id );
+	},
+	
+	RemoveStatusBar: function()
+	/*====================================================
+		- Removes status bar div
+	=====================================================*/
+	{
+		if(!this.hasGrid) return;
+		if(this.statusBarDiv)
+		{
+			this.statusBarDiv.innerHTML = '';
+			this.statusBarDiv.parentNode.removeChild( 
+				this.statusBarDiv
+			);
+			this.statusBarSpan = null;
+			this.statusBarSpanText = null;
+			this.statusBarDiv = null;
+		}
+	},
+	
+	SetResultsPerPage: function()
+	/*====================================================
+		- Generates results per page select + label
+	=====================================================*/
+	{
+		if(!this.hasGrid && !this.isFirstLoad) return;
+		if( this.resultsPerPageSlc!=null || this.resultsPerPage==null ) return;
+		var slcR = tf_CreateElm( this.fltTypeSlc,['id',this.prfxSlcResults+this.id] );
+		slcR.className = this.resultsSlcCssClass;
+		var slcRText = this.resultsPerPage[0], slcROpts = this.resultsPerPage[1];
+		var slcRSpan = tf_CreateElm( 'span',['id',this.prfxSlcResultsTxt+this.id] );
+		slcRSpan.className = this.resultsSpanCssClass;
+		
+		// results per page select is added to defined element
+		if(this.resultsPerPageTgtId==null) this.SetTopDiv();
+		var targetEl = ( this.resultsPerPageTgtId==null ) ? this.rDiv : tf_Id( this.resultsPerPageTgtId );
+		slcRSpan.appendChild(tf_CreateText(slcRText));
+		targetEl.appendChild(slcRSpan);
+		targetEl.appendChild(slcR);
+		
+		this.resultsPerPageSlc = tf_Id(this.prfxSlcResults+this.id);
+		
+		for(var r=0; r<slcROpts.length; r++)
+		{
+			var currOpt = new Option(slcROpts[r],slcROpts[r],false,false);
+			this.resultsPerPageSlc.options[r] = currOpt;
+		}
+		slcR.onchange = this.Evt._OnSlcResultsChange;
+	},
+	
+	RemoveResultsPerPage: function()
+	/*====================================================
+		- Removes results per page select + label
+	=====================================================*/
+	{
+		if(!this.hasGrid) return;
+		if( this.resultsPerPageSlc==null || this.resultsPerPage==null ) return;
+		var slcR, slcRSpan;
+		slcR = this.resultsPerPageSlc;
+		slcRSpan = tf_Id( this.prfxSlcResultsTxt+this.id );
+		if( slcR!=null )
+			slcR.parentNode.removeChild( slcR );
+		if( slcRSpan!=null )
+			slcRSpan.parentNode.removeChild( slcRSpan );
+		this.resultsPerPageSlc = null;
+	},
+	
+	SetResetBtn: function()
+	/*====================================================
+		- Generates reset button
+	=====================================================*/
+	{
+		if(!this.hasGrid && !this.isFirstLoad) return;
+		if( this.btnResetEl!=null ) return;
+		var resetspan = tf_CreateElm('span',['id',this.prfxResetSpan+this.id]);
+		
+		// reset button is added to defined element
+		if(this.btnResetTgtId==null) this.SetTopDiv();
+		var targetEl = ( this.btnResetTgtId==null ) ? this.rDiv : tf_Id( this.btnResetTgtId );
+		targetEl.appendChild(resetspan);
+			
+		if(this.btnResetHtml==null)
+		{	
+			var fltreset = tf_CreateElm( 'a', ['href','javascript:void(0);'] );
+			fltreset.className = this.btnResetCssClass;
+			fltreset.appendChild(tf_CreateText(this.btnResetText));
+			resetspan.appendChild(fltreset);
+			fltreset.onclick = this.Evt._Clear;
+		} else {
+			resetspan.innerHTML = this.btnResetHtml;
+			var resetEl = resetspan.firstChild;
+			resetEl.onclick = this.Evt._Clear;
+		}
+		this.btnResetEl = tf_Id(this.prfxResetSpan+this.id).firstChild;	
+	},
+	
+	RemoveResetBtn: function()
+	/*====================================================
+		- Removes reset button
+	=====================================================*/
+	{
+		if(!this.hasGrid) return;
+		if( this.btnResetEl==null ) return;
+		var resetspan = tf_Id(this.prfxResetSpan+this.id);
+		if( resetspan!=null )
+			resetspan.parentNode.removeChild( resetspan );
+		this.btnResetEl = null;	
+	},
+	
+	RemoveExternalFlts: function()
+	/*====================================================
+		- removes external filters
+	=====================================================*/
+	{
+		if( !this.isExternalFlt && !this.externalFltTgtIds ) return;
+		for(var ct=0; ct<this.externalFltTgtIds.length; ct++ )
+			if( tf_Id(this.externalFltTgtIds[ct]) )
+				tf_Id(this.externalFltTgtIds[ct]).innerHTML = '';
+	},
+	
+	SetSort: function()
+	/*====================================================
+		- Sets sorting feature by loading 
+		WebFX Sortable Table 1.12 by Erik Arvidsson
+		and TF adapter by Max Guglielmi
+	=====================================================*/
+	{
+		if(tf_isImported(this.sortConfig.src))
+			this.Evt._EnableSort();
+		else
+			this.IncludeFile(
+				this.sortConfig.name, 
+				this.sortConfig.src, 
+				this.Evt._EnableSort
+			);
+	},
+	
+	RemoveSort: function()
+	/*====================================================
+		- removes sorting feature
+	=====================================================*/
+	{
+		if(!this.sort) return;
+		this.sort = false;
+	},
+	
+	PopulateSelect: function(colIndex,isExternal,extSlcId)
+	{ 
+		this.EvtManager(
+			this.Evt.name.populateselect,
+			{ slcIndex:colIndex, slcExternal:isExternal, slcId:extSlcId }
+		); 
+	},
+	_PopulateSelect: function(colIndex,isRefreshed,isExternal,extSlcId)
+	/*====================================================
+		- populates drop-down filters
+	=====================================================*/
+	{
+		isExternal = (isExternal==undefined) ? false : isExternal;
+		var slcId = this.fltIds[colIndex];
+		if( tf_Id(slcId)==null && !isExternal ) return;
+		if( tf_Id(extSlcId)==null && isExternal ) return;
+		var slc = (!isExternal) ? tf_Id(slcId) : tf_Id(extSlcId);
+		var o = this, row = this.tbl.rows;
+		var fillMethod = this.slcFillingMethod.tf_LCase();
+		var optArray = [], slcInnerHtml = '', opt0;
+		var isCustomSlc = (this.hasCustomSlcOptions  //custom select test
+							&& this.customSlcOptions.cols.tf_Has(colIndex));
+		var optTxt = []; //custom selects text
+		var activeFlt;
+		if(isRefreshed && this.activeFilterId){
+			activeFlt = this.activeFilterId.split('_')[0];
+			activeFlt = activeFlt.split(this.prfxFlt)[1];
+		}
+
+		/*** remember grid values ***/
+		var flts_values = [], fltArr = [];
+		if(this.rememberGridValues)
+		{
+			flts_values = tf_CookieValueArray(this.fltsValuesCookie);			
+			fltArr = (flts_values[colIndex]!=undefined) 
+						? flts_values[colIndex].split(' '+this.orOperator+' ') 
+						: flts_values[colIndex] = [];			
+		}
+
+		for(var k=this.refRow; k<this.nbRows; k++)
+		{
+			// always visible rows don't need to appear on selects as always valid
+			if( this.hasVisibleRows && this.visibleRows.tf_Has(k) && !this.paging ) 
+				continue;
+
+			var cell = tf_Tag(row[k],'td');
+			var nchilds = cell.length;
+
+			if(nchilds == this.nbCells && !isCustomSlc)
+			{// checks if row has exact cell #
+				for(var j=0; j<nchilds; j++)// this loop retrieves cell data
+				{
+					if((colIndex==j && !isRefreshed) || 
+						(colIndex==j && isRefreshed && ((row[k].style.display == '' && !this.paging) || 
+						( this.paging && (!this.validRowsIndex || (this.validRowsIndex && this.validRowsIndex.tf_Has(k)))
+							&& ((activeFlt==undefined || activeFlt==colIndex)  || (activeFlt!=colIndex && this.validRowsIndex.tf_Has(k) ))) )))
+					{
+						var cell_data = this.GetCellData(j, cell[j]);
+						var cell_string = cell_data.tf_MatchCase(this.matchCase);//Váry Péter's patch
+						// checks if celldata is already in array
+						var isMatched = false;
+						isMatched = optArray.tf_Has(cell_string,this.matchCase);
+						
+						if(!isMatched)
+							optArray.push(cell_data);						
+					}//if colIndex==j
+				}//for j
+			}//if
+		}//for k
+		
+		//Retrieves custom values
+		if(isCustomSlc)
+		{
+			var customValues = this.__getCustomValues(colIndex);
+			optArray = customValues[0];
+			optTxt = customValues[1];
+		}
+		
+		if(this.sortSlc && !isCustomSlc)
+			optArray.sort(this.matchCase ? null : tf_IgnoreCaseSort);
+		
+		if(this.sortNumAsc && this.sortNumAsc.tf_Has(colIndex))
+		{//asc sort
+			try{
+				optArray.sort( tf_NumSortAsc ); 
+				if(isCustomSlc) optTxt.sort( tf_NumSortAsc );
+			} catch(e) {
+				optArray.sort(); 
+				if(isCustomSlc) optTxt.sort();
+			}//in case there are alphanumeric values
+		}
+		if(this.sortNumDesc && this.sortNumDesc.tf_Has(colIndex))
+		{//desc sort
+			try{
+				optArray.sort( tf_NumSortDesc ); 
+				if(isCustomSlc) optTxt.sort( tf_NumSortDesc );
+			} catch(e) {
+				optArray.sort(); 
+				if(isCustomSlc) optTxt.sort();
+			}//in case there are alphanumeric values
+		}
+		
+		AddOpts();//populates drop-down
+		
+		function AddOpt0()
+		{// adds 1st option
+			if( fillMethod == 'innerhtml' )
+				slcInnerHtml += '<option value="">'+o.displayAllText+'</option>';
+			else {
+				var opt0 = tf_CreateOpt(o.displayAllText,'');			
+				slc.appendChild(opt0);
+			}
+		}
+		
+		function AddOpts()
+		{// populates select
+			var slcValue = slc.value;
+			slc.innerHTML = '';
+			AddOpt0();			
+			
+			for(var y=0; y<optArray.length; y++)
+			{			
+				if( fillMethod == 'innerhtml' )
+				{
+					var slcAttr = '';
+					var slcCustomTxt = (isCustomSlc) ? optTxt[y] : optArray[y];
+					if( o.fillSlcOnDemand && slcValue==optArray[y] )
+						slcAttr = 'selected="selected"';
+					slcInnerHtml += '<option value="'+optArray[y]+'" '
+										+slcAttr+'>'+slcCustomTxt+'</option>';
+				} else {
+					var opt;
+					//fill select on demand
+					if(o.fillSlcOnDemand && slcValue==optArray[y] && o['col'+colIndex]==o.fltTypeSlc)
+						opt = tf_CreateOpt( (isCustomSlc) ? optTxt[y] : optArray[y],
+											optArray[y],
+											true );
+					else{
+						if( o['col'+colIndex]!=o.fltTypeMulti )
+							opt = tf_CreateOpt( (isCustomSlc) ? optTxt[y] : optArray[y],
+												optArray[y],
+												(flts_values[colIndex]!=' ' && optArray[y]==flts_values[colIndex]) 
+												? true : false 	);
+						else
+						{
+							opt = tf_CreateOpt( (isCustomSlc) ? optTxt[y] : optArray[y],
+												optArray[y],
+												(fltArr.tf_Has(optArray[y].tf_MatchCase(o.matchCase),o.matchCase)) 
+												? true : false 	);
+						}
+					}
+					slc.appendChild(opt);
+				}
+			}// for y
+
+			if( fillMethod == 'innerhtml' )
+				slc.innerHTML += slcInnerHtml;
+				
+			slc.setAttribute('filled','1');
+		}// fn AddOpt
+	},
+	
+	PopulateCheckList: function(colIndex, isExternal, extFltId)
+	{
+		this.EvtManager(
+			this.Evt.name.populatechecklist,
+			{ slcIndex:colIndex, slcExternal:isExternal, slcId:extFltId }
+		); 
+	},
+	_PopulateCheckList: function(colIndex, isExternal, extFltId)
+	/*====================================================
+		- populates checklist filters
+	=====================================================*/
+	{
+		isExternal = (isExternal==undefined) ? false : isExternal;
+		var divFltId = this.prfxCheckListDiv+colIndex+'_'+this.id;
+		if( tf_Id(divFltId)==null && !isExternal ) return;
+		if( tf_Id(extFltId)==null && isExternal ) return;
+		var flt = (!isExternal) ? this.checkListDiv[colIndex] : tf_Id(extFltId);
+		var ul = tf_CreateElm('ul',['id',this.fltIds[colIndex]],['colIndex',colIndex]);
+		ul.className = this.checkListCssClass;
+		ul.onchange = this.Evt._OnSlcChange;
+		var o = this, row = this.tbl.rows;
+		var optArray = [];
+		var isCustomSlc = (this.hasCustomSlcOptions  //custom select test
+							&& this.customSlcOptions.cols.tf_Has(colIndex));
+		var optTxt = []; //custom selects text
+		var activeFlt;
+		if(this.refreshFilters && this.activeFilterId){
+			activeFlt = this.activeFilterId.split('_')[0];
+			activeFlt = activeFlt.split(this.prfxFlt)[1];
+		}		
+		
+		for(var k=this.refRow; k<this.nbRows; k++)
+		{
+			// always visible rows don't need to appear on selects as always valid
+			if( this.hasVisibleRows && this.visibleRows.tf_Has(k) && !this.paging ) 
+				continue;
+
+			var cells = tf_Tag(row[k],'td');
+			var ncells = cells.length;
+
+			if(ncells == this.nbCells && !isCustomSlc)
+			{// checks if row has exact cell #
+				for(var j=0; j<ncells; j++)
+				{// this loop retrieves cell data
+					if((colIndex==j && !this.refreshFilters) || 
+						(colIndex==j && this.refreshFilters && ((row[k].style.display == '' && !this.paging) || 
+						( this.paging && ((activeFlt==undefined || activeFlt==colIndex ) ||(activeFlt!=colIndex && this.validRowsIndex.tf_Has(k))) ))))
+					{
+						var cell_data = this.GetCellData(j, cells[j]);
+						var cell_string = cell_data.tf_MatchCase(this.matchCase);//Váry Péter's patch
+						// checks if celldata is already in array
+						var isMatched = false;
+						isMatched = optArray.tf_Has(cell_string,this.matchCase);
+						
+						if(!isMatched)
+							optArray.push(cell_data);
+					}
+				}
+			}
+		}
+		
+		//Retrieves custom values
+		if(isCustomSlc)
+		{
+			var customValues = this.__getCustomValues(colIndex);
+			optArray = customValues[0];
+			optTxt = customValues[1];
+		}
+		
+		if(this.sortSlc && !isCustomSlc)
+			optArray.sort(this.matchCase ? null : tf_IgnoreCaseSort);
+		
+		if(this.sortNumAsc && this.sortNumAsc.tf_Has(colIndex))
+		{//asc sort
+			try{
+				optArray.sort( tf_NumSortAsc ); 
+				if(isCustomSlc) optTxt.sort( tf_NumSortAsc );
+			} catch(e) {
+				optArray.sort(); 
+				if(isCustomSlc) optTxt.sort();
+			}//in case there are alphanumeric values
+		}
+		if(this.sortNumDesc && this.sortNumDesc.tf_Has(colIndex))
+		{//desc sort
+			try{
+				optArray.sort( tf_NumSortDesc ); 
+				if(isCustomSlc) optTxt.sort( tf_NumSortDesc );
+			} catch(e) {
+				optArray.sort(); 
+				if(isCustomSlc) optTxt.sort();
+			}//in case there are alphanumeric values
+		}
+
+		AddChecks();
+			
+		function AddCheck0()
+		{// adds 1st option
+			var li0 = tf_CreateCheckItem(o.fltIds[colIndex]+'_0', '', o.displayAllText);
+			li0.className = o.checkListItemCssClass;
+			ul.appendChild(li0);
+			li0.check.onclick = function(){  
+				o.__setCheckListValues(this); 
+								
+				if(o.refreshFilters){
+					//o.activeFilterId = '';
+					//o.RefreshFiltersGrid();
+				}
+				else
+				ul.onchange.call(null);
+			};
+			
+			if(tf_isIE)
+			{//IE: label looses check capability
+				li0.label.onclick = function(){ li0.check.click(); };
+			}
+		}
+		
+		function AddChecks()
+		{		
+			AddCheck0();
+			
+			var flts_values = [], fltArr = []; //remember grid values
+			if(tf_CookieValueByIndex(o.fltsValuesCookie, colIndex)!=undefined)
+				fltArr = tf_CookieValueByIndex(o.fltsValuesCookie, colIndex).split(' '+o.orOperator+' ');
+
+			for(var y=0; y<optArray.length; y++)
+			{
+				var li = tf_CreateCheckItem(
+					o.fltIds[colIndex]+'_'+(y+1), 
+					optArray[y], 
+					(isCustomSlc) ? optTxt[y] : optArray[y]
+				);
+				li.className = o.checkListItemCssClass;
+				ul.appendChild(li);
+				li.check.onclick = function(){ o.__setCheckListValues(this); ul.onchange.call(null); };
+				
+				/*** remember grid values ***/
+				if(o.rememberGridValues)
+				{
+					if(fltArr.tf_Has(optArray[y].tf_MatchCase(o.matchCase),o.matchCase))
+					{
+						li.check.checked = true;
+						o.__setCheckListValues(li.check);
+					}			
+				}
+				
+				if(tf_isIE)
+				{//IE: label looses check capability
+					li.label.onclick = function(){ this.firstChild.click(); };	
+				}
+			}
+		}
+		
+		if(this.fillSlcOnDemand)
+			flt.innerHTML = '';
+		flt.appendChild(ul);
+		flt.setAttribute('filled','1');
+		
+		/*** remember grid values IE only, items remain un-checked ***/
+		if(o.rememberGridValues && tf_isIE)
+		{
+			var slcIndexes = ul.getAttribute('indexes');
+			if(slcIndexes != null)
+			{
+				var indSplit = slcIndexes.split(',');//items indexes
+				for(var n=0; n<indSplit.length; n++)
+				{
+					var cChk = tf_Id(this.fltIds[colIndex]+'_'+indSplit[n]); //checked item
+					if(cChk) cChk.checked = true;
+				}
+			}
+		}
+	},
+	
+	Filter: function()
+	{
+		this.EvtManager(this.Evt.name.filter); 
+	},
+	_Filter: function()
+	/*====================================================
+		- Filtering fn
+		- retrieves data from each td in every single tr
+		and compares to search string for current
+		column
+		- tr is hidden if all search strings are not 
+		found
+	=====================================================*/
+	{
+		if( !this.fltGrid || (!this.hasGrid && !this.isFirstLoad) ) return;
+		//invokes eventual onbefore method
+		if(this.onBeforeFilter) this.onBeforeFilter.call(null,this);
+		var row = this.tbl.rows;	
+		f = this.fObj!=undefined ? this.fObj : [];
+		var hiddenrows = 0;
+		this.validRowsIndex = [];
+		var o = this;		
+		
+		// removes keyword highlighting
+		this.UnhighlightAll();
+
+		// search args re-init
+		this.searchArgs = this.GetFiltersValue(); 
+		
+		var num_cell_data, nbFormat;
+		var re_le = new RegExp(this.leOperator), re_ge = new RegExp(this.geOperator);
+		var re_l = new RegExp(this.lwOperator), re_g = new RegExp(this.grOperator);
+		var re_d = new RegExp(this.dfOperator), re_lk = new RegExp(tf_RegexpEscape(this.lkOperator));
+		var re_eq = new RegExp(this.eqOperator), re_st = new RegExp(this.stOperator);
+		var re_en = new RegExp(this.enOperator), re_an = new RegExp(this.anOperator);
+		var re_cr = new RegExp(this.curExp);
+		
+		function highlight(str,ok,cell){//keyword highlighting
+			if( o.highlightKeywords && ok ){
+				str = str.replace(re_lk,'');
+				str = str.replace(re_eq,'');
+				str = str.replace(re_st,'');
+				str = str.replace(re_en,'');
+				var w = str;
+				if(re_le.test(str) || re_ge.test(str) || re_l.test(str) || re_g.test(str) || re_d.test(str))	
+					w = tf_GetNodeText(cell);
+				if(w!='')
+					tf_HighlightWord( cell,w,o.highlightCssClass );
+			}
+		}
+		
+		//looks for search argument in current row
+		function hasArg(sA,cell_data,j)
+		{
+			var occurence;
+			//Search arg operator tests
+			var hasLO = re_l.test(sA), hasLE = re_le.test(sA);
+			var hasGR = re_g.test(sA), hasGE = re_ge.test(sA);
+			var hasDF = re_d.test(sA), hasEQ = re_eq.test(sA);
+			var hasLK = re_lk.test(sA), hasAN = re_an.test(sA);
+			var hasST = re_st.test(sA), hasEN = re_en.test(sA);
+			
+			//Search arg dates tests
+			var isLDate = ( hasLO && tf_isValidDate(sA.replace(re_l,''),dtType) );
+			var isLEDate = ( hasLE && tf_isValidDate(sA.replace(re_le,''),dtType) );
+			var isGDate = ( hasGR && tf_isValidDate(sA.replace(re_g,''),dtType) );
+			var isGEDate = ( hasGE && tf_isValidDate(sA.replace(re_ge,''),dtType) );
+			var isDFDate = ( hasDF && tf_isValidDate(sA.replace(re_d,''),dtType) );
+			var isEQDate = ( hasEQ && tf_isValidDate(sA.replace(re_eq,''),dtType) );
+						
+			if( tf_isValidDate(cell_data,dtType) )
+			{//dates
+				var dte1 = tf_formatDate(cell_data,dtType);
+				if(isLDate) 
+				{// lower date
+					var dte2 = tf_formatDate(sA.replace(re_l,''),dtType);
+					occurence = (dte1 < dte2);
+				}
+				else if(isLEDate) 
+				{// lower equal date
+					var dte2 = tf_formatDate(sA.replace(re_le,''),dtType);
+					occurence = (dte1 <= dte2);
+				}
+				else if(isGEDate) 
+				{// greater equal date
+					var dte2 = tf_formatDate(sA.replace(re_ge,''),dtType);
+					occurence = (dte1 >= dte2);
+				}
+				else if(isGDate) 
+				{// greater date
+					var dte2 = tf_formatDate(sA.replace(re_g,''),dtType);
+					occurence = (dte1 > dte2);
+				}
+				else if(isDFDate) 
+				{// different date
+					var dte2 = tf_formatDate(sA.replace(re_d,''),dtType);
+					occurence = (dte1.toString() != dte2.toString());
+				}
+				else if(isEQDate) 
+				{// equal date
+					var dte2 = tf_formatDate(sA.replace(re_eq,''),dtType);
+					occurence = (dte1.toString() == dte2.toString());
+				}
+				else if(re_lk.test(sA)) // searched keyword with * operator doesn't have to be a date
+				{// like date
+					occurence = o.__containsStr( sA.replace(re_lk,''),cell_data,null,false);
+				}
+				else if(tf_isValidDate(sA,dtType))
+				{
+					var dte2 = tf_formatDate(sA,dtType);
+					occurence = (dte1.toString() == dte2.toString());
+				}
+			}
+			
+			else 
+			{						
+				//first numbers need to be formated
+				if(o.hasColNbFormat && o.colNbFormat[j]!=null)
+				{
+					num_cell_data = tf_removeNbFormat(cell_data,o.colNbFormat[j]);
+					nbFormat = o.colNbFormat[j];
+				} else {
+					if(o.thousandsSeparator==',' && o.decimalSeparator=='.')
+					{
+						num_cell_data = tf_removeNbFormat(cell_data,'us');
+						nbFormat = 'us';
+					} else {
+						num_cell_data = tf_removeNbFormat(cell_data,'eu');
+						nbFormat = 'eu';
+					}
+				}
+				
+				// first checks if there is any operator (<,>,<=,>=,!,*,=,{,})
+				if(hasLE) //lower equal
+					occurence = num_cell_data <= tf_removeNbFormat(sA.replace(re_le,''),nbFormat);
+				
+				else if(hasGE) //greater equal
+					occurence = num_cell_data >= tf_removeNbFormat(sA.replace(re_ge,''),nbFormat);
+				
+				else if(hasLO) //lower
+					occurence = num_cell_data < tf_removeNbFormat(sA.replace(re_l,''),nbFormat);
+					
+				else if(hasGR) //greater
+					occurence = num_cell_data > tf_removeNbFormat(sA.replace(re_g,''),nbFormat);							
+					
+				else if(hasDF) //different
+					occurence = o.__containsStr( sA.replace(re_d,''),cell_data ) ? false : true;
+			
+				else if(hasLK) //like
+					occurence = o.__containsStr( sA.replace(re_lk,''),cell_data,null,false);
+				
+				else if(hasEQ) //equal
+					occurence = o.__containsStr( sA.replace(re_eq,''),cell_data,null,true);
+				
+				else if(hasST) //starts with
+					occurence = cell_data.indexOf(sA.replace(re_st,''))==0 ? true : false;
+				
+				else if(hasEN) //ends with
+				{
+					var searchArg = sA.replace(re_en,'');
+					occurence = cell_data.lastIndexOf(searchArg,cell_data.length-1)==(cell_data.length-1)-(searchArg.length-1)
+						&& cell_data.lastIndexOf(searchArg,cell_data.length-1) > -1
+						? true : false;
+				}
+				
+				else
+					occurence = o.__containsStr( sA,cell_data,(f['col_'+j]==undefined) ? this.fltTypeInp : f['col_'+j] );
+				
+			}//else
+			return occurence;
+		}//fn
+		
+		for(var k=this.refRow; k<this.nbRows; k++)
+		{
+			/*** if table already filtered some rows are not visible ***/
+			if(row[k].style.display == 'none') row[k].style.display = '';
+					
+			var cell = tf_Tag(row[k],'td');
+			var nchilds = cell.length;			
+			
+			// checks if row has exact cell #
+			if(nchilds != this.nbCells) continue;
+	
+			var occurence = [];
+			var isRowValid = (this.searchType=='include') ? true : false;
+			var singleFltRowValid = false; //only for single filter search
+			
+			for(var j=0; j<nchilds; j++)
+			{// this loop retrieves cell data
+				var sA = this.searchArgs[(this.singleSearchFlt) ? 0 : j]; //searched keyword
+				var dtType = (this.hasColDateType) ? this.colDateType[j] : this.defaultDateType;
+				if(sA=='') continue;
+				
+				var cell_data = this.GetCellData(j, cell[j]).tf_MatchCase(this.matchCase);
+	
+				var sAOrSplit = sA.split(this.orOperator);//multiple search parameter operator ||
+				var hasMultiOrSA = (sAOrSplit.length>1) ? true : false;//multiple search || parameter boolean
+				var sAAndSplit = sA.split('&&');//multiple search parameter operator &&
+				var hasMultiAndSA = (sAAndSplit.length>1) ? true : false;//multiple search && parameter boolean
+
+				if(hasMultiOrSA || hasMultiAndSA)
+				{//multiple sarch parameters
+					var cS, occur = false;
+					var s = (hasMultiOrSA) ? sAOrSplit : sAAndSplit;
+					for(var w=0; w<s.length; w++)
+					{
+						cS = s[w].tf_Trim();
+						occur = hasArg(cS,cell_data,j);
+						highlight(cS,occur,cell[j]);
+						if(hasMultiOrSA && occur) break;
+						if(hasMultiAndSA && !occur) break;
+					}
+					occurence[j] = occur;
+				}
+				else {//single search parameter		
+					occurence[j] = hasArg(sA.tf_Trim(),cell_data,j);
+					highlight(sA,occurence[j],cell[j]);
+				}//else single param
+				
+				if(!occurence[j]) isRowValid = (this.searchType=='include') ? false : true;
+				if(this.singleSearchFlt && occurence[j]) singleFltRowValid = true;
+				
+			}//for j
+			
+			if(this.singleSearchFlt && singleFltRowValid) isRowValid = true;
+			
+			if(!isRowValid)
+			{
+				this.SetRowValidation(k,false);
+				// always visible rows need to be counted as valid
+				if( this.hasVisibleRows && this.visibleRows.tf_Has(k) && !this.paging)
+					this.validRowsIndex.push(k);
+				else
+					hiddenrows++;
+			} else {
+				this.SetRowValidation(k,true);
+				this.validRowsIndex.push(k);
+				this.SetRowBg(k,this.validRowsIndex.length);
+				if(this.onRowValidated) this.onRowValidated.call(null,this,k);
+			}
+			
+		}// for k
+		
+		this.nbVisibleRows = this.validRowsIndex.length;
+		this.nbHiddenRows = hiddenrows;
+		this.isStartBgAlternate = false;
+		if( this.rememberGridValues ) this.RememberFiltersValue(this.fltsValuesCookie);
+		if(!this.paging) this.ApplyGridProps();//applies filter props after filtering process
+		if(this.paging){ 
+			this.startPagingRow = 0; 
+			this.currentPageNb = 1;
+			this.SetPagingInfo(this.validRowsIndex); 
+		}//starts paging process
+		//invokes eventual onafter function
+		if(this.onAfterFilter) this.onAfterFilter.call(null,this);
+	},
+	
+	SetPagingInfo: function( validRows )
+	/*====================================================
+		- calculates page # according to valid rows
+		- refreshes paging select according to page #
+		- Calls GroupByPage method
+	=====================================================*/
+	{
+		var row = this.tbl.rows;
+		var mdiv = ( this.pagingTgtId==null ) ? this.mDiv : tf_Id( this.pagingTgtId );
+		var pgspan = tf_Id(this.prfxPgSpan+this.id);
+		
+		if( validRows!=undefined ) this.validRowsIndex = validRows;//stores valid rows index
+		else 
+		{
+			this.validRowsIndex = [];//re-sets valid rows index
+	
+			for(var j=this.refRow; j<this.nbRows; j++)//counts rows to be grouped 
+			{
+				var isRowValid = row[j].getAttribute('validRow');
+				if(isRowValid=='true' || isRowValid==null )
+						this.validRowsIndex.push(j);
+			}//for j
+		}
+	
+		this.nbPages = Math.ceil( this.validRowsIndex.length/this.pagingLength );//calculates nb of pages
+		pgspan.innerHTML = this.nbPages; //refresh page nb span 
+		if(this.pageSelectorType==this.fltTypeSlc) 
+			this.pagingSlc.innerHTML = '';//select clearing shortcut
+		
+		if( this.nbPages>0 )
+		{
+			mdiv.style.visibility = 'visible';
+			if(this.pageSelectorType==this.fltTypeSlc)
+				for(var z=0; z<this.nbPages; z++)
+				{
+					var currOpt = new Option((z+1),z*this.pagingLength,false,false);
+					this.pagingSlc.options[z] = currOpt;
+				}
+			else this.pagingSlc.value = this.currentPageNb; //input type
+			
+		} else {/*** if no results paging select and buttons are hidden ***/
+			mdiv.style.visibility = 'hidden';
+		}
+		this.GroupByPage( this.validRowsIndex );
+	},
+	
+	GroupByPage: function( validRows )
+	/*====================================================
+		- Displays current page rows
+	=====================================================*/
+	{
+		var row = this.tbl.rows;
+		var paging_end_row = parseInt( this.startPagingRow ) + parseInt( this.pagingLength );
+		
+		if( validRows!=undefined ) this.validRowsIndex = validRows;//stores valid rows index
+	
+		for(h=0; h<this.validRowsIndex.length; h++)
+		{//this loop shows valid rows of current page
+			if( h>=this.startPagingRow && h<paging_end_row )
+			{
+				var r = row[ this.validRowsIndex[h] ];
+				if(r.getAttribute('validRow')=='true' || r.getAttribute('validRow')==undefined)
+					r.style.display = '';
+				this.SetRowBg(this.validRowsIndex[h],h);
+			} else {
+				row[ this.validRowsIndex[h] ].style.display = 'none';
+				this.RemoveRowBg(this.validRowsIndex[h]);
+			}
+		}
+		
+		this.nbVisibleRows = this.validRowsIndex.length;
+		this.isStartBgAlternate = false;
+		this.ApplyGridProps();//re-applies filter behaviours after filtering process
+	},
+	
+	ApplyGridProps: function()
+	/*====================================================
+		- checks methods that should be called
+		after filtering and/or paging process
+	=====================================================*/
+	{
+		if( this.activeFlt && this.activeFlt.nodeName.tf_LCase()==this.fltTypeSlc )
+		{// blurs active filter (IE)
+			this.activeFlt.blur(); 
+			if(this.activeFlt.parentNode) this.activeFlt.parentNode.focus(); 
+		}
+		
+		if( this.visibleRows ) this.SetVisibleRows();//shows rows always visible
+		if( this.colOperation ) this.SetColOperation();//makes operation on a col
+		if( this.refreshFilters ) this.RefreshFiltersGrid();//re-populates drop-down filters
+		var nr = (!this.paging && this.hasVisibleRows) 
+					? (this.nbVisibleRows - this.visibleRows.length) : this.nbVisibleRows;
+		if( this.rowsCounter ) this.RefreshNbRows( nr );//refreshes rows counter
+	},
+	
+	RefreshNbRows: function(p)
+	/*====================================================
+		- Shows total number of filtered rows
+	=====================================================*/
+	{
+		if(this.rowsCounterSpan == null) return;
+		var totTxt;
+		if(!this.paging)
+		{
+			if(p!=undefined && p!='') totTxt=p;
+			else totTxt = (this.nbFilterableRows - this.nbHiddenRows - (this.hasVisibleRows ? this.visibleRows.length : 0) );
+		} else {
+			var paging_start_row = parseInt(this.startPagingRow)+((this.nbVisibleRows>0) ? 1 : 0);//paging start row
+			var paging_end_row = (paging_start_row+this.pagingLength)-1 <= this.nbVisibleRows 
+				? (paging_start_row+this.pagingLength)-1 : this.nbVisibleRows;
+			totTxt = paging_start_row+'-'+paging_end_row+' / '+this.nbVisibleRows;
+		} 
+		this.rowsCounterSpan.innerHTML = totTxt;
+	},
+	
+	ChangePage: function( index )
+	{
+		this.EvtManager(this.Evt.name.changepage,{ pgIndex:index });
+	},
+	_ChangePage: function( index )
+	/*====================================================
+		- Changes page
+		- Param:
+			- index: option index of paging select 
+			(numeric value)
+	=====================================================*/
+	{
+		if( !this.paging ) return;
+		if( index==undefined ) 
+			index = (this.pageSelectorType==this.fltTypeSlc) ? 
+				this.pagingSlc.options.selectedIndex : (this.pagingSlc.value-1);
+		if( index>=0 && index<=(this.nbPages-1) )
+		{
+			this.currentPageNb = parseInt(index)+1;
+			if(this.pageSelectorType==this.fltTypeSlc)
+				this.pagingSlc.options[index].selected = true;
+			else
+				this.pagingSlc.value = this.currentPageNb;
+
+			if( this.rememberPageNb ) this.RememberPageNb( this.pgNbCookie );
+			this.startPagingRow = (this.pageSelectorType==this.fltTypeSlc)
+				? this.pagingSlc.value : (index*this.pagingLength);
+			this.GroupByPage();
+		}
+	},
+	
+	ChangeResultsPerPage: function()
+	{
+		this.EvtManager(this.Evt.name.changeresultsperpage);
+	},
+	_ChangeResultsPerPage: function()
+	/*====================================================
+		- calculates rows to be displayed in a page
+		- method called by nb results per page select
+	=====================================================*/
+	{
+		if( !this.paging ) return;
+		var slcR = this.resultsPerPageSlc;
+		var slcPagesSelIndex = (this.pageSelectorType==this.fltTypeSlc) 
+			? this.pagingSlc.selectedIndex : parseInt(this.pagingSlc.value-1);
+		this.pagingLength = parseInt(slcR.options[slcR.selectedIndex].value);
+		this.startPagingRow = this.pagingLength*slcPagesSelIndex;
+
+		if( !isNaN(this.pagingLength) )
+		{
+			if( this.startPagingRow>=this.nbFilterableRows )
+				this.startPagingRow = (this.nbFilterableRows-this.pagingLength);
+			this.SetPagingInfo();
+
+			if(this.pageSelectorType==this.fltTypeSlc)
+			{
+				var slcIndex = (this.pagingSlc.options.length-1<=slcPagesSelIndex ) 
+								? (this.pagingSlc.options.length-1) : slcPagesSelIndex;
+				this.pagingSlc.options[slcIndex].selected = true;
+			}
+			if( this.rememberPageLen ) this.RememberPageLength( this.pgLenCookie );
+		}//if isNaN
+	},
+	
+	Sort: function()
+	{
+		this.EvtManager(this.Evt.name.sort);
+	},
+	
+	GetColValues: function(colindex,num,exclude)
+	/*====================================================
+		- returns an array containing cell values of
+		a column
+		- needs following args:
+			- column index (number)
+			- a boolean set to true if we want only 
+			numbers to be returned
+			- array containing rows index to be excluded
+			from returned values
+	=====================================================*/
+	{
+		if( !this.fltGrid ) return;
+		var row = this.tbl.rows;
+		var colValues = [];
+	
+		for(var i=this.refRow; i<this.nbRows; i++)//iterates rows
+		{
+			var isExludedRow = false;
+			if(exclude!=undefined && (typeof exclude).tf_LCase()=='object')
+			{ // checks if current row index appears in exclude array
+				isExludedRow = exclude.tf_Has(i); //boolean
+			}
+			var cell = tf_Tag(row[i],'td');
+			var nchilds = cell.length;
+			
+			if(nchilds == this.nbCells && !isExludedRow)
+			{// checks if row has exact cell # and is not excluded
+				for(var j=0; j<nchilds; j++)// this loop retrieves cell data
+				{
+					if(j==colindex && row[i].style.display=='' )
+					{
+						var cell_data = this.GetCellData(j, cell[j]).tf_LCase();
+						var nbFormat = this.colNbFormat ? this.colNbFormat[colindex] : null;
+						(num) ? colValues.push( tf_removeNbFormat(cell_data,nbFormat) ) 
+								: colValues.push( cell_data );
+					}//if j==k
+				}//for j
+			}//if nchilds == this.nbCells
+		}//for i
+		return colValues;	
+	},
+	
+	GetFilterValue: function(index)
+	/*====================================================
+		- Returns value of a specified filter
+		- Params:
+			- index: filter column index (numeric value)
+	=====================================================*/
+	{
+		if( !this.fltGrid ) return;
+		var fltValue;
+		var flt = tf_Id(this.fltIds[index]);
+		if(flt==null) return fltValue='';
+		
+		if( this['col'+index]!=this.fltTypeMulti && 
+			this['col'+index]!=this.fltTypeCheckList )
+			fltValue = flt.value;
+		else if(this['col'+index] == this.fltTypeMulti)
+		{//mutiple select
+			fltValue = '';
+			for(var j=0; j<flt.options.length; j++) 
+				if(flt.options[j].selected)
+					fltValue = fltValue.concat(
+								flt.options[j].value+' ' +
+								this.orOperator + ' '
+								);
+			//removes last operator ||
+			fltValue = fltValue.substr(0,fltValue.length-4);
+		}
+		else if(this['col'+index]==this.fltTypeCheckList)
+		{//checklist
+			if(flt.getAttribute('value')!=null)
+			{
+				fltValue = flt.getAttribute('value');
+				//removes last operator ||
+				fltValue = fltValue.substr(0,fltValue.length-3);
+			} else fltValue = '';
+		}			
+		return fltValue;
+	},
+	
+	GetFiltersValue: function()
+	/*====================================================
+		- Returns the value of every single filter
+	=====================================================*/
+	{
+		if( !this.fltGrid ) return;
+		var searchArgs = [];
+		for(var i=0; i<this.fltIds.length; i++)
+			searchArgs.push(
+				this.GetFilterValue(i).tf_MatchCase(this.matchCase).tf_Trim()
+			);
+		return searchArgs;
+	},
+	
+	GetFilterId: function(index)
+	/*====================================================
+		- Returns filter id of a specified column
+		- Params:
+			- index: column index (numeric value)
+	=====================================================*/
+	{
+		if( !this.fltGrid ) return;
+		return this.fltIds[i];
+	},
+	
+	GetFiltersByType: function(type,bool)
+	/*====================================================
+		- returns an array containing ids of filters of a 
+		specified type (inputs or selects)
+		- Note that hidden filters are also returned
+		- Needs folllowing args:
+			- filter type string ('input','select',
+			'multiple')
+			- optional boolean: if set true method
+			returns column indexes otherwise filters ids
+	=====================================================*/
+	{
+		if( !this.fltGrid ) return;
+		var arr = [];
+		for(var i=0; i<this.fltIds.length; i++)
+		{
+			var fltType = this['col'+i];
+			if(fltType == type.tf_LCase())
+			{
+				var a = (bool) ? i : this.fltIds[i];
+				arr.push(a);
+			}
+		}
+		return arr;
+	},
+	
+	GetCellsNb: function( rowIndex )
+	/*====================================================
+		- returns number of cells in a row
+		- if rowIndex param is passed returns number of 
+		cells of specified row (number)
+	=====================================================*/
+	{
+		var tr = (rowIndex == undefined) ? this.tbl.rows[0] : this.tbl.rows[rowIndex];
+		var n = tf_GetChildElms(tr);
+		return n.childNodes.length;
+	},
+	
+	GetRowsNb: function()
+	/*====================================================
+		- returns total nb of filterable rows starting 
+		from reference row if defined
+	=====================================================*/
+	{
+		var s = this.refRow==undefined ? 0 : this.refRow;
+		var ntrs = this.tbl.rows.length;
+		return parseInt(ntrs-s);
+	},
+	
+	GetCellData: function(i, cell)
+	/*====================================================
+		- returns text content of a given cell
+		- Params:
+			- i: index of the column (number)
+			- cell: td DOM object
+	=====================================================*/
+	{
+		if(i==undefined || cell==null) return "";
+		//First checks for customCellData event
+		if(this.customCellData && this.customCellDataCols.tf_Has(i))
+			return this.customCellData.call(null,this,cell,i);
+		else
+			return tf_GetNodeText(cell);
+	},
+	
+	GetTableData: function()
+	/*====================================================
+		- returns an array containing table data:
+		[rowindex,[value1,value2,value3...]]
+	=====================================================*/
+	{
+		var row = this.tbl.rows;
+		for(var k=this.refRow; k<this.nbRows; k++)
+		{
+			var rowData, cellData;
+			rowData = [k,[]];
+			var cells = tf_Tag(row[k],'td');
+			for(var j=0; j<cells.length; j++)
+			{// this loop retrieves cell data
+				var cell_data = this.GetCellData(j, cells[j]);
+				rowData[1].push( cell_data );
+			}
+			this.tblData.push( rowData )
+		}
+		return this.tblData;
+	},
+	
+	GetFilteredData: function()
+	/*====================================================
+		- returns an array containing filtered data:
+		[rowindex,[value1,value2,value3...]]
+	=====================================================*/
+	{
+		if(!this.validRowsIndex) return [];
+		var row = this.tbl.rows;
+		var filteredData = [];
+		for(var i=0; i<this.validRowsIndex.length; i++)
+		{
+			var rowData, cellData;
+			rowData = [this.validRowsIndex[i],[]];
+			var cells = tf_Tag(row[this.validRowsIndex[i]],'td');
+			for(var j=0; j<cells.length; j++)
+			{
+				var cell_data = this.GetCellData(j, cells[j]);
+				rowData[1].push( cell_data );
+			}
+			filteredData.push(rowData);
+		}
+		return filteredData;
+	},
+	
+	GetFilteredDataCol: function(colIndex)
+	/*====================================================
+		- returns an array containing filtered data of a
+		specified column. 
+		- Params:
+			- colIndex: index of the column (number)
+		- returned array:
+		[value1,value2,value3...]
+	=====================================================*/
+	{
+		if(colIndex==undefined) return [];
+		var data =  this.GetFilteredData();
+		var colData = [];
+		for(var i=0; i<data.length; i++)
+		{
+			var r = data[i];
+			var d = r[1]; //cols values of current row
+			var c = d[colIndex]; //data of searched column
+			colData.push(c);
+		}
+		return colData;
+	},
+	
+	GetRowDisplay: function(row)
+	{
+		if( !this.fltGrid && typeof row.tf_LCase!='object' ) return;
+		return row.style.display;
+	},
+	
+	SetRowValidation: function( rowIndex,isValid )
+	/*====================================================
+		- Validates/unvalidates row by setting 'validRow' 
+		attribute and shows/hides row
+		- Params:
+			- rowIndex: index of the row (number)
+			- isValid: boolean
+	=====================================================*/
+	{
+		var row = this.tbl.rows[rowIndex];
+		if( !row || (typeof isValid).tf_LCase()!='boolean' ) return;
+	
+		// always visible rows are valid
+		if( this.hasVisibleRows && this.visibleRows.tf_Has(rowIndex) && !this.paging )
+			isValid = true;
+		
+		var displayFlag = (isValid) ? '' : 'none';
+		var validFlag = (isValid) ? 'true' : 'false';		
+		row.style.display = displayFlag;
+		
+		if( this.paging ) 
+			row.setAttribute('validRow',validFlag);
+	},
+	
+	ValidateAllRows: function()
+	/*====================================================
+		- Validates all filterable rows
+	=====================================================*/
+	{
+		if( !this.hasGrid ) return;
+		this.validRowsIndex = [];
+		for(var k=this.refRow; k<this.nbFilterableRows; k++)
+		{
+			this.SetRowValidation(k,true);
+			this.validRowsIndex.push(k);
+		}
+	},
+	
+	SetFilterValue: function(index,searcharg,doFilter)
+	/*====================================================
+		- Inserts value in a specified filter
+		- Params:
+			- index: filter column index (numeric value)
+			- searcharg: search string
+			- doFilter: optional boolean for multiple
+			selects: executes filtering when multiple 
+			select populated... IE only!
+	=====================================================*/
+	{
+		if( (!this.fltGrid && !this.isFirstLoad) || tf_Id(this.fltIds[index])==null ) return;
+		var slc = tf_Id(this.fltIds[index]);
+		var execFilter = (doFilter==undefined) ? true : doFilter;
+		searcharg = (searcharg==undefined) ? '' : searcharg;
+		
+		if( this['col'+index]!=this.fltTypeMulti && 
+			this['col'+index]!=this.fltTypeCheckList )
+			slc.value = searcharg;
+			
+		else if(this['col'+index] == this.fltTypeMulti)
+		{//multiple selects
+			var s = searcharg.split(' '+this.orOperator+' ');
+			var ct = 0; //keywords counter
+			for(var j=0; j<slc.options.length; j++) 
+			{
+				if(s=='') slc.options[j].selected = false;
+				if(slc.options[j].value=='') slc.options[j].selected = false;
+				if(slc.options[j].value!='' && s.tf_Has(slc.options[j].value,true))
+				{
+					if(tf_isIE)
+					{// IE multiple selection work-around
+						//when last value reached filtering can be executed
+						var filter = (ct==(s.length-1) && execFilter) ? true : false;
+						this.__deferMultipleSelection(slc,j,filter);
+						ct++;
+					}					
+					else
+						slc.options[j].selected = true;
+				}//if
+			}//for j
+		}
+		
+		else if(this['col'+index]==this.fltTypeCheckList)
+		{//checklist
+			searcharg = searcharg.tf_MatchCase(this.matchCase);
+			var s = searcharg.split(' '+this.orOperator+' ');
+			var fltValue = slc.setAttribute('value','');
+			var fltIndex = slc.setAttribute('indexes','');
+			for(var k=0; k<tf_Tag(slc,'li').length; k++) 
+			{
+				var li = tf_Tag(slc,'li')[k];
+				var lbl = tf_Tag(li,'label')[0];
+				var chk = tf_Tag(li,'input')[0];
+				var lblTxt = tf_GetNodeText(lbl).tf_MatchCase(this.matchCase);
+				if(lblTxt!='' && s.tf_Has(lblTxt,true))
+				{
+					chk.checked = true;
+					this.__setCheckListValues(chk);
+				}
+				else{ 
+					chk.checked = false;
+					this.__setCheckListValues(chk);
+				}
+			}
+		}
+	},
+
+	SetColWidths: function(rowIndex)
+	/*====================================================
+		- sets coluun widths in pixels
+	=====================================================*/
+	{
+		if( !this.fltGrid || !this.hasColWidth ) return;
+		var o = this, rIndex;
+		if(rowIndex==undefined) rIndex = this.tbl.rows[0].style.display!='none' ? 0 : 1;
+		else rIndex = rowIndex;
+		setWidths( this.tbl.rows[rIndex] );
+
+		function setWidths( row )
+		{
+			if( !o && (o.nbCells!=o.colWidth.length) ) return;
+			if( o.nbCells==row.cells.length )
+				for(var k=0; k<o.nbCells; k++)
+					row.cells[k].style.width = o.colWidth[k];
+		}
+	},
+	
+	SetVisibleRows: function()
+	/*====================================================
+		- makes a row always visible
+		- Note this works only if paging is false
+	=====================================================*/
+	{
+		if( this.hasGrid && this.hasVisibleRows && !this.paging )
+		{
+			for(var i=0; i<this.visibleRows.length; i++)
+			{
+				if(this.visibleRows[i]<=this.nbRows)//row index cannot be > nrows
+					this.SetRowValidation(this.visibleRows[i],true);
+			}//for i
+		}//if hasGrid
+	},
+	
+	SetRowBg: function(rIndex,index)
+	/*====================================================
+		- sets row background color
+		- Params:
+			- rIndex: row index (numeric value)
+			- index: valid row collection index needed to
+			calculate bg color
+	=====================================================*/
+	{
+		if(!this.alternateBgs || isNaN(rIndex)) return;
+		var rows = this.tbl.rows;
+		var i = (index==undefined) ? rIndex : index;
+		this.RemoveRowBg(rIndex);
+		tf_addClass(
+			rows[rIndex],
+			(i%2 == 0) ? this.rowBgEvenCssClass : this.rowBgOddCssClass
+		);
+	},
+	
+	RemoveRowBg: function(index)
+	/*====================================================
+		- removes row background color
+		- Params:
+			- index: row index (numeric value)
+	=====================================================*/
+	{
+		if(isNaN(index)) return;
+		var rows = this.tbl.rows;
+		tf_removeClass(rows[index],this.rowBgOddCssClass);
+		tf_removeClass(rows[index],this.rowBgEvenCssClass);
+	},
+	
+	SetAlternateRows: function()
+	/*====================================================
+		- alternates row colors for better readability
+	=====================================================*/
+	{
+		if( !this.hasGrid && !this.isFirstLoad ) return;
+		var rows = this.tbl.rows;
+		var noValidRowsIndex = this.validRowsIndex==null;
+		var beginIndex = (noValidRowsIndex) ? this.refRow : 0; //1st index
+		var indexLen = (noValidRowsIndex) // nb indexes
+			? (this.nbFilterableRows+beginIndex) : this.validRowsIndex.length;
+
+		for(var j=beginIndex; j<indexLen; j++)//alternates bg color
+		{
+			var rIndex = (noValidRowsIndex) ? j : this.validRowsIndex[j];
+			this.SetRowBg(rIndex);
+		}
+	},
+	
+	RemoveAlternateRows: function()
+	/*====================================================
+		- removes alternate row colors
+	=====================================================*/
+	{
+		if(!this.hasGrid) return;
+		var row = this.tbl.rows;
+		for(var i=this.refRow; i<this.nbRows; i++)
+			this.RemoveRowBg(i);
+		this.isStartBgAlternate = true;
+	},
+	
+	SetColOperation: function()
+	/*====================================================
+		- Calculates values of a column
+		- params are stored in 'colOperation' table's
+		attribute
+			- colOperation['id'] contains ids of elements 
+			showing result (array)
+			- colOperation['col'] contains index of 
+			columns (array)
+			- colOperation['operation'] contains operation
+			type (array, values: sum, mean)
+			- colOperation['write_method'] array defines 
+			which method to use for displaying the 
+			result (innerHTML, setValue, createTextNode).
+			Note that innerHTML is the default value.
+			- colOperation['tot_row_index'] defines in 
+			which row results are displayed (integers array)
+			
+		- changes made by nuovella: 
+		(1) optimized the routine (now it will only 
+		process each column once),
+		(2) added calculations for the median, lower and 
+		upper quartile.
+	=====================================================*/
+	{
+		if( !this.isFirstLoad && !this.hasGrid ) return;
+		
+		if(this.onBeforeOperation) this.onBeforeOperation.call(null,this);
+		
+		var labelId = this.colOperation['id'];
+		var colIndex = this.colOperation['col'];
+		var operation = this.colOperation['operation'];
+		var outputType = this.colOperation['write_method'];
+		var totRowIndex = this.colOperation['tot_row_index'];
+		var excludeRow = this.colOperation['exclude_row'];
+		var decimalPrecision = this.colOperation['decimal_precision']!=undefined
+								? this.colOperation['decimal_precision'] : 2;
+		
+		//nuovella: determine unique list of columns to operate on
+		var ucolIndex =[]; 
+		var ucolMax=0;
+		
+		ucolIndex[ucolMax]=colIndex[0];
+		
+		for(var i=1; i<colIndex.length; i++)
+		{
+			saved=0;
+			//see if colIndex[i] is already in the list of unique indexes
+			for(var j=0; j<=ucolMax; j++ )
+			{
+				if (ucolIndex[j]==colIndex[i])
+					saved=1;
+			}
+			if (saved==0)
+			{//if not saved then, save the index;
+				ucolMax++;
+				ucolIndex[ucolMax]=colIndex[i];
+			}
+		}// for i
+		
+		if( (typeof labelId).tf_LCase()=='object' 
+			&& (typeof colIndex).tf_LCase()=='object' 
+			&& (typeof operation).tf_LCase()=='object' )
+		{
+			var row = this.tbl.rows;
+			var colvalues = [];
+			
+			for(var ucol=0; ucol<=ucolMax; ucol++)
+			{
+				//this retrieves col values 
+				//use ucolIndex because we only want to pass through this loop once for each column
+				//get the values in this unique column
+				colvalues.push( this.GetColValues(ucolIndex[ucol],true,excludeRow) );
+				
+			   //next: calculate all operations for this column
+			   var result, nbvalues=0,  temp;
+			   var meanValue=0, sumValue=0, minValue=null, maxValue=null, q1Value=null, medValue=null, q3Value=null;
+			   var meanFlag=0, sumFlag=0, minFlag=0, maxFlag=0, q1Flag=0, medFlag=0, q3Flag=0;
+			   var theList=[];
+			   var opsThisCol=[], decThisCol=[], labThisCol=[], oTypeThisCol=[];
+			   var mThisCol=-1;
+				
+				for(var i=0; i<colIndex.length; i++)
+				{
+					 if (colIndex[i]==ucolIndex[ucol])
+					 {
+						mThisCol++;
+						opsThisCol[mThisCol]=operation[i].tf_LCase();
+						decThisCol[mThisCol]=decimalPrecision[i];
+						labThisCol[mThisCol]=labelId[i]; 
+						oTypeThisCol = (outputType != undefined && (typeof outputType).tf_LCase()=='object') 
+											? outputType[i] : null;
+						
+						switch( opsThisCol[mThisCol] )
+						{			
+							case 'mean':
+								meanFlag=1;
+							break;
+							case 'sum':
+								sumFlag=1;
+							break;
+							case 'min':
+								minFlag=1;
+							break;
+							case 'max':
+								maxFlag=1;
+							break;
+							case 'median':
+								medFlag=1;	
+								break;
+							case 'q1':
+								q1Flag=1;
+							break;
+							case 'q3':
+								q3Flag=1;
+							break;
+						}
+					}		
+				}
+				
+				for(var j=0; j<colvalues[ucol].length; j++ )
+				{
+					if ((q1Flag==1)||(q3Flag==1) || (medFlag==1))
+					{//sort the list for calculation of median and quartiles
+						if (j<colvalues[ucol].length -1)
+						{
+							for(k=j+1;k<colvalues[ucol].length; k++) {
+				  
+								if( eval(colvalues[ucol][k]) < eval(colvalues[ucol][j]))
+								{
+									temp = colvalues[ucol][j];            
+									colvalues[ucol][j] = colvalues[ucol][k];              
+									colvalues[ucol][k] = temp;            
+								}
+							}
+						}
+					}
+					var cvalue = parseFloat(colvalues[ucol][j]);
+					theList[j]=parseFloat( cvalue );
+	
+					if( !isNaN(cvalue) )
+					{
+						nbvalues++;
+						if ((sumFlag==1)|| (meanFlag==1)) sumValue += parseFloat( cvalue );
+						if (minFlag==1) 
+						{
+							if (minValue==null)
+							{
+								minValue = parseFloat( cvalue );
+							}
+							else minValue= parseFloat( cvalue )<minValue? parseFloat( cvalue ): minValue;
+						}
+						if (maxFlag==1) {
+							if (maxValue==null)
+							{maxValue = parseFloat( cvalue );}
+						else {maxValue= parseFloat( cvalue )>maxValue? parseFloat( cvalue ): maxValue;}
+						}
+					}
+				}//for j
+				if (meanFlag==1) meanValue = sumValue/nbvalues;
+				if (medFlag==1)
+				{
+						var aux = 0;
+						if(nbvalues%2 == 1) 
+						{
+							aux = Math.floor(nbvalues/2);
+							medValue = theList[aux];   
+						}
+					else medValue = (theList[nbvalues/2]+theList[((nbvalues/2)-1)])/2;
+				}
+				if (q1Flag==1)
+				{	
+					var posa=0.0;
+					posa = Math.floor(nbvalues/4);
+					if (4*posa == nbvalues) {q1Value = (theList[posa-1] + theList[posa])/2;}
+					else {q1Value = theList[posa];}
+				}
+				if (q3Flag==1)
+				{
+					var posa=0.0;
+					var posb=0.0;
+					posa = Math.floor(nbvalues/4);
+					if (4*posa == nbvalues)
+					{
+						posb = 3*posa;
+						q3Value = (theList[posb] + theList[posb-1])/2;  
+					}
+					else
+						q3Value = theList[nbvalues-posa-1];
+				}
+				
+				for(var i=0; i<=mThisCol; i++ )
+				{
+				   switch( opsThisCol[i] )
+				   {			
+						case 'mean':
+							result=meanValue;
+						break;
+						case 'sum':
+							result=sumValue;
+						break;
+						case 'min':
+							result=minValue;
+						break;
+						case 'max':
+							result=maxValue;
+						break;
+						case 'median':
+							result=medValue;	
+							break;
+						case 'q1':
+							result=q1Value;
+						break;
+						case 'q3':
+							result=q3Value;
+						break;
+				  }		
+					
+				var precision = decThisCol[i]!=undefined && !isNaN( decThisCol[i] )
+									? decThisCol[i] : 2;
+
+				if(oTypeThisCol!=null && result)
+				{//if outputType is defined
+					result = result.toFixed( precision );
+					if( tf_Id( labThisCol[i] )!=undefined )
+					{
+						switch( oTypeThisCol.tf_LCase() )
+						{
+							case 'innerhtml':							
+								if (isNaN(result) || !isFinite(result) || (nbvalues==0)) 
+									tf_Id( labThisCol[i] ).innerHTML = '.';
+								else
+									tf_Id( labThisCol[i] ).innerHTML = result;
+							break;
+							case 'setvalue':
+								tf_Id( labThisCol[i] ).value = result;
+							break;
+							case 'createtextnode':
+								var oldnode = tf_Id( labThisCol[i] ).firstChild;
+								var txtnode = tf_CreateText( result );
+								tf_Id( labThisCol[i] ).replaceChild( txtnode,oldnode );
+							break;
+						}//switch
+					}
+				} else {
+					try
+					{      
+						if (isNaN(result) || !isFinite(result) || (nbvalues==0)) 
+							tf_Id( labThisCol[i] ).innerHTML = '.';
+						else
+							 tf_Id( labThisCol[i] ).innerHTML = result.toFixed( precision );
+					} catch(e){ }//catch
+				}//else
+			 }//for i
+			//eventual row(s) with result are always visible
+			if(totRowIndex!=undefined && row[totRowIndex[ucol]]) 
+				row[totRowIndex[ucol]].style.display = '';
+			}//for ucol
+		}//if typeof
+		
+		if(this.onAfterOperation) this.onAfterOperation.call(null,this);
+	},
+	
+	SetPage: function( cmd )
+	/*====================================================
+		- If paging set true shows page according to
+		param value (string or number):
+			- strings: 'next','previous','last','first' or
+			- number: page number
+	=====================================================*/
+	{
+		if( this.hasGrid && this.paging )
+		{
+			var btnEvt = this.pagingBtnEvents, cmdtype = typeof cmd;
+			if(cmdtype=='string')
+			{
+				switch(cmd.tf_LCase())
+				{
+					case 'next':
+						btnEvt.next();
+					break;
+					case 'previous':
+						btnEvt.prev();
+					break;
+					case 'last':
+						btnEvt.last();
+					break;
+					case 'first':
+						btnEvt.first();
+					break;
+					default:
+						btnEvt.next();
+					break;
+				}//switch
+			}
+			if(cmdtype=='number') this.ChangePage( (cmd-1) );
+		}// this.hasGrid 
+	},
+	
+	RefreshFiltersGrid: function()
+	/*====================================================
+		- retrieves select, multiple and checklist filters
+		- calls method repopulating filters
+	=====================================================*/
+	{
+		var slcA1 = this.GetFiltersByType( this.fltTypeSlc,true );
+		var slcA2 = this.GetFiltersByType( this.fltTypeMulti,true );
+		var slcA3 = this.GetFiltersByType( this.fltTypeCheckList,true );
+		var slcIndex = slcA1.concat(slcA2);
+		slcIndex = slcIndex.concat(slcA3);
+
+		if( this.activeFilterId!=null )//for paging
+		{
+			var activeFlt = this.activeFilterId.split('_')[0];
+			activeFlt = activeFlt.split(this.prfxFlt)[1];
+			var slcSelectedValue;
+			for(var i=0; i<slcIndex.length; i++)
+			{
+				var curSlc = tf_Id(this.fltIds[slcIndex[i]]);
+				slcSelectedValue = this.GetFilterValue( slcIndex[i] );
+				//if(activeFlt==slcIndex[i] && slcA3.tf_Has(slcIndex[i]) && slcSelectedValue!=this.displayAllText) continue;
+				if(activeFlt!=slcIndex[i] || (this.paging && slcA1.tf_Has(slcIndex[i]) && activeFlt==slcIndex[i] ) || 
+					( !this.paging && (slcA3.tf_Has(slcIndex[i]) || slcA2.tf_Has(slcIndex[i]) ) /*&& activeFlt==slcIndex[i]*/) || 
+					slcSelectedValue==this.displayAllText )
+					//(this.paging && (!slcA3.tf_Has(slcIndex[i]) && !slcA2.tf_Has(slcIndex[i]) && activeFlt==slcIndex[i]) ) )
+				{
+					if(slcA3.tf_Has(slcIndex[i]))
+						this.checkListDiv[slcIndex[i]].innerHTML = '';
+					else curSlc.innerHTML = '';
+					
+					if(this.fillSlcOnDemand) { //1st option needs to be inserted
+						var opt0 = tf_CreateOpt(this.displayAllText,'');
+						curSlc.appendChild( opt0 );
+					}
+					
+					if(slcA3.tf_Has(slcIndex[i]))
+						this._PopulateCheckList(slcIndex[i]);
+					else
+						this._PopulateSelect(slcIndex[i],true);
+						
+					this.SetFilterValue(slcIndex[i],slcSelectedValue);
+				}
+			}// for i
+		}
+	},
+	
+	RememberFiltersValue: function( name )
+	/*==============================================
+		- stores filters' values in a cookie
+		when Filter() method is called
+		- Params:
+			- name: cookie name (string)
+		- credits to Florent Hirchy
+	===============================================*/
+	{
+		var flt_values = [];
+		for(var i=0; i<this.fltIds.length; i++)
+		{//creates an array with filters' values
+			value = this.GetFilterValue(i);
+			if (value == '') value = ' ';
+			flt_values.push(value);
+		}
+		flt_values.push(this.fltIds.length); //adds array size
+		tf_WriteCookie(
+			name,
+			flt_values,
+			this.cookieDuration
+		); //writes cookie  
+	},
+	
+	RememberPageNb: function( name )
+	/*==============================================
+		- stores page number value in a cookie
+		when ChangePage method is called
+		- Params:
+			- name: cookie name (string)
+	===============================================*/
+	{
+		tf_WriteCookie(
+			name,
+			this.currentPageNb,
+			this.cookieDuration
+		); //writes cookie  
+	},
+	
+	RememberPageLength: function( name )
+	/*==============================================
+		- stores page length value in a cookie
+		when ChangePageLength method is called
+		- Params:
+			- name: cookie name (string)
+	===============================================*/
+	{
+		tf_WriteCookie(
+			name,
+			this.resultsPerPageSlc.selectedIndex,
+			this.cookieDuration
+		); //writes cookie
+	},
+	
+	ResetValues: function()
+	{ 
+		this.EvtManager(this.Evt.name.resetvalues); 
+	},
+	
+	_ResetValues: function()
+	/*==============================================
+		- re-sets grid values when page is 
+		re-loaded. It invokes ResetGridValues,
+		ResetPage and ResetPageLength methods
+		- Params:
+			- name: cookie name (string)
+	===============================================*/
+	{
+		if(this.rememberGridValues && this.fillSlcOnDemand) //only fillSlcOnDemand
+			this.ResetGridValues(this.fltsValuesCookie);
+		if(this.rememberPageLen) this.ResetPageLength( this.pgLenCookie );
+		if(this.rememberPageNb) this.ResetPage( this.pgNbCookie );		
+	},	
+	
+	ResetGridValues: function( name )
+	/*==============================================
+		- re-sets filters' values when page is 
+		re-loaded if load on demand is enabled
+		- Params:
+			- name: cookie name (string)
+		- credits to Florent Hirchy
+	===============================================*/
+	{
+		if(!this.fillSlcOnDemand) return;
+		var flts = tf_ReadCookie(name); //reads the cookie
+		var reg = new RegExp(',','g');	
+		var flts_values = flts.split(reg); //creates an array with filters' values
+		var slcFltsIndex = this.GetFiltersByType(this.fltTypeSlc, true);
+		var multiFltsIndex = this.GetFiltersByType(this.fltTypeMulti, true);
+		
+		if(flts_values[(flts_values.length-1)] == this.fltIds.length)
+		{//if the number of columns is the same as before page reload
+			for(var i=0; i<(flts_values.length - 1); i++)
+			{			
+				if (flts_values[i]==' ') continue;				
+				if(this['col'+i]==this.fltTypeSlc || this['col'+i]==this.fltTypeMulti)
+				{// if fillSlcOnDemand, drop-down needs to contain stored value(s) for filtering
+					var slc = tf_Id( this.fltIds[i] );
+					slc.options[0].selected = false;
+					
+					if( slcFltsIndex.tf_Has(i) )
+					{//selects
+						var opt = tf_CreateOpt(flts_values[i],flts_values[i],true);
+						slc.appendChild(opt);
+						this.hasStoredValues = true;
+					}
+					if(multiFltsIndex.tf_Has(i))
+					{//multiple select
+						var s = flts_values[i].split(' '+this.orOperator+' ');
+						for(j=0; j<s.length; j++)
+						{
+							if(s[j]=='') continue;
+							var opt = tf_CreateOpt(s[j],s[j],true);
+							slc.appendChild(opt);
+							this.hasStoredValues = true;
+							
+							if(tf_isIE)
+							{// IE multiple selection work-around
+								this.__deferMultipleSelection(slc,j,false);
+								hasStoredValues = false;
+							}
+						}
+					}// if multiFltsIndex
+				}
+				else if(this['col'+i]==this.fltTypeCheckList)
+				{
+					var divChk = this.checkListDiv[i];
+					divChk.title = divChk.innerHTML;
+					divChk.innerHTML = '';
+					
+					var ul = tf_CreateElm('ul',['id',this.fltIds[i]],['colIndex',i]);
+					ul.className = this.checkListCssClass;
+
+					var li0 = tf_CreateCheckItem(this.fltIds[i]+'_0', '', this.displayAllText);
+					li0.className = this.checkListItemCssClass;
+					ul.appendChild(li0);
+
+					divChk.appendChild(ul);
+					
+					var s = flts_values[i].split(' '+this.orOperator+' ');
+					for(j=0; j<s.length; j++)
+					{
+						if(s[j]=='') continue;
+						var li = tf_CreateCheckItem(this.fltIds[i]+'_'+(j+1), s[j], s[j]);
+						li.className = this.checkListItemCssClass;
+						ul.appendChild(li);
+						li.check.checked = true;
+						this.__setCheckListValues(li.check);
+						this.hasStoredValues = true;
+					}					
+				}
+			}//end for
+			
+			if(!this.hasStoredValues && this.paging) this.SetPagingInfo();
+		}//end if
+	},
+	
+	ResetPage: function( name )
+	{
+		this.EvtManager(this.Evt.name.resetpage);
+	},
+	_ResetPage: function( name )
+	/*==============================================
+		- re-sets page nb at page re-load
+		- Params:
+			- name: cookie name (string)
+	===============================================*/
+	{
+		var pgnb = tf_ReadCookie(name); //reads the cookie
+		if( pgnb!='' ) 
+			this.ChangePage((pgnb-1));
+	},
+	
+	ResetPageLength: function( name )
+	{
+		this.EvtManager(this.Evt.name.resetpagelength);
+	},
+	_ResetPageLength: function( name )
+	/*==============================================
+		- re-sets page length at page re-load
+		- Params:
+			- name: cookie name (string)
+	===============================================*/
+	{
+		if(!this.paging) return;
+		var pglenIndex = tf_ReadCookie(name); //reads the cookie
+		
+		if( pglenIndex!='' )
+		{
+			this.resultsPerPageSlc.options[pglenIndex].selected = true;
+			this.ChangeResultsPerPage();
+		}
+	},
+	
+	SetLoader: function()
+	/*====================================================
+		- generates loader div
+	=====================================================*/
+	{
+		if( this.loaderDiv!=null ) return;
+		var containerDiv = tf_CreateElm( 'div',['id',this.prfxLoader+this.id] );
+		containerDiv.className = this.loaderCssClass;// for ie<=6
+		//containerDiv.style.display = 'none';
+		var targetEl = (this.loaderTgtId==null) 
+			? (this.gridLayout ? this.tblCont : this.tbl.parentNode) : tf_Id( this.loaderTgtId );
+		if(this.loaderTgtId==null) targetEl.insertBefore(containerDiv, this.tbl);
+		else targetEl.appendChild( containerDiv );
+		this.loaderDiv = tf_Id(this.prfxLoader+this.id);
+		if(this.loaderHtml==null) 
+			this.loaderDiv.appendChild( tf_CreateText(this.loaderText) );
+		else this.loaderDiv.innerHTML = this.loaderHtml;
+	},
+	
+	RemoveLoader: function()
+	/*====================================================
+		- removes loader div
+	=====================================================*/
+	{
+		if( this.loaderDiv==null ) return;
+		var targetEl = (this.loaderTgtId==null) 
+			? (this.gridLayout ? this.tblCont : this.tbl.parentNode) : tf_Id( this.loaderTgtId );
+		targetEl.removeChild(this.loaderDiv);
+		this.loaderDiv = null;
+	},
+	
+	ShowLoader: function(p)
+	/*====================================================
+		- displays/hides loader div
+	=====================================================*/
+	{
+		if(!this.loader || !this.loaderDiv) return;
+		if(this.loaderDiv.style.display==p) return;
+		var o = this;
+
+		function displayLoader(){ 
+			if(!o.loaderDiv) return;
+			if(o.onShowLoader && p!='none') 
+				o.onShowLoader.call(null,o);
+			o.loaderDiv.style.display = p;
+			if(o.onHideLoader && p=='none') 
+				o.onHideLoader.call(null,o);
+		}
+
+		var t = (p=='none') ? this.loaderCloseDelay : 1;
+		window.setTimeout(displayLoader,t);
+	},
+	
+	StatusMsg: function(t)
+	/*====================================================
+		- sets status messages
+	=====================================================*/
+	{
+		if(t==undefined) this.StatusMsg('');
+		if(this.status) this.WinStatusMsg(t);
+		if(this.statusBar) this.StatusBarMsg(t);
+	},
+	
+	StatusBarMsg: function(t)
+	/*====================================================
+		- sets status bar messages
+	=====================================================*/
+	{
+		if(!this.statusBar || !this.statusBarSpan) return;
+		var o = this;
+		function setMsg(){
+			o.statusBarSpan.innerHTML = t;
+		}
+		var d = (t=='') ? (this.statusBarCloseDelay) : 1;
+		window.setTimeout(setMsg,d);
+	},
+	
+	WinStatusMsg: function(t)
+	/*====================================================
+		- sets window status messages
+	=====================================================*/
+	{
+		if(!this.status) return;
+		window.status = t;
+	},
+	
+	ClearFilters: function()
+	{ 
+		this.EvtManager(this.Evt.name.clear); 
+	},	
+	_ClearFilters: function()
+	/*====================================================
+		- clears grid filters
+	=====================================================*/
+	{
+		if( !this.fltGrid ) return;
+		for(var i=0; i<this.fltIds.length; i++)
+			this.SetFilterValue(i,'');
+		if(this.refreshFilters){
+			this.activeFilterId = '';	
+			this.RefreshFiltersGrid();
+		}
+		if(this.rememberPageLen) tf_RemoveCookie(this.pgLenCookie);
+		if(this.rememberPageNb) tf_RemoveCookie(this.pgNbCookie);
+	},
+	
+	UnhighlightAll: function()
+	/*====================================================
+		- removes keyword highlighting
+	=====================================================*/
+	{
+		if( this.highlightKeywords && this.searchArgs!=null )
+			for(var y=0; y<this.searchArgs.length; y++)
+				tf_UnhighlightWord( 
+					this.tbl,this.searchArgs[y],
+					this.highlightCssClass 
+				);
+	},
+	
+	RefreshGrid: function()
+	/*====================================================
+		- Re-generates filters grid
+	=====================================================*/
+	{
+		this.RemoveGrid();
+		setFilterGrid(this.id, this.startRow, this.fObj);
+	},
+	
+	__resetGrid: function()
+	/*====================================================
+		- Only used by AddGrid() method
+		- Resets filtering grid bar if previously removed
+	=====================================================*/
+	{
+		if( this.isFirstLoad ) return;
+		
+		// grid was removed, grid row element is stored in this.fltGridEl property
+		this.tbl.rows[this.filtersRowIndex].parentNode.insertBefore( 
+			this.fltGridEl,
+			this.tbl.rows[this.filtersRowIndex]
+		);
+		
+		if( this.isExternalFlt )
+		{// filters are appended in external placeholders elements
+			for(var ct=0; ct<this.externalFltTgtIds.length; ct++ )
+				if( tf_Id(this.externalFltTgtIds[ct]) )
+					tf_Id(this.externalFltTgtIds[ct]).appendChild(this.externalFltEls[ct]);
+		}
+		
+		this.nbFilterableRows = this.GetRowsNb();
+		this.nbVisibleRows = this.nbFilterableRows;
+		this.nbRows = this.tbl.rows.length;
+		this.sort = true;
+		
+		/*** 	ie bug work-around, filters need to be re-generated
+				since row is empty; insertBefore method doesn't seem to work properly 
+				with previously generated DOM nodes modified by innerHTML 	***/
+		if( this.tbl.rows[this.filtersRowIndex].innerHTML=='' )
+		{
+			this.tbl.deleteRow(this.filtersRowIndex);
+			this.RemoveGrid();
+			this.RemoveExternalFlts();
+			this.fltIds = [];
+			this.isFirstLoad = true;
+			this.AddGrid();
+			
+		}
+		
+		this.hasGrid = true;
+	},
+	
+	__deferMultipleSelection: function(slc,index,filter)
+	/*====================================================
+		- IE bug: it seems there is no way to make 
+		multiple selections programatically, only last 
+		selection is kept (multiple select previously 
+		populated via DOM)
+		- Turn-around: defer selection with a setTimeout
+		If you find an alternative elegant solution to 
+		this let me know ;-)
+		- For the moment only this solution seems 
+		to work!
+		- Params: 
+			- slc = select object (select obj)
+			- index to be selected (integer)
+			- execute filtering (boolean)
+	=====================================================*/
+	{
+		if(slc.nodeName.tf_LCase() != 'select') return;
+		var doFilter = (filter==undefined) ? false : filter;
+		var o = this;
+		window.setTimeout(
+			function(){
+				slc.options[0].selected = false;
+				
+				if(slc.options[index].value=='') 
+					slc.options[index].selected = false;
+				else
+				slc.options[index].selected = true; 
+				if(doFilter) o.Filter();
+			},
+			.1
+		);
+	},
+	
+	__getCustomValues: function(colIndex)
+	/*====================================================
+		- Returns an array [[values],[texts]] with 
+		custom values for a given filter
+		- Param: column index (integer)
+	=====================================================*/
+	{
+		if(colIndex==undefined) return;
+		var isCustomSlc = (this.hasCustomSlcOptions  //custom select test
+							&& this.customSlcOptions.cols.tf_Has(colIndex));
+		if(!isCustomSlc) return;
+		var optTxt = [], optArray = [];
+		var index = this.customSlcOptions.cols.tf_IndexByValue(colIndex);
+		var slcValues = this.customSlcOptions.values[index];
+		var slcTexts = this.customSlcOptions.texts[index];
+		var slcSort = this.customSlcOptions.sorts[index];
+		for(var r=0; r<slcValues.length; r++)
+		{
+			optArray.push(slcValues[r]);
+			if(slcTexts[r]!=undefined)
+				optTxt.push(slcTexts[r]);
+			else
+				optTxt.push(slcValues[r]);
+		}
+		if(slcSort)
+		{
+			optArray.sort();
+			optTxt.sort();
+		}
+		return [optArray,optTxt];
+	},
+	
+	__setCheckListValues: function(o)
+	/*====================================================
+		- Sets checked items information of a checklist
+	=====================================================*/
+	{
+		if(o==null) return;
+		var chkValue = o.value; //checked item value
+		var chkIndex = parseInt(o.id.split('_')[2]);
+		var filterTag = 'ul', itemTag = 'li';
+		var n = o;
+		
+		//ul tag search
+		while(n.nodeName.tf_LCase() != filterTag)
+			n = n.parentNode;
+
+		if(n.nodeName.tf_LCase() != filterTag) return;
+		
+		var li = n.childNodes[chkIndex];
+		var colIndex = n.getAttribute('colIndex');
+		var fltValue = n.getAttribute('value'); //filter value (ul tag)
+		var fltIndexes = n.getAttribute('indexes'); //selected items (ul tag)
+
+		if(o.checked)		
+		{
+			if(chkValue=='')
+			{//show all item
+				if((fltIndexes!=null && fltIndexes!=''))
+				{
+					var indSplit = fltIndexes.split(this.separator);//items indexes
+					for(var u=0; u<indSplit.length; u++)
+					{//checked items loop
+						var cChk = tf_Id(this.fltIds[colIndex]+'_'+indSplit[u]); //checked item
+						if(cChk)
+						{ 
+							cChk.checked = false;
+							tf_removeClass(
+								n.childNodes[indSplit[u]],
+								this.checkListSlcItemCssClass
+							);
+						}
+					}
+				}
+				n.setAttribute('value', '');
+				n.setAttribute('indexes', '');
+				
+			} else {
+				fltValue = (fltValue) ? fltValue : '';
+				chkValue = (fltValue+' '+chkValue +' '+this.orOperator).tf_Trim();
+				chkIndex = fltIndexes + chkIndex + this.separator;
+				n.setAttribute('value', chkValue );
+				n.setAttribute('indexes', chkIndex);
+				//1st option unchecked
+				if(tf_Id(this.fltIds[colIndex]+'_0'))
+					tf_Id(this.fltIds[colIndex]+'_0').checked = false; 
+			}
+			
+			if(li.nodeName.tf_LCase() == itemTag)
+			{
+				tf_removeClass(n.childNodes[0],this.checkListSlcItemCssClass);
+				tf_addClass(li,this.checkListSlcItemCssClass);
+			}
+		} else { //removes values and indexes
+			if(chkValue!='')
+			{
+				var replaceValue = new RegExp(tf_RegexpEscape(chkValue+' '+this.orOperator));
+				fltValue = fltValue.replace(replaceValue,'');
+				n.setAttribute('value', fltValue);
+				
+				var replaceIndex = new RegExp(tf_RegexpEscape(chkIndex + this.separator));
+				fltIndexes = fltIndexes.replace(replaceIndex,'');
+				n.setAttribute('indexes', fltIndexes);
+			}
+			if(li.nodeName.tf_LCase() == itemTag)
+				tf_removeClass(li,this.checkListSlcItemCssClass);
+		}
+			
+	},
+	
+	__containsStr: function(arg,data,fltType,forceMatch)
+	/*==============================================
+		- Checks if data contains searched arg,
+		returns a boolean
+		- Params:
+			- arg: searched string
+			- data: data string
+			- fltType: filter type (string, 
+			exact match by default for selects - 
+			optional)
+			- forceMatch: boolean forcing exact
+			match (optional)
+	===============================================*/
+	{
+		// Improved by Cedric Wartel (cwl)
+		// automatic exact match for selects and special characters are now filtered
+		var regexp;
+		var modifier = (this.matchCase) ? 'g' : 'gi';
+		var exactMatch = (forceMatch==undefined) ? this.exactMatch : forceMatch;
+		if(exactMatch || (fltType!=this.fltTypeInp && fltType!=undefined))//Váry Péter's patch
+			regexp = new RegExp('(^\\s*)'+tf_RegexpEscape(arg)+'(\\s*$)', modifier);							
+		else
+			regexp = new RegExp(tf_RegexpEscape(arg), modifier);
+		return regexp.test(data);
+	},
+	
+	IncludeFile: function(fileId, filePath, callback, type)
+	{
+		var ftype = (type==undefined) ? 'script' : type;
+		var isImported = tf_isImported(filePath, ftype);
+		if( isImported ) return;
+		
+		var o = this, isLoaded = false, file;			
+		var head = tf_Tag(document,'head')[0];
+		
+		if(ftype.tf_LCase() == 'link')
+			file = tf_CreateElm(
+						'link', ['id',fileId], ['type','text/css'],
+						['rel','stylesheet'], ['href',filePath]
+					);
+		else
+			file = tf_CreateElm(
+						'script', ['id',fileId], 
+						['type','text/javascript'], ['src',filePath]
+					);
+
+		file.onload = file.onreadystatechange = function()
+		{
+			if (!isLoaded && 
+				(!this.readyState || this.readyState == 'loaded' || this.readyState == 'complete')) 
+			{
+				isLoaded = true;
+				if (typeof callback === 'function')
+					callback(o);
+			}
+		}
+		head.appendChild(file);
+	},
+	
+	/*====================================================
+		- Additional public methods for developers
+	=====================================================*/
+	
+	HasGrid: function()
+	/*====================================================
+		- checks if table has a filter grid
+		- returns a boolean
+	=====================================================*/
+	{
+		return this.hasGrid;
+	},
+	
+	GetFiltersId: function()
+	/*====================================================
+		- returns an array containing filters ids
+		- Note that hidden filters are also returned
+	=====================================================*/
+	{
+		if( !this.hasGrid ) return;
+		return this.fltIds;
+	},
+	
+	GetValidRowsIndex: function()
+	/*====================================================
+		- returns an array containing valid rows indexes 
+		(valid rows upon filtering)
+	=====================================================*/
+	{
+		if( !this.hasGrid ) return;
+		return this.validRowsIndex;
+	},
+	
+	GetFiltersRowIndex: function()
+	/*====================================================
+		- Returns the index of the row containing the 
+		filters
+	=====================================================*/
+	{
+		if( !this.hasGrid ) return;
+		return this.filtersRowIndex;
+	},
+	
+	GetHeadersRowIndex: function()
+	/*====================================================
+		- Returns the index of the headers row
+	=====================================================*/
+	{
+		if( !this.hasGrid ) return;
+		return this.headersRow;
+	},
+	
+	GetStartRowIndex: function()
+	/*====================================================
+		- Returns the index of the row from which will 
+		start the filtering process (1st filterable row)
+	=====================================================*/
+	{
+		if( !this.hasGrid ) return;
+		return this.refRow;
+	},
+	
+	GetLastRowIndex: function()
+	/*====================================================
+		- Returns the index of the last row
+	=====================================================*/
+	{
+		if( !this.hasGrid ) return;
+		return (this.nbRows-1);
+	},
+	
+	AddPaging: function(filterTable)
+	/*====================================================
+		- Adds paging feature if filter grid bar is 
+		already set
+		- Param(s):
+			- execFilter: if true table is filtered 
+			(boolean)
+	=====================================================*/
+	{
+		if( !this.hasGrid || this.paging ) return;
+		this.paging = true; 
+		this.isPagingRemoved = true; 
+		this.SetPaging();
+		if(filterTable) this.Filter();
+	}	
+	
+}
+
+/* --- */
+
+/*====================================================
+	- General TF utility fns below
+=====================================================*/
+
+function tf_GetChildElms(n)
+/*====================================================
+	- checks passed node is a ELEMENT_NODE nodeType=1
+	- removes TEXT_NODE nodeType=3  
+=====================================================*/
+{
+	if(n!=undefined && n.nodeType == 1)
+	{
+		var enfants = n.childNodes;
+		for(var i=0; i<enfants.length; i++)
+		{
+			var child = enfants[i];
+			if(child.nodeType == 3)
+			{ 
+				n.removeChild(child);
+				i = -1;
+			}
+		}
+		return n;	
+	}
+}
+
+function tf_GetNodeText(n)
+/*====================================================
+	- returns text + text of child nodes of a node
+=====================================================*/
+{
+	/*if(n.innerText) return n.innerText.tf_Trim();
+	var s = '';
+	var enfants = n.childNodes;
+	for(var i=0; i<enfants.length; i++)
+	{
+		var child = enfants[i];
+		if(child.nodeType == 3) s+= child.data;
+		else s+= tf_GetNodeText(child).tf_Trim();
+	}*/
+	var s = n.textContent || n.innerText || n.innerHTML.replace(/\<[^<>]+>/g, '');
+	return s.replace(/^\s+/, '').replace(/\s+$/, '');
+
+	return s.tf_Trim();
+}
+
+function tf_isObj(varname)
+/*====================================================
+	- checks if var exists and is an object
+	- returns a boolean
+=====================================================*/
+{
+	var isO = false;
+	if( window[varname] && (typeof window[varname]).tf_LCase()=='object' )
+		isO = true;
+	return isO;
+}
+
+function tf_isFn(fn)
+/*====================================================
+	- checks if passed param is a function
+	- returns a boolean
+=====================================================*/
+{
+	var isFn = false;
+	if(fn && (typeof fn).tf_LCase() == 'function')
+		isFn = true;
+	return isFn;
+}
+
+function tf_Id(id)
+/*====================================================
+	- this is just a getElementById shortcut
+=====================================================*/
+{
+	return document.getElementById( id );
+}
+
+function tf_Tag(o,tagname)
+/*====================================================
+	- this is just a getElementsByTagName shortcut
+=====================================================*/
+{
+	return o.getElementsByTagName( tagname );
+}
+
+function tf_RegexpEscape(s)
+/*====================================================
+	- escapes special characters [\^$.|?*+() 
+	for regexp
+	- Many thanks to Cedric Wartel for this fn
+=====================================================*/
+{
+	// traite les caractères spéciaux [\^$.|?*+()
+	//remplace le carctère c par \c
+	function escape(e)
+	{
+		a = new RegExp('\\'+e,'g');
+		s = s.replace(a,'\\'+e);
+	}
+
+	chars = new Array('\\','[','^','$','.','|','?','*','+','(',')');
+	//for(e in chars) escape(chars[e]); // compatibility issue with prototype
+	for(var e=0; e<chars.length; e++) escape(chars[e]);
+	return s;
+}
+
+function tf_CreateElm(tag)
+/*====================================================
+	- creates an html element with its attributes
+	- accepts the following params:
+		- a string defining the html tag
+		to create
+		- an undetermined # of arrays containing the
+		couple 'attribute name','value' ['id','myId']
+=====================================================*/
+{
+	if(tag==undefined || tag==null || tag=='') return;
+	var el = document.createElement( tag );		
+	if(arguments.length>1)
+	{
+		for(var i=0; i<arguments.length; i++)
+		{
+			var argtype = typeof arguments[i];
+			switch( argtype.tf_LCase() )
+			{
+				case 'object':
+					if( arguments[i].length==2 )
+					{						
+						el.setAttribute( arguments[i][0],arguments[i][1] );
+					}//if array length==2
+				break;
+			}//switch
+		}//for i
+	}//if args
+	return el;	
+}
+
+function tf_CreateText(node)
+/*====================================================
+	- this is just a document.createTextNode shortcut
+=====================================================*/
+{
+	return document.createTextNode( node );
+}
+
+function tf_CreateOpt(text,value,isSel)
+/*====================================================
+	- creates an option element and returns it:
+		- text: displayed text (string)
+		- value: option value (string)
+		- isSel: is selected option (boolean)
+=====================================================*/
+{
+	var isSelected = isSel ? true : false;
+	var opt = (isSelected) 
+		? tf_CreateElm('option',['value',value],['selected','true'])
+		: tf_CreateElm('option',['value',value]);
+	opt.appendChild(tf_CreateText(text));
+	return opt;
+}
+
+function tf_CreateCheckItem(chkIndex, chkValue, labelText)
+/*====================================================
+	- creates an checklist item and returns it
+	- accepts the following params:
+		- chkIndex: index of check item (number)
+		- chkValue: check item value (string)
+		- labelText: check item label text (string)
+=====================================================*/
+{
+	if(chkIndex==undefined || chkValue==undefined || labelText==undefined )
+		return;
+	var li = tf_CreateElm('li');
+	var label = tf_CreateElm('label',['for',chkIndex]);
+	var check = tf_CreateElm( 'input',
+					['id',chkIndex],
+					['name',chkIndex],
+					['type','checkbox'],
+					['value',chkValue] );
+	label.appendChild(check);
+	label.appendChild(tf_CreateText(labelText));
+	li.appendChild(label);
+	li.label = label;
+	li.check = check;
+	return li;
+}
+
+function tf_HighlightWord( node,word,cssClass )
+/*====================================================
+	- highlights keyword found in passed node
+	- accepts the following params:
+		- node
+		- word to search
+		- css class name for highlighting
+=====================================================*/
+{
+	// Iterate into this nodes childNodes
+	if(node.hasChildNodes) 
+		for( var i=0; i<node.childNodes.length; i++ )
+			tf_HighlightWord(node.childNodes[i],word,cssClass);
+
+	// And do this node itself
+	if(node.nodeType == 3) 
+	{ // text node
+		var tempNodeVal = node.nodeValue.tf_LCase();
+		var tempWordVal = word.tf_LCase();
+		if(tempNodeVal.indexOf(tempWordVal) != -1) 
+		{
+			var pn = node.parentNode;
+			if(pn.className != cssClass) 
+			{
+				// word has not already been highlighted!
+				var nv = node.nodeValue;
+				var ni = tempNodeVal.indexOf(tempWordVal);
+				// Create a load of replacement nodes
+				var before = tf_CreateText(nv.substr(0,ni));
+				var docWordVal = nv.substr(ni,word.length);
+				var after = tf_CreateText(nv.substr(ni+word.length));
+				var hiwordtext = tf_CreateText(docWordVal);
+				var hiword = tf_CreateElm('span');
+				hiword.className = cssClass;
+				hiword.appendChild(hiwordtext);
+				pn.insertBefore(before,node);
+				pn.insertBefore(hiword,node);
+				pn.insertBefore(after,node);
+				pn.removeChild(node);
+			}
+		}
+	}// if node.nodeType == 3
+}
+
+function tf_UnhighlightWord( node,word,cssClass )
+/*====================================================
+	- removes highlights found in passed node
+	- accepts the following params:
+		- node
+		- word to search
+		- css class name for highlighting
+=====================================================*/
+{
+	// Iterate into this nodes childNodes
+	if(node.hasChildNodes)
+		for( var i=0; i<node.childNodes.length; i++ )
+			tf_UnhighlightWord(node.childNodes[i],word,cssClass);
+
+	// And do this node itself
+	if(node.nodeType == 3) 
+	{ // text node
+		var tempNodeVal = node.nodeValue.tf_LCase();
+		var tempWordVal = word.tf_LCase();
+		if(tempNodeVal.indexOf(tempWordVal) != -1)
+		{
+			var pn = node.parentNode;
+			if(pn.className == cssClass)
+			{
+				var prevSib = pn.previousSibling;
+				var nextSib = pn.nextSibling;
+				nextSib.nodeValue = prevSib.nodeValue + node.nodeValue + nextSib.nodeValue;
+				prevSib.nodeValue = '';
+				node.nodeValue = '';
+			}
+		}
+	}// if node.nodeType == 3
+}
+
+function tf_addEvent(obj,event_name,func_name)
+{
+	if (obj.attachEvent)
+		obj.attachEvent('on'+event_name, func_name);
+	else if(obj.addEventListener)
+		obj.addEventListener(event_name,func_name,true);
+	else
+		obj['on'+event_name] = func_name;
+}
+
+function tf_removeEvent(obj,event_name,func_name)
+{
+	if (obj.detachEvent)
+		obj.detachEvent('on'+event_name,func_name);
+	else if(obj.removeEventListener)
+		obj.removeEventListener(event_name,func_name,true);
+	else
+		obj['on'+event_name] = null;
+}
+
+function tf_NumSortAsc(a, b){ return (a-b); }
+
+function tf_NumSortDesc(a, b){ return (b-a); }
+
+function tf_IgnoreCaseSort(a, b) {
+	var x = a.tf_LCase();
+	var y = b.tf_LCase();
+	return ((x < y) ? -1 : ((x > y) ? 1 : 0));
+}
+
+String.prototype.tf_MatchCase = function (mc) 
+{
+	if (!mc) return this.tf_LCase();
+	else return this.toString();
+}
+
+String.prototype.tf_Trim = function()
+{//optimised by Anthony Maes
+	return this.replace(/(^[\s\xA0]*)|([\s\xA0]*$)/g,'');
+}
+
+String.prototype.tf_LCase = function()
+{
+	return this.toLowerCase();
+}
+
+String.prototype.tf_UCase = function()
+{
+	return this.toUpperCase();
+}
+
+Array.prototype.tf_Has = function(s,mc) 
+{
+	//return this.indexOf(s) >= 0;
+	var sCase = (mc==undefined) ? false : mc;
+	for (i=0; i<this.length; i++)
+		if (this[i].toString().tf_MatchCase(sCase)==s) return true;
+	return false;
+}
+
+Array.prototype.tf_IndexByValue = function(s,mc) 
+{
+	var sCase = (mc==undefined) ? false : mc;
+	for (i=0; i<this.length; i++)
+		if (this[i].toString().tf_MatchCase(sCase)==s) return i;
+	return (-1);
+}
+
+// Is this IE 6? the ultimate browser sniffer ;-)
+//window['tf_isIE'] = (window.innerHeight) ? false : true;
+window['tf_isIE'] = (window.innerHeight) ? false : /msie|MSIE 6/.test(navigator.userAgent) ? true : false;
+window['tf_isIE7'] = (window.innerHeight) ? false : /msie|MSIE 7/.test(navigator.userAgent) ? true : false;
+
+function tf_hasClass(elm,cl) 
+{
+	return elm.className.match(new RegExp('(\\s|^)'+cl+'(\\s|$)'));
+}
+
+function tf_addClass(elm,cl) 
+{
+	if (!tf_hasClass(elm,cl))
+		elm.className += ' '+cl;
+}
+
+function tf_removeClass(elm,cl) 
+{
+	if ( !tf_hasClass(elm,cl) ) return;
+	var reg = new RegExp('(\\s|^)'+cl+'(\\s|$)');
+	elm.className = elm.className.replace(reg,' ');
+}
+
+function tf_isValidDate(dateStr, format) 
+{
+	if (format == null) { format = 'DMY'; }
+	format = format.toUpperCase();
+	if (format.length != 3) { format = 'DMY'; }
+	if ( (format.indexOf('M') == -1) || (format.indexOf('D') == -1) ||
+		(format.indexOf('Y') == -1) ) { format = 'DMY'; }
+	if (format.substring(0, 1) == 'Y') { // If the year is first
+		  var reg1 = /^\d{2}(\-|\/|\.)\d{1,2}\1\d{1,2}$/;
+		  var reg2 = /^\d{4}(\-|\/|\.)\d{1,2}\1\d{1,2}$/;
+	} else if (format.substring(1, 2) == 'Y') { // If the year is second
+		  var reg1 = /^\d{1,2}(\-|\/|\.)\d{2}\1\d{1,2}$/;
+		  var reg2 = /^\d{1,2}(\-|\/|\.)\d{4}\1\d{1,2}$/;
+	} else { // The year must be third
+		  var reg1 = /^\d{1,2}(\-|\/|\.)\d{1,2}\1\d{2}$/;
+		  var reg2 = /^\d{1,2}(\-|\/|\.)\d{1,2}\1\d{4}$/;
+	}
+	// If it doesn't conform to the right format (with either a 2 digit year or 4 digit year), fail
+	if ( (reg1.test(dateStr) == false) && (reg2.test(dateStr) == false) ) { return false; }
+	var parts = dateStr.split(RegExp.$1); // Split into 3 parts based on what the divider was
+	// Check to see if the 3 parts end up making a valid date
+	if (format.substring(0, 1) == 'M') { var mm = parts[0]; } else
+		if (format.substring(1, 2) == 'M') { var mm = parts[1]; } else { var mm = parts[2]; }
+	if (format.substring(0, 1) == 'D') { var dd = parts[0]; } else
+		if (format.substring(1, 2) == 'D') { var dd = parts[1]; } else { var dd = parts[2]; }
+	if (format.substring(0, 1) == 'Y') { var yy = parts[0]; } else
+		if (format.substring(1, 2) == 'Y') { var yy = parts[1]; } else { var yy = parts[2]; }
+	if (parseFloat(yy) <= 50) { yy = (parseFloat(yy) + 2000).toString(); }
+	if (parseFloat(yy) <= 99) { yy = (parseFloat(yy) + 1900).toString(); }
+	var dt = new Date(parseFloat(yy), parseFloat(mm)-1, parseFloat(dd), 0, 0, 0, 0);
+	if (parseFloat(dd) != dt.getDate()) { return false; }
+	if (parseFloat(mm)-1 != dt.getMonth()) { return false; }
+	return true;
+}
+
+function tf_formatDate(dateStr, format)
+{
+	if(format==null) format = 'DMY';
+	var oDate, parts;
+	
+	function y2kDate(yr){
+		if(yr == undefined) return 0;
+		if(yr.length>2) return yr;
+		var y;
+		if(yr <= 99 && yr>50) //>50 belong to 1900
+			y = '19' + yr;
+		if(yr<50 || yr =='00') //<50 belong to 2000
+			y = '20' + yr;
+		return y;
+	}
+	
+	switch(format.toUpperCase())
+	{
+		case 'DMY':
+			parts = dateStr.replace(/^(0?[1-9]|[12][0-9]|3[01])([- \/.])(0?[1-9]|1[012])([- \/.])((\d\d)?\d\d)$/,'$1 $3 $5').split(' ');
+			oDate = new Date(y2kDate(parts[2]),parts[1]-1,parts[0]);
+		break;
+		case 'MDY':
+			parts = dateStr.replace(/^(0?[1-9]|1[012])([- \/.])(0?[1-9]|[12][0-9]|3[01])([- \/.])((\d\d)?\d\d)$/,'$1 $3 $5').split(' ');
+			oDate = new Date(y2kDate(parts[2]),parts[0]-1,parts[1]);
+		break;
+		case 'YMD':
+			parts = dateStr.replace(/^((\d\d)?\d\d)([- \/.])(0?[1-9]|1[012])([- \/.])(0?[1-9]|[12][0-9]|3[01])$/,'$1 $4 $6').split(' ');
+			oDate = new Date(y2kDate(parts[0]),parts[1]-1,parts[2]);
+		break;
+		default: //in case format is not correct
+			parts = dateStr.replace(/^(0?[1-9]|[12][0-9]|3[01])([- \/.])(0?[1-9]|1[012])([- \/.])((\d\d)?\d\d)$/,'$1 $3 $5').split(' ');
+			oDate = new Date(y2kDate(parts[2]),parts[1]-1,parts[0]);
+		break;
+	}
+	return oDate;
+}
+
+function tf_removeNbFormat(data,format)
+{
+	if(data==null) return;
+	if(format==null) format = 'us';
+	var n = data;
+	if( format.tf_LCase()=='us' )
+		n =+ n.replace(/[^\d\.-]/g,'');
+	else
+		n =+ n.replace(/[^\d\,-]/g,'').replace(',','.');
+	return n;
+}
+
+function tf_isImported(filePath,type)
+{
+	var isImported = false; 
+	var importType = (type==undefined) ? 'script' : type;
+	var files = tf_Tag(document,importType);
+	for (var i=0; i<files.length; i++)
+	{
+		if(files[i].src == undefined) continue;
+		if(files[i].src.match(filePath))
+		{
+			isImported = true;	
+			break;
+		}
+	}
+	return isImported;
+}
+
+function tf_WriteCookie(name, value, hours)
+{
+	var expire = '';
+	if(hours != null)
+	{
+		expire = new Date((new Date()).getTime() + hours * 3600000);
+		expire = '; expires=' + expire.toGMTString();
+	}
+	document.cookie = name + '=' + escape(value) + expire;
+}
+
+function tf_ReadCookie(name)
+{
+	var cookieValue = '';
+	var search = name + '=';
+	if(document.cookie.length > 0)
+	{ 
+		offset = document.cookie.indexOf(search);
+		if (offset != -1)
+		{ 
+			offset += search.length;
+			end = document.cookie.indexOf(';', offset);
+			if (end == -1) end = document.cookie.length;
+			cookieValue = unescape(document.cookie.substring(offset, end))
+		}
+	}
+	return cookieValue;
+}
+
+function tf_CookieValueArray(name)
+{
+	var val = tf_ReadCookie(name); //reads the cookie
+	var arr = val.split(','); //creates an array with filters' values
+	return arr;
+}
+
+function tf_CookieValueByIndex(name, index)
+{
+	var val = tf_CookieValueArray(name); //reads the cookie
+	return val[index];
+}
+
+function tf_RemoveCookie(name)
+{
+	tf_WriteCookie(name,'',-1);
+}
+/* --- */
+
+/*====================================================
+	- Backward compatibility fns
+=====================================================*/
+function grabEBI(id){ return tf_Id( id ); }
+function grabTag(obj,tagname){ return tf_Tag(obj,tagname); }
+function tf_GetCellText(n){ return tf_GetNodeText(n); }
+function tf_isObject(varname){ return tf_isObj(varname); }
+/* --- */
+    //]]>
+    </script>
+    
+    <script language="javascript" type="text/javascript">
+    //<![CDATA[
+    /**
+ * Copyright (c)2005-2009 Matt Kruse (javascripttoolbox.com)
+ * 
+ * Dual licensed under the MIT and GPL licenses. 
+ * This basically means you can use this code however you want for
+ * free, but don't claim to have written it yourself!
+ * Donations always accepted: http://www.JavascriptToolbox.com/donate/
+ * 
+ * Please do not link to the .js files on javascripttoolbox.com from
+ * your site. Copy the files locally to your server instead.
+ * 
+ */
+/* ******************************************************************* */
+/*   UTIL FUNCTIONS                                                    */
+/* ******************************************************************* */
+var Util = {'$VERSION':1.06};
+
+// Util functions - these are GLOBAL so they
+// look like built-in functions.
+
+// Determine if an object is an array
+function isArray(o) {
+	return (o!=null && typeof(o)=="object" && typeof(o.length)=="number" && (o.length==0 || defined(o[0])));
+};
+
+// Determine if an object is an Object
+function isObject(o) {
+	return (o!=null && typeof(o)=="object" && defined(o.constructor) && o.constructor==Object && !defined(o.nodeName));
+};
+
+// Determine if a reference is defined
+function defined(o) {
+	return (typeof(o)!="undefined");
+};
+
+// Iterate over an array, object, or list of items and run code against each item
+// Similar functionality to Perl's map() function
+function map(func) {
+	var i,j,o;
+	var results = [];
+	if (typeof(func)=="string") {
+		func = new Function('$_',func);
+	}
+	for (i=1; i<arguments.length; i++) {
+		o = arguments[i];
+		if (isArray(o)) {
+			for (j=0; j<o.length; j++) {
+				results[results.length] = func(o[j]);
+			}
+		}
+		else if (isObject(o)) {
+			for (j in o) {
+				results[results.length] = func(o[j]);
+			}
+		}
+		else {
+			results[results.length] = func(o);
+		}
+	}
+	return results;
+};
+
+// Set default values in an object if they are undefined
+function setDefaultValues(o,values) {
+	if (!defined(o) || o==null) {
+		o = {};
+	}
+	if (!defined(values) || values==null) {
+		return o;
+	}
+	for (var val in values) {
+		if (!defined(o[val])) {
+			o[val] = values[val];
+		}
+	}
+	return o;
+};
+
+/* ******************************************************************* */
+/*   DEFAULT OBJECT PROTOTYPE ENHANCEMENTS                             */
+/* ******************************************************************* */
+// These functions add useful functionality to built-in objects
+Array.prototype.contains = function(o) {
+	var i,l;
+	if (!(l = this.length)) { return false; }
+	for (i=0; i<l; i++) {
+		if (o==this[i]) {
+			return true;
+		}
+	}
+};
+
+/* ******************************************************************* */
+/*   DOM FUNCTIONS                                                     */
+/* ******************************************************************* */
+var DOM = (function() { 
+	var dom = {};
+	
+	// Get a parent tag with a given nodename
+	dom.getParentByTagName = function(o,tagNames) {
+		if(o==null) { return null; }
+		if (isArray(tagNames)) {
+			tagNames = map("return $_.toUpperCase()",tagNames);
+			while (o=o.parentNode) {
+				if (o.nodeName && tagNames.contains(o.nodeName)) {
+					return o;
+				}
+			}
+		}
+		else {
+			tagNames = tagNames.toUpperCase();
+			while (o=o.parentNode) {
+				if (o.nodeName && tagNames==o.nodeName) {
+					return o;
+				}
+			}
+		}
+		return null;
+	};
+	
+	// Remove a node from its parent
+	dom.removeNode = function(o) {
+		if (o!=null && o.parentNode && o.parentNode.removeChild) {
+			// First remove all attributes which are func references, to avoid memory leaks
+			for (var i in o) {
+				if (typeof(o[i])=="function") {
+					o[i] = null;
+				}
+			}
+			o.parentNode.removeChild(o);
+			return true;
+		}
+		return false;
+	};
+
+	// Get the outer width in pixels of an object, including borders, padding, and margin
+	dom.getOuterWidth = function(o) {
+		if (defined(o.offsetWidth)) {
+			return o.offsetWidth;
+		}
+		return null;
+	};
+
+	// Get the outer height in pixels of an object, including borders, padding, and margin
+	dom.getOuterHeight = function(o) {
+		if (defined(o.offsetHeight)) {
+			return o.offsetHeight;
+		}
+		return null;
+	};
+
+	// Resolve an item, an array of items, or an object of items
+	dom.resolve = function() {
+		var results = new Array();
+		var i,j,o;
+		for (var i=0; i<arguments.length; i++) {
+			var o = arguments[i];
+			if (o==null) {
+				if (arguments.length==1) {
+					return null;
+				}
+				results[results.length] = null;
+			}
+			else if (typeof(o)=='string') {
+				if (document.getElementById) {
+					o = document.getElementById(o);
+				}
+				else if (document.all) {
+					o = document.all[o];
+				}
+				if (arguments.length==1) {
+					return o;
+				}
+				results[results.length] = o;
+			}
+			else if (isArray(o)) {
+				for (j=0; j<o.length; j++) {
+					results[results.length] = o[j];
+				}
+			}
+			else if (isObject(o)) {
+				for (j in o) {
+					results[results.length] = o[j];
+				}
+			}
+			else if (arguments.length==1) {
+				return o;
+			}
+			else {
+				results[results.length] = o;
+			}
+	  }
+	  return results;
+	};
+	dom.$ = dom.resolve;
+	
+	return dom;
+})();
+
+/* ******************************************************************* */
+/*   CSS FUNCTIONS                                                     */
+/* ******************************************************************* */
+var CSS = (function(){
+	var css = {};
+
+	// Convert an RGB string in the form "rgb (255, 255, 255)" to "#ffffff"
+	css.rgb2hex = function(rgbString) {
+		if (typeof(rgbString)!="string" || !defined(rgbString.match)) { return null; }
+		var result = rgbString.match(/^\s*rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*/);
+		if (result==null) { return rgbString; }
+		var rgb = +result[1] << 16 | +result[2] << 8 | +result[3];
+		var hex = "";
+		var digits = "0123456789abcdef";
+		while(rgb!=0) { 
+			hex = digits.charAt(rgb&0xf)+hex; 
+			rgb>>>=4; 
+		} 
+		while(hex.length<6) { hex='0'+hex; }
+		return "#" + hex;
+	};
+
+	// Convert hyphen style names like border-width to camel case like borderWidth
+	css.hyphen2camel = function(property) {
+		if (!defined(property) || property==null) { return null; }
+		if (property.indexOf("-")<0) { return property; }
+		var str = "";
+		var c = null;
+		var l = property.length;
+		for (var i=0; i<l; i++) {
+			c = property.charAt(i);
+			str += (c!="-")?c:property.charAt(++i).toUpperCase();
+		}
+		return str;
+	};
+	
+	// Determine if an object or class string contains a given class.
+	css.hasClass = function(obj,className) {
+		if (!defined(obj) || obj==null || !RegExp) { return false; }
+		var re = new RegExp("(^|\\s)" + className + "(\\s|$)");
+		if (typeof(obj)=="string") {
+			return re.test(obj);
+		}
+		else if (typeof(obj)=="object" && obj.className) {
+			return re.test(obj.className);
+		}
+		return false;
+	};
+	
+	// Add a class to an object
+	css.addClass = function(obj,className) {
+		if (typeof(obj)!="object" || obj==null || !defined(obj.className)) { return false; }
+		if (obj.className==null || obj.className=='') { 
+			obj.className = className; 
+			return true; 
+		}
+		if (css.hasClass(obj,className)) { return true; }
+		obj.className = obj.className + " " + className;
+		return true;
+	};
+	
+	// Remove a class from an object
+	css.removeClass = function(obj,className) {
+		if (typeof(obj)!="object" || obj==null || !defined(obj.className) || obj.className==null) { return false; }
+		if (!css.hasClass(obj,className)) { return false; }
+		var re = new RegExp("(^|\\s+)" + className + "(\\s+|$)");
+		obj.className = obj.className.replace(re,' ');
+		return true;
+	};
+	
+	// Fully replace a class with a new one
+	css.replaceClass = function(obj,className,newClassName) {
+		if (typeof(obj)!="object" || obj==null || !defined(obj.className) || obj.className==null) { return false; }
+		css.removeClass(obj,className);
+		css.addClass(obj,newClassName);
+		return true;
+	};
+	
+	// Get the currently-applied style of an object
+	css.getStyle = function(o, property) {
+		if (o==null) { return null; }
+		var val = null;
+		var camelProperty = css.hyphen2camel(property);
+		// Handle "float" property as a special case
+		if (property=="float") {
+			val = css.getStyle(o,"cssFloat");
+			if (val==null) { 
+				val = css.getStyle(o,"styleFloat"); 
+			}
+		}
+		else if (o.currentStyle && defined(o.currentStyle[camelProperty])) {
+			val = o.currentStyle[camelProperty];
+		}
+		else if (window.getComputedStyle) {
+			val = window.getComputedStyle(o,null).getPropertyValue(property);
+		}
+		else if (o.style && defined(o.style[camelProperty])) {
+			val = o.style[camelProperty];
+		}
+		// For color values, make the value consistent across browsers
+		// Convert rgb() colors back to hex for consistency
+		if (/^\s*rgb\s*\(/.test(val)) {
+			val = css.rgb2hex(val);
+		}
+		// Lowercase all #hex values
+		if (/^#/.test(val)) {
+			val = val.toLowerCase();
+		}
+		return val;
+	};
+	css.get = css.getStyle;
+
+	// Set a style on an object
+	css.setStyle = function(o, property, value) {
+		if (o==null || !defined(o.style) || !defined(property) || property==null || !defined(value)) { return false; }
+		if (property=="float") {
+			o.style["cssFloat"] = value;
+			o.style["styleFloat"] = value;
+		}
+		else if (property=="opacity") {
+			o.style['-moz-opacity'] = value;
+			o.style['-khtml-opacity'] = value;
+			o.style.opacity = value;
+			if (defined(o.style.filter)) {
+				o.style.filter = "alpha(opacity=" + value*100 + ")";
+			}
+		}
+		else {
+			o.style[css.hyphen2camel(property)] = value;
+		}
+		return true;
+	};
+	css.set = css.setStyle;
+	
+	// Get a unique ID which doesn't already exist on the page
+	css.uniqueIdNumber=1000;
+	css.createId = function(o) {
+		if (defined(o) && o!=null && defined(o.id) && o.id!=null && o.id!="") { 
+			return o.id;
+		}
+		var id = null;
+		while (id==null || document.getElementById(id)!=null) {
+			id = "ID_"+(css.uniqueIdNumber++);
+		}
+		if (defined(o) && o!=null && (!defined(o.id)||o.id=="")) {
+			o.id = id;
+		}
+		return id;
+	};
+	
+	return css;
+})();
+
+/* ******************************************************************* */
+/*   EVENT FUNCTIONS                                                   */
+/* ******************************************************************* */
+
+var Event = (function(){
+	var ev = {};
+	
+	// Resolve an event using IE's window.event if necessary
+	// --------------------------------------------------------------------
+	ev.resolve = function(e) {
+		if (!defined(e) && defined(window.event)) {
+			e = window.event;
+		}
+		return e;
+	};
+	
+	// Add an event handler to a function
+	// Note: Don't use 'this' within functions added using this method, since
+	// the attachEvent and addEventListener models differ.
+	// --------------------------------------------------------------------
+	ev.add = function( obj, type, fn, capture ) {
+		if (obj.addEventListener) {
+			obj.addEventListener( type, fn, capture );
+			return true;
+		}
+		else if (obj.attachEvent) {
+			obj.attachEvent( "on"+type, fn );
+			return true;
+		}
+		return false;
+	};
+
+	// Get the mouse position of an event
+	// --------------------------------------------------------------------
+	// PageX/Y, where they exist, are more reliable than ClientX/Y because 
+	// of some browser bugs in Opera/Safari
+	ev.getMouseX = function(e) {
+		e = ev.resolve(e);
+		if (defined(e.pageX)) {
+			return e.pageX;
+		}
+		if (defined(e.clientX)) {
+			return e.clientX+Screen.getScrollLeft();
+		}
+		return null;
+	};
+	ev.getMouseY = function(e) {
+		e = ev.resolve(e);
+		if (defined(e.pageY)) {
+			return e.pageY;
+		}
+		if (defined(e.clientY)) {
+			return e.clientY+Screen.getScrollTop();
+		}
+		return null;
+	};
+
+	// Stop the event from bubbling up to parent elements.
+	// Two method names map to the same function
+	// --------------------------------------------------------------------
+	ev.cancelBubble = function(e) {
+		e = ev.resolve(e);
+		if (typeof(e.stopPropagation)=="function") { e.stopPropagation(); } 
+		if (defined(e.cancelBubble)) { e.cancelBubble = true; }
+	};
+	ev.stopPropagation = ev.cancelBubble;
+
+	// Prevent the default handling of the event to occur
+	// --------------------------------------------------------------------
+	ev.preventDefault = function(e) {
+		e = ev.resolve(e);
+		if (typeof(e.preventDefault)=="function") { e.preventDefault(); } 
+		if (defined(e.returnValue)) { e.returnValue = false; }
+	};
+	
+	return ev;
+})();
+
+/* ******************************************************************* */
+/*   SCREEN FUNCTIONS                                                  */
+/* ******************************************************************* */
+var Screen = (function() {
+	var screen = {};
+
+	// Get a reference to the body
+	// --------------------------------------------------------------------
+	screen.getBody = function() {
+		if (document.body) {
+			return document.body;
+		}
+		if (document.getElementsByTagName) {
+			var bodies = document.getElementsByTagName("BODY");
+			if (bodies!=null && bodies.length>0) {
+				return bodies[0];
+			}
+		}
+		return null;
+	};
+
+	// Get the amount that the main document has scrolled from top
+	// --------------------------------------------------------------------
+	screen.getScrollTop = function() {
+		if (document.documentElement && defined(document.documentElement.scrollTop) && document.documentElement.scrollTop>0) {
+			return document.documentElement.scrollTop;
+		}
+		if (document.body && defined(document.body.scrollTop)) {
+			return document.body.scrollTop;
+		}
+		return null;
+	};
+	
+	// Get the amount that the main document has scrolled from left
+	// --------------------------------------------------------------------
+	screen.getScrollLeft = function() {
+		if (document.documentElement && defined(document.documentElement.scrollLeft) && document.documentElement.scrollLeft>0) {
+			return document.documentElement.scrollLeft;
+		}
+		if (document.body && defined(document.body.scrollLeft)) {
+			return document.body.scrollLeft;
+		}
+		return null;
+	};
+	
+	// Util function to default a bad number to 0
+	// --------------------------------------------------------------------
+	screen.zero = function(n) {
+		return (!defined(n) || isNaN(n))?0:n;
+	};
+
+	// Get the width of the entire document
+	// --------------------------------------------------------------------
+	screen.getDocumentWidth = function() {
+		var width = 0;
+		var body = screen.getBody();
+		if (document.documentElement && (!document.compatMode || document.compatMode=="CSS1Compat")) {
+		    var rightMargin = parseInt(CSS.get(body,'marginRight'),10) || 0;
+		    var leftMargin = parseInt(CSS.get(body,'marginLeft'), 10) || 0;
+			width = Math.max(body.offsetWidth + leftMargin + rightMargin, document.documentElement.clientWidth);
+		}
+		else {
+			width =  Math.max(body.clientWidth, body.scrollWidth);
+		}
+		if (isNaN(width) || width==0) {
+			width = screen.zero(self.innerWidth);
+		}
+		return width;
+	};
+	
+	// Get the height of the entire document
+	// --------------------------------------------------------------------
+	screen.getDocumentHeight = function() {
+		var body = screen.getBody();
+		var innerHeight = (defined(self.innerHeight)&&!isNaN(self.innerHeight))?self.innerHeight:0;
+		if (document.documentElement && (!document.compatMode || document.compatMode=="CSS1Compat")) {
+		    var topMargin = parseInt(CSS.get(body,'marginTop'),10) || 0;
+		    var bottomMargin = parseInt(CSS.get(body,'marginBottom'), 10) || 0;
+			return Math.max(body.offsetHeight + topMargin + bottomMargin, document.documentElement.clientHeight, document.documentElement.scrollHeight, screen.zero(self.innerHeight));
+		}
+		return Math.max(body.scrollHeight, body.clientHeight, screen.zero(self.innerHeight));
+	};
+	
+	// Get the width of the viewport (viewable area) in the browser window
+	// --------------------------------------------------------------------
+	screen.getViewportWidth = function() {
+		if (document.documentElement && (!document.compatMode || document.compatMode=="CSS1Compat")) {
+			return document.documentElement.clientWidth;
+		}
+		else if (document.compatMode && document.body) {
+			return document.body.clientWidth;
+		}
+		return screen.zero(self.innerWidth);
+	};
+	
+	// Get the height of the viewport (viewable area) in the browser window
+	// --------------------------------------------------------------------
+	screen.getViewportHeight = function() {
+		if (!window.opera && document.documentElement && (!document.compatMode || document.compatMode=="CSS1Compat")) {
+			return document.documentElement.clientHeight;
+		}
+		else if (document.compatMode && !window.opera && document.body) {
+			return document.body.clientHeight;
+		}
+		return screen.zero(self.innerHeight);
+	};
+
+	return screen;
+})();var Sort = (function(){
+	var sort = {};
+	sort.AlphaNumeric = function(a,b) {
+		if (a==b) { return 0; }
+		if (a<b) { return -1; }
+		return 1;
+	};
+
+	sort.Default = sort.AlphaNumeric;
+	
+	sort.NumericConversion = function(val) {
+		if (typeof(val)!="number") {
+			if (typeof(val)=="string") {
+				val = parseFloat(val.replace(/,/g,''));
+				if (isNaN(val) || val==null) { val=0; }
+			}
+			else {
+				val = 0;
+			}
+		}
+		return val;
+	};
+	
+	sort.Numeric = function(a,b) {
+		return sort.NumericConversion(a)-sort.NumericConversion(b);
+	};
+
+	sort.IgnoreCaseConversion = function(val) {
+		if (val==null) { val=""; }
+		return (""+val).toLowerCase();
+	};
+
+	sort.IgnoreCase = function(a,b) {
+		return sort.AlphaNumeric(sort.IgnoreCaseConversion(a),sort.IgnoreCaseConversion(b));
+	};
+
+	sort.CurrencyConversion = function(val) {
+		if (typeof(val)=="string") {
+			val = val.replace(/^[^\d\.]/,'');
+		}
+		return sort.NumericConversion(val);
+	};
+	
+	sort.Currency = function(a,b) {
+		return sort.Numeric(sort.CurrencyConversion(a),sort.CurrencyConversion(b));
+	};
+	
+	sort.DateConversion = function(val) {
+		// inner util function to parse date formats
+		function getdate(str) {
+			// inner util function to convert 2-digit years to 4
+			function fixYear(yr) {
+				yr = +yr;
+				if (yr<50) { yr += 2000; }
+				else if (yr<100) { yr += 1900; }
+				return yr;
+			};
+			var ret;
+			// YYYY-MM-DD
+			if (ret=str.match(/(\d{2,4})-(\d{1,2})-(\d{1,2})/)) {
+				return (fixYear(ret[1])*10000) + (ret[2]*100) + (+ret[3]);
+			}
+			// MM/DD/YY[YY] or MM-DD-YY[YY]
+			if (ret=str.match(/(\d{1,2})[\/-](\d{1,2})[\/-](\d{2,4})/)) {
+				return (fixYear(ret[3])*10000) + (ret[1]*100) + (+ret[2]);
+			}
+			return 99999999; // So non-parsed dates will be last, not first
+		};
+		return getdate(val);
+	};
+
+	sort.Date = function(a,b) {
+		return sort.Numeric(sort.DateConversion(a),sort.DateConversion(b));
+	};
+
+	return sort;
+})();
+
+var Position = (function() {
+	// Resolve a string identifier to an object
+	// ========================================
+	function resolveObject(s) {
+		if (document.getElementById && document.getElementById(s)!=null) {
+			return document.getElementById(s);
+		}
+		else if (document.all && document.all[s]!=null) {
+			return document.all[s];
+		}
+		else if (document.anchors && document.anchors.length && document.anchors.length>0 && document.anchors[0].x) {
+			for (var i=0; i<document.anchors.length; i++) {
+				if (document.anchors[i].name==s) { 
+					return document.anchors[i]
+				}
+			}
+		}
+	}
+	
+	var pos = {};
+	pos.$VERSION = 1.0;
+	
+	// Set the position of an object
+	// =============================
+	pos.set = function(o,left,top) {
+		if (typeof(o)=="string") {
+			o = resolveObject(o);
+		}
+		if (o==null || !o.style) {
+			return false;
+		}
+		
+		// If the second parameter is an object, it is assumed to be the result of getPosition()
+		if (typeof(left)=="object") {
+			var pos = left;
+			left = pos.left;
+			top = pos.top;
+		}
+		
+		o.style.left = left + "px";
+		o.style.top = top + "px";
+		return true;
+	};
+	
+	// Retrieve the position and size of an object
+	// ===========================================
+	pos.get = function(o) {
+		var fixBrowserQuirks = true;
+			// If a string is passed in instead of an object ref, resolve it
+		if (typeof(o)=="string") {
+			o = resolveObject(o);
+		}
+		
+		if (o==null) {
+			return null;
+		}
+		
+		var left = 0;
+		var top = 0;
+		var width = 0;
+		var height = 0;
+		var parentNode = null;
+		var offsetParent = null;
+	
+		
+		offsetParent = o.offsetParent;
+		var originalObject = o;
+		var el = o; // "el" will be nodes as we walk up, "o" will be saved for offsetParent references
+		while (el.parentNode!=null) {
+			el = el.parentNode;
+			if (el.offsetParent==null) {
+			}
+			else {
+				var considerScroll = true;
+				/*
+				In Opera, if parentNode of the first object is scrollable, then offsetLeft/offsetTop already 
+				take its scroll position into account. If elements further up the chain are scrollable, their 
+				scroll offsets still need to be added in. And for some reason, TR nodes have a scrolltop value
+				which must be ignored.
+				*/
+				if (fixBrowserQuirks && window.opera) {
+					if (el==originalObject.parentNode || el.nodeName=="TR") {
+						considerScroll = false;
+					}
+				}
+				if (considerScroll) {
+					if (el.scrollTop && el.scrollTop>0) {
+						top -= el.scrollTop;
+					}
+					if (el.scrollLeft && el.scrollLeft>0) {
+						left -= el.scrollLeft;
+					}
+				}
+			}
+			// If this node is also the offsetParent, add on the offsets and reset to the new offsetParent
+			if (el == offsetParent) {
+				left += o.offsetLeft;
+				if (el.clientLeft && el.nodeName!="TABLE") { 
+					left += el.clientLeft;
+				}
+				top += o.offsetTop;
+				if (el.clientTop && el.nodeName!="TABLE") {
+					top += el.clientTop;
+				}
+				o = el;
+				if (o.offsetParent==null) {
+					if (o.offsetLeft) {
+						left += o.offsetLeft;
+					}
+					if (o.offsetTop) {
+						top += o.offsetTop;
+					}
+				}
+				offsetParent = o.offsetParent;
+			}
+		}
+		
+	
+		if (originalObject.offsetWidth) {
+			width = originalObject.offsetWidth;
+		}
+		if (originalObject.offsetHeight) {
+			height = originalObject.offsetHeight;
+		}
+		
+		return {'left':left, 'top':top, 'width':width, 'height':height
+				};
+	};
+	
+	// Retrieve the position of an object's center point
+	// =================================================
+	pos.getCenter = function(o) {
+		var c = this.get(o);
+		if (c==null) { return null; }
+		c.left = c.left + (c.width/2);
+		c.top = c.top + (c.height/2);
+		return c;
+	};
+	
+	return pos;
+})();// CLASS CONSTRUCTOR
+// --------------------------------------------------------------------
+var Popup = function(div, options) {
+	this.div = defined(div)?div:null;
+	this.index = Popup.maxIndex++;
+	this.ref = "Popup.objects["+this.index+"]";
+	Popup.objects[this.index] = this;
+	// Store a reference to the DIV by id, also
+	if (typeof(this.div)=="string") {
+		Popup.objectsById[this.div] = this;
+	}
+	if (defined(this.div) && this.div!=null && defined(this.div.id)) {
+		Popup.objectsById[this.div.id] = this.div.id;
+	}
+	// Apply passed-in options
+	if (defined(options) && options!=null && typeof(options)=="object") {
+		for (var i in options) {
+			this[i] = options[i];
+		}
+	}
+	return this;
+};
+
+// CLASS PROPERTIES
+// --------------------------------------------------------------------
+// Index of popup objects, to maintain a global reference if necessary
+Popup.maxIndex = 0;
+Popup.objects = {};
+Popup.objectsById = {};
+
+// The z-index value that popups will start at
+Popup.minZIndex = 101;
+
+// Class names to assign to other objects
+Popup.screenClass = "PopupScreen";
+Popup.iframeClass = "PopupIframe";
+Popup.screenIframeClass = "PopupScreenIframe";
+
+// CLASS METHODS
+// --------------------------------------------------------------------
+
+// Hide all currently-visible non-modal dialogs
+Popup.hideAll = function() {
+	for (var i in Popup.objects) {
+		var p = Popup.objects[i];
+		if (!p.modal && p.autoHide) {
+			p.hide();
+		}
+	}
+};
+// Catch global events as a trigger to hide auto-hide popups
+Event.add(document, "mouseup", Popup.hideAll, false);
+
+// A simple class method to show a popup without creating an instance
+Popup.show = function(divObject, referenceObject, position, options, modal) {
+	var popup;
+	if (defined(divObject)) { 
+		popup = new Popup(divObject);
+	}
+	else {
+		popup = new Popup();
+		popup.destroyDivOnHide = true;
+	}
+	if (defined(referenceObject)) { popup.reference = DOM.resolve(referenceObject); }
+	if (defined(position)) { popup.position = position; }
+	if (defined(options) && options!=null && typeof(options)=="object") {
+		for (var i in options) {
+			popup[i] = options[i];
+		}
+	}
+	if (typeof(modal)=="boolean") {
+		popup.modal = modal;
+	}
+	popup.destroyObjectsOnHide = true;
+	popup.show();
+	return popup;
+};
+
+// A simple class method to show a modal popup
+Popup.showModal = function(divObject, referenceObject, position, options) {
+	Popup.show(divObject, referenceObject, position, options, true);
+};
+
+// A method to retrieve a popup object based on a div ID
+Popup.get = function(divId) {
+	if (defined(Popup.objectsById[divId])) {
+		return Popup.objectsById[divId];
+	}
+	return null;
+};
+
+// A method to hide a popup based on a div id
+Popup.hide = function(divId) {
+	var popup = Popup.get(divId);
+	if (popup!=null) {
+		popup.hide();
+	}
+};
+
+// PROTOTYPE PROPERTIES
+// --------------------------------------------------------------------
+Popup.prototype.content = null;
+Popup.prototype.className = "PopupDiv";
+Popup.prototype.style = null; // Styles to be applied to the DIV
+Popup.prototype.width = null;
+Popup.prototype.height = null;
+Popup.prototype.top = null;
+Popup.prototype.left = null;
+Popup.prototype.offsetLeft = 0;
+Popup.prototype.offsetTop = 0;
+Popup.prototype.constrainToScreen = true;
+Popup.prototype.autoHide = true;
+Popup.prototype.useIframeShim = false; /*@cc_on @*/ /*@if (@_win32) {Popup.prototype.useIframeShim = true;} @end @*/ 
+Popup.prototype.iframe = null;
+Popup.prototype.position = null; // vertical: "above top center bottom below", horizontal: "adjacent-left,left,center,right,adjacent-right"
+Popup.prototype.reference = null;
+Popup.prototype.modal = false;
+Popup.prototype.destroyDivOnHide = false;
+Popup.prototype.destroyObjectsOnHide = false;
+Popup.prototype.screen = null;
+Popup.prototype.screenIframeShim = null;
+Popup.prototype.screenOpacity=.4;
+Popup.prototype.screenColor="#cccccc";
+
+// INSTANCE METHODS
+// --------------------------------------------------------------------
+
+// Show the popup
+// --------------------------------------------------------------------
+Popup.prototype.show = function(options, modal) {
+	this.modal = this.modal || (typeof(modal)=="boolean" && modal);
+	if (defined(options) && options!=null && typeof(options)=="object") {
+		for (var i in options) {
+			this[i] = options[i];
+		}
+	}
+	this.div = DOM.resolve(this.div);
+	CSS.setStyle(this.div,'position','absolute');
+	
+	// If there is no div pre-defined to use, create one
+	if (this.div==null) {
+		this.div = this.createDiv();
+	}
+	if (this.content!=null) {
+		this.div.innerHTML = this.content;
+		this.content = null;
+	}
+	if (this.className!=null) {
+		this.div.className = this.className;
+	}
+	if (this.style!=null) {
+		this.applyStyle();
+	}
+	if (this.width!=null) {
+		this.div.style.width = this.width+"px";
+		this.div.style.overflowX="auto";
+	}
+	if (this.height!=null) {
+		this.div.style.height = this.height+"px";
+		this.div.style.overflowY="auto";
+	}
+
+	// Do the actual display - this is a separate method so display transitions can be implemented
+	this.transition();
+	
+	// Make sure clicks on the DIV don't bubble up to the document
+	this.div.onclick = function(e) { 
+		Event.cancelBubble(Event.resolve(e));
+	};
+	this.div.onmouseup = this.div.onclick;
+	
+	// Focus to the DIV if possible	
+	if (this.modal && this.div.focus) {
+		this.div.focus();
+	}
+};
+
+// Show the popup but make it modal
+// --------------------------------------------------------------------
+Popup.prototype.transition = function() {
+	if (this.modal) {
+		this.addScreen();
+	}
+	
+	// Make the DIV displayed but hidden so its size can be measured
+	CSS.setStyle(this.div,'visibility','hidden');
+	CSS.setStyle(this.div,'display','block');
+
+	// Position the popup
+	this.setPosition();
+
+	// Add the shim if necessary	
+	if (this.useIframeShim) {
+		this.addIframeShim();
+	}
+
+	// Make sure the DIV is higher than the shim
+	this.div.style.zIndex = Popup.minZIndex++;
+
+	CSS.setStyle(this.div,'display','block');
+	CSS.setStyle(this.div,'visibility','visible');
+};
+
+// Show the popup but make it modal
+// --------------------------------------------------------------------
+Popup.prototype.showModal = function(options) {
+	this.show(options,true);
+};
+
+// Apply user styles to the DIV
+// --------------------------------------------------------------------
+Popup.prototype.applyStyle = function() {
+	if (this.div!=null && this.style!=null && typeof(this.style)=="object") {
+		for (var i in this.style) {
+			this.div.style[i] = this.style[i];
+		}
+	}
+};
+
+// Hide the popup
+// --------------------------------------------------------------------
+Popup.prototype.hide = function() {
+	// If this was a temp object creating on-the-fly, then remove objects from the DOM so
+	// The document doesn't get littered with extra objects
+	if (this.destroyDivOnHide) {
+		DOM.removeNode(this.div);
+		this.div = null;
+		delete Popup.objects[this.id];
+	}
+	else if (this.div!=null) {
+		CSS.setStyle(this.div,'display','none');
+	}
+
+	if (this.destroyObjectsOnHide) {
+		DOM.removeNode(this.iframe);
+		DOM.removeNode(this.screen);
+		DOM.removeNode(this.screenIframeShim);
+	}
+	else {
+		if (this.iframe!=null) {
+			this.iframe.style.display = "none";
+		}
+		if (this.screen!=null) {
+			this.screen.style.display = "none";
+		}
+		if (this.screenIframeShim!=null) {
+			this.screenIframeShim.style.display = "none";
+		}
+	}
+};
+
+// Util funcs for position
+// --------------------------------------------------------------------
+Popup.prototype.setTop = function(top) {
+	this.div.style.top = top+"px";
+};
+Popup.prototype.setLeft = function(left) {
+	this.div.style.left = left+"px";
+};
+Popup.prototype.getTop = function() {
+	return parseInt(CSS.getStyle(this.div,"top"),10);
+};
+Popup.prototype.getLeft = function() {
+	return parseInt(CSS.getStyle(this.div,"left"),10);
+};
+
+// All the logic to position the popup based on various criteria
+// --------------------------------------------------------------------
+Popup.prototype.setPosition = function() {
+	if (this.position!=null) {
+		var m = this.position.match(/^(\S+)\s+(\S+)/); 
+		if (m!=null && m.length==3) {
+			var v = m[1];
+			var h = m[2];
+
+			var ref = this.reference;
+			if (ref==null) { ref = Screen.getBody(); }
+			var p = Position.get(ref);
+			var refTop = p.top;
+			var refLeft = p.left;
+			var refWidth = DOM.getOuterWidth(ref);
+			var refHeight = DOM.getOuterHeight(ref);
+			
+			var width = DOM.getOuterWidth(this.div);
+			var height = DOM.getOuterHeight(this.div);
+			
+			var scrollLeft = Screen.getScrollLeft();
+			var scrollTop = Screen.getScrollTop();
+
+			// Set vertical position relative to reference object
+			if (v=="above") { this.setTop(refTop-height+this.offsetTop); }
+			else if (v=="top") { this.setTop(refTop+this.offsetTop); }
+			else if (v=="center") { this.setTop(refTop+(refHeight/2)-(height/2)+this.offsetTop); }
+			else if (v=="bottom") { this.setTop(refTop+refHeight-height+this.offsetTop); }
+			else if (v=="below") { this.setTop(refTop+refHeight+this.offsetTop); }
+
+			// Set horizontal position relative to reference object
+			if (h=="adjacent-left") { this.setLeft(refLeft-width+this.offsetLeft); }
+			else if (h=="left") { this.setLeft(refLeft+this.offsetLeft); }
+			else if (h=="center") { this.setLeft(refLeft+(refWidth/2)-(width/2)+this.offsetLeft); }
+			else if (h=="right") { this.setLeft(refLeft+refWidth-width+this.offsetLeft); }
+			else if (h=="adjacent-right") { this.setLeft(refLeft+refWidth+this.offsetLeft); }
+		}
+	}
+	else if (this.top==null && this.left==null) {
+		this.center();
+	}
+	else {
+		if (this.top==null) { this.top=0; }
+		if (this.left==null) { this.left=0; }
+		this.div.style.top = this.top+this.offsetTop+"px";
+		this.div.style.left = this.left+this.offsetLeft+"px";
+	}
+
+	// Re-position to make sure it stays on the screen
+	if (this.constrainToScreen) {
+		this.fitToScreen();
+	}
+};
+
+// Append an object to the body
+// --------------------------------------------------------------------
+Popup.prototype.appendToBody = function(o) {
+	var body = Screen.getBody();
+	if (body && body.appendChild) {
+		body.appendChild(o);
+	}
+};
+
+// Create a new DIV object to be used for a popup
+// --------------------------------------------------------------------
+Popup.prototype.createDiv = function() {
+	if (document.createElement) {
+		var d = document.createElement("DIV");
+		d.style.position="absolute";
+		d.style.display="block";
+		d.style.visibility="hidden";
+		this.appendToBody(d);
+		return d;
+	}
+	alert("ERROR: Couldn't create DIV element in Popup.prototype.createDiv()");
+	return null;
+};
+
+// Create a new IFRAME object to be used behind the popup
+// --------------------------------------------------------------------
+Popup.prototype.createIframe = function() {
+	if (document.createElement) {
+		var i= document.createElement("IFRAME");
+		i.style.position="absolute";
+		i.style.display="block";
+		i.style.visibility="hidden";
+		i.style.background="none";
+		this.appendToBody(i);
+		return i;
+	}
+	else {
+		alert("ERROR: Couldn't create IFRAME object in Popup.prototype.createIframe()");
+	}
+};
+
+// Add an IFRAME shim for the DIV
+// --------------------------------------------------------------------
+Popup.prototype.addIframeShim = function() {
+	if (this.iframe==null) {
+		this.iframe = this.createIframe();
+	}
+	this.iframe.className = Popup.iframeClass;
+	CSS.setStyle(this.iframe,'top',this.getTop()+"px");
+	CSS.setStyle(this.iframe,'left',this.getLeft()+"px");
+	CSS.setStyle(this.iframe,'width',DOM.getOuterWidth(this.div) + "px");
+	CSS.setStyle(this.iframe,'height',DOM.getOuterHeight(this.div) + "px");
+	CSS.setStyle(this.iframe,'zIndex',Popup.minZIndex++);
+	CSS.setStyle(this.iframe,'opacity',0);
+	CSS.setStyle(this.iframe,'visibility','visible');
+	CSS.setStyle(this.iframe,'display','block');
+};
+
+// Create a "screen" to make a popup modal
+// --------------------------------------------------------------------
+Popup.prototype.addScreen = function() {
+	if (this.screen==null) {
+		this.screen = this.createDiv();
+		this.screen.style.top="0px";
+		this.screen.style.left="0px";
+		this.screen.style.backgroundColor = this.screenColor;
+		this.screen.className=Popup.screenClass;;
+		CSS.setStyle(this.screen,"opacity",this.screenOpacity);
+		this.screen.onclick = function(e) { Event.cancelBubble(Event.resolve(e)); }
+	}
+	if (this.screenIframeShim==null) {
+		this.screenIframeShim = this.createIframe();
+		this.screenIframeShim.style.top="0px";
+		this.screenIframeShim.style.left="0px";
+		this.screenIframeShim.className=Popup.screenIframeClass;
+		CSS.setStyle(this.screenIframeShim,"opacity",0);
+	}
+	this.screen.style.width = Screen.getDocumentWidth()+"px";
+	this.screen.style.height = Screen.getDocumentHeight()+"px";
+	this.screenIframeShim.style.width = Screen.getDocumentWidth()+"px";
+	this.screenIframeShim.style.height = Screen.getDocumentHeight()+"px";
+	this.screenIframeShim.style.zIndex = Popup.minZIndex++;
+	this.screenIframeShim.style.visibility="visible";
+	this.screenIframeShim.style.display="block";
+	this.screen.style.zIndex = Popup.minZIndex++;
+	this.screen.style.visibility="visible";
+	this.screen.style.display="block";
+};
+
+// Re-position the DIV so it stays on the screen
+// --------------------------------------------------------------------
+Popup.prototype.fitToScreen = function() {
+	var width = DOM.getOuterWidth(this.div);
+	var height = DOM.getOuterHeight(this.div);
+	var top = this.getTop();
+	var left = this.getLeft();
+	
+	var clientWidth = Screen.getViewportWidth();
+	var clientHeight = Screen.getViewportHeight();
+	
+	var scrollLeft = Screen.getScrollLeft();
+	var scrollTop = Screen.getScrollTop();
+
+	if (top-scrollTop+height>clientHeight) {
+		top = top - ((top+height) - (scrollTop+clientHeight));
+		this.div.style.top = top + "px";
+	}
+	if (left-scrollLeft+width>clientWidth) {
+		left = left - ((left+width) - (scrollLeft+clientWidth));
+		this.div.style.left = left + "px";
+	}
+	if (top<scrollTop) {
+		this.div.style.top=scrollTop+"px";
+	}
+	if (left<scrollLeft) {
+		this.div.style.left=scrollLeft+"px";
+	}
+};
+
+// Center the DIV object
+// --------------------------------------------------------------------
+Popup.prototype.center = function() {
+	var left = DOM.getOuterWidth(this.div);
+	var top = DOM.getOuterHeight(this.div);
+	if (isNaN(left)) { left=0; }
+	if (isNaN(top)) { top=0; }	
+	var clientW = Screen.getViewportWidth();
+	var clientH = Screen.getViewportHeight();
+	if (clientW!=null && clientH!=null) {
+		top = (clientH-top)/2;
+		left = (clientW-left)/2;
+	}
+	top += Screen.getScrollTop();
+	left += Screen.getScrollLeft();
+	
+	this.div.style.top = top+this.offsetTop+"px";
+	this.div.style.left = left+this.offsetLeft+"px";
+};
+
+    //]]>
+    </script>
+
 </head>
 <body>
 
     <h1>Generation summary:</h1>
     <table class="summary">
-     <tr>
-        <th class="featureName" colspan="2">Statistics</th>
-     </tr>
-     <tr>
+    <tr>
+        <th class="featureName">Statistics</th>
+        <th class="featureName"></th>
+        </tr>
+    <tr>
         <td>Refs in files</td>
-        <td>12</td>
-    </tr>
+        <td>48</td>
+        </tr>
     <tr>
-        <td>Refs with no implementation</td>
-        <td>13</td>
-    </tr>
+        <td>Not generated Refs</td>
+        <td>32</td>
+        </tr>
     <tr>
         <th class="featureName" colspan="2">Details</th>
-     </tr>
+    </tr>
     <tr>
         <td>Report generated</td>
-        <td>30.09.2009 15:42:50</td>
-    </tr>
+        <td>20.04.2010 19:23:59</td>
+        </tr>
     <tr>
         <td>Generation duration</td>
-        <td>0.547</td>
-    </tr>
+        <td>1.172</td>
+        </tr>
     <tr>
         <td>Generation log</td>
-        <td><a href="file:///this_is_ignored/cone.log">cone.log</a></td>
-    </tr>
+        <td><a href="file:///C|/Documents%20and%20Settings/teerytko/workspace/cone.trunk/source/scripts/tests/temp/gen_ll3/cone.log">cone log</a></td>
+        </tr>
     <tr>
         <th class="featureName" colspan="2">Generation options</th>
     </tr>
     <tr>
         <td align="left">Layers</td>
         <td align="left">[-1]</td>
-    </tr>
+        </tr>
     <tr>
         <td align="left">Added</td>
         <td align="left">None</td>
-    </tr>
+        </tr>
     <tr>
         <td align="left">Dryrun</td>
         <td align="left">False</td>
-    </tr>
+        </tr>
     <tr>
         <td align="left">Verbose</td>
         <td align="left">3</td>
-    </tr>
+        </tr>
     <tr>
         <td align="left">Overrides</td>
         <td align="left">None</td>
-    </tr>
+        </tr>
     <tr>
         <td align="left">Project</td>
-        <td align="left">this_is_ignored\generation_test_project</td>
-    </tr>
+        <td align="left">C:\Documents and Settings\teerytko\workspace\cone.trunk\source\scripts\tests\generation_test_project</td>
+        </tr>
         <tr>
         <td align="left">Report</td>
         <td align="left">report.html</td>
-    </tr>
+        </tr>
     <tr>
         <td align="left">Impls</td>
         <td align="left">None</td>
-    </tr>
+        </tr>
+    <tr>
+        <td align="left">Tags</td>
+        <td align="left">{}</td>
+        </tr>
     <tr>
         <td align="left">Output</td>
         <td align="left">output</td>
-    </tr>
+        </tr>
     <tr>
         <td align="left">Configuration</td>
         <td align="left">root.confml</td>
-    </tr>
-    <tr>
-        <td align="left">Working directory</td>
-        <td align="left">this_is_ignored\source\scripts\tests\temp\gen_ll3</td>
-    </tr>
-    </table>
-    
-    <h1>Rule execution results:</h1><br>
-    
-    <table class="report">
-        <tr>
-            <th class="featureName">File</th>
-            <th class="featureName">Rule No.</th>
-            <th class="featureName">Input refs</th>
-            <th class="featureName">Affected refs</th>
         </tr>
-        
-        
-        <tr>
-            <a name="rule:custom/implml/missing_file_in_report_test.implml:1"/>
-            <td><a href="file:///this_is_ignored/custom/implml/missing_file_in_report_test.implml">custom/implml/missing_file_in_report_test.implml</a></td>
-            <td>1</td>
-            <td>
-            </td>
-            <td>TempFeatureMissingFile.Test1<br/>
-            
-            </td>
-        </tr>
-        
-        <tr>
-            <a name="rule:custom/implml/missing_file_in_report_test.implml:2"/>
-            <td><a href="file:///this_is_ignored/custom/implml/missing_file_in_report_test.implml">custom/implml/missing_file_in_report_test.implml</a></td>
-            <td>2</td>
-            <td>
-            </td>
-            <td>TempFeatureMissingFile.Test2<br/>
-            
-            </td>
-        </tr>
-        
-        <tr>
-            <a name="rule:custom/implml/seq_tempvar.implml:1"/>
-            <td><a href="file:///this_is_ignored/custom/implml/seq_tempvar.implml">custom/implml/seq_tempvar.implml</a></td>
-            <td>1</td>
-            <td>
-            </td>
-            <td>TempFeature2.FilesToCopy<br/>
-            
-            </td>
-        </tr>
-        
-        <tr>
-            <a name="rule:custom/implml/simple_tempvars.implml:1"/>
-            <td><a href="file:///this_is_ignored/custom/implml/simple_tempvars.implml">custom/implml/simple_tempvars.implml</a></td>
-            <td>1</td>
-            <td>
-            </td>
-            <td>TempFeature.String<br/>
-            
-            </td>
-        </tr>
-        
-        <tr>
-            <a name="rule:custom/implml/simple_tempvars.implml:2"/>
-            <td><a href="file:///this_is_ignored/custom/implml/simple_tempvars.implml">custom/implml/simple_tempvars.implml</a></td>
-            <td>2</td>
-            <td>
-            </td>
-            <td>TempFeature.Int<br/>
-            
-            </td>
-        </tr>
-        
-        <tr>
-            <a name="rule:custom/implml/simple_tempvars.implml:3"/>
-            <td><a href="file:///this_is_ignored/custom/implml/simple_tempvars.implml">custom/implml/simple_tempvars.implml</a></td>
-            <td>3</td>
-            <td>
-            </td>
-            <td>TempFeature.Real<br/>
-            
-            </td>
-        </tr>
-        
-        
     </table>
     
-    
-    <h1>Output files:</h1><br>
-    
-    <table class="report">
+    <h1>Generation Outputs:</h1><br>
+    <p>Predefined filters:<br>
+        <FORM>
+        <INPUT type="button" value="Refs with no implementation" onclick="tf_outputs.SetFilterValue(1,'None');tf_outputs.SetFilterValue(0, '');tf_outputs.SetFilterValue(2, '');tf_outputs.Filter();return false;" name="Refs with no implementation"">
+        <br>
+        <INPUT type="button" value="Refs with not output" onclick="tf_outputs.SetFilterValue(2, 'None');tf_outputs.SetFilterValue(0, '');tf_outputs.SetFilterValue(1, '');tf_outputs.Filter();return false;" name="Refs with not output">
+        </FORM>
+    </p>
+    <table class="report" id="outputs">
     <tr>
-        <th class="featureName">API</th>
-        <th class="featureName">Data</th>
+        <th class="featureName">Settings</th>
         <th class="featureName">Impl. file</th>
-        <th class="featureName">Impl. type</th>
-        <th class="featureName">Generated for</th>
-        <th class="featureName">Output files</th>
+        <th class="featureName">Outputs</th>
     </tr>
-    
+
     
-        <tr>
-            <td align="left" rowspan=1>
-                <b>MultiSelectionTest.MultiSelectionSetting</b><br>
-                <b>Name: </b>Multi-selection setting<br>
-                <b>Type: </b>multiSelection<br>
-                <b>ConfML: </b><a href="file:///this_is_ignored/base/confml/multiselection.confml">base\confml\multiselection.confml</a>
-            </td>
-            <td align="left" rowspan=1>
-            <table class="report">
-            
-            
-                
-                    <tr>
-                        <th class="th.header">Layer</th>
-                        <th class="th.header">Value</th>
-                    </tr>
-                    <tr>
-                        <td><a href="file:///this_is_ignored/base/confml/multiselection.confml">base\confml\multiselection.confml</a></td>
-                        <td>&#34;opt 1&#34; &#34;opt 3&#34;</td>
-                    </tr>
-                
-            
-                
-                    <tr>
-                        <td><a href="file:///this_is_ignored/data/confml/data.confml">data\confml\data.confml</a></td>
-                        <td>&#34;opt 2&#34; &#34;opt 4&#34; &#34;opt 5&#34;</td>
-                    </tr>
-                
-            
-            </table>
-
-            <table class="report">
-                
-            </table>
-            
-            
-                
-                    <td align="left">
-                        <a href="file:///this_is_ignored/base/implml/multiselection.templateml">base\implml\multiselection.templateml</a>
-                    </td>
-                    <td align="left">
-                        templateml
-                    </td>
-                    <td align="left">
-                        
-                    </td>
-                    <td align="left">
-                        
-                                <a href="file:///this_is_ignored/multiselection.txt">output\multiselection.txt</a><br>
-                            
-                    </td>
-                
-                
-            
-        </tr>
-    
+
     
-        <tr>
-            <td align="left" rowspan=1>
-                <b>NameIdMappingTestTargetSettings.Int</b><br>
-                <b>Name: </b>Int setting<br>
-                <b>Type: </b>int<br>
-                <b>ConfML: </b><a href="file:///this_is_ignored/base/confml/name_id_mapping_test.confml">base\confml\name_id_mapping_test.confml</a>
-            </td>
-            <td align="left" rowspan=1>
-            <table class="report">
-            
-            
-                
-                    <tr>
-                        <th class="th.header">Layer</th>
-                        <th class="th.header">Value</th>
-                    </tr>
-                    <tr>
-                        <td><a href="file:///this_is_ignored/base/confml/name_id_mapping_test.confml">base\confml\name_id_mapping_test.confml</a></td>
-                        <td>0</td>
-                    </tr>
-                
-            
-                
-                    <tr>
-                        <td><a href="file:///this_is_ignored/data/confml/data.confml">data\confml\data.confml</a></td>
-                        <td>140</td>
-                    </tr>
-                
-            
-            </table>
-
-            <table class="report">
-                
-            </table>
-            
-            
-                
-                    <td align="left">
-                        <a href="file:///this_is_ignored/base/implml/name_id_mapping_test.templateml">base\implml\name_id_mapping_test.templateml</a>
-                    </td>
-                    <td align="left">
-                        templateml
-                    </td>
-                    <td align="left">
-                        
-                    </td>
-                    <td align="left">
-                        
-                                <a href="file:///this_is_ignored/name_id_mapping_test.txt">output\name_id_mapping_test.txt</a><br>
-                            
-                    </td>
-                
-                
-            
-        </tr>
-    
+
+    <!-- process the output files -->    
     
-        <tr>
-            <td align="left" rowspan=1>
-                <b>NameIdMappingTestTargetSettings.Real</b><br>
-                <b>Name: </b>Real setting<br>
-                <b>Type: </b>real<br>
-                <b>ConfML: </b><a href="file:///this_is_ignored/base/confml/name_id_mapping_test.confml">base\confml\name_id_mapping_test.confml</a>
-            </td>
-            <td align="left" rowspan=1>
-            <table class="report">
-            
-            
-                
-                    <tr>
-                        <th class="th.header">Layer</th>
-                        <th class="th.header">Value</th>
-                    </tr>
-                    <tr>
-                        <td><a href="file:///this_is_ignored/base/confml/name_id_mapping_test.confml">base\confml\name_id_mapping_test.confml</a></td>
-                        <td>0</td>
-                    </tr>
-                
-            
-                
-                    <tr>
-                        <td><a href="file:///this_is_ignored/data/confml/data.confml">data\confml\data.confml</a></td>
-                        <td>1.4</td>
-                    </tr>
-                
-            
-            </table>
-
-            <table class="report">
-                
-            </table>
-            
-            
-                
-                    <td align="left">
-                        <a href="file:///this_is_ignored/base/implml/name_id_mapping_test.templateml">base\implml\name_id_mapping_test.templateml</a>
-                    </td>
-                    <td align="left">
-                        templateml
-                    </td>
-                    <td align="left">
-                        
-                    </td>
-                    <td align="left">
-                        
-                                <a href="file:///this_is_ignored/name_id_mapping_test.txt">output\name_id_mapping_test.txt</a><br>
-                            
-                    </td>
-                
-                
-            
-        </tr>
-    
-    
-        <tr>
-            <td align="left" rowspan=1>
-                <b>NameIdMappingTestTargetSettings.Selection</b><br>
-                <b>Name: </b>Selection setting<br>
-                <b>Type: </b>selection<br>
-                <b>ConfML: </b><a href="file:///this_is_ignored/base/confml/name_id_mapping_test.confml">base\confml\name_id_mapping_test.confml</a>
-            </td>
-            <td align="left" rowspan=1>
-            <table class="report">
-            
-            
-                
-                    <tr>
-                        <th class="th.header">Layer</th>
-                        <th class="th.header">Value</th>
-                    </tr>
-                    <tr>
-                        <td><a href="file:///this_is_ignored/base/confml/name_id_mapping_test.confml">base\confml\name_id_mapping_test.confml</a></td>
-                        <td>None</td>
-                    </tr>
-                
-            
-                
-                    <tr>
-                        <td><a href="file:///this_is_ignored/data/confml/data.confml">data\confml\data.confml</a></td>
-                        <td>Entry 4 (new)</td>
-                    </tr>
-                
-            
-            </table>
-
-            <table class="report">
-                
-            </table>
-            
-            
-                
-                    <td align="left">
-                        <a href="file:///this_is_ignored/base/implml/name_id_mapping_test.templateml">base\implml\name_id_mapping_test.templateml</a>
-                    </td>
-                    <td align="left">
-                        templateml
-                    </td>
-                    <td align="left">
-                        
-                    </td>
-                    <td align="left">
-                        
-                                <a href="file:///this_is_ignored/name_id_mapping_test.txt">output\name_id_mapping_test.txt</a><br>
-                            
-                    </td>
-                
-                
-            
-        </tr>
-    
-    
-        <tr>
-            <td align="left" rowspan=1>
-                <b>NameIdMappingTestTargetSettings.Sequence</b><br>
-                <b>Name: </b>Sequence<br>
-                <b>Type: </b>sequence<br>
-                <b>ConfML: </b><a href="file:///this_is_ignored/base/confml/name_id_mapping_test.confml">base\confml\name_id_mapping_test.confml</a>
-            </td>
-            <td align="left" rowspan=1>
-            <table class="report">
-            
-            
-            </table>
-
-            <table class="report">
-                
-                    
-                        <tr>
-                            <th class="th.header">Setting</th>
-                            <th class="th.header">Value</th>
-                        </tr>
-                        <tr>
-                            <td><b>Selection sub-setting</b></td>
-                            <td>
-                                
-                                    Entry 2<br>
-                                
-                                    Entry 4 (new)<br>
-                                
-                                    Entry 5 (new)<br>
-                                
-                            </td>
-                        </tr>
-                    
-                
-                    
-                        <tr>
-                            <td><b>Int sub-setting</b></td>
-                            <td>
-                                
-                                    120<br>
-                                
-                                    140<br>
-                                
-                                    150<br>
-                                
-                            </td>
-                        </tr>
-                    
-                
-                    
-                        <tr>
-                            <td><b>Real sub-setting</b></td>
-                            <td>
-                                
-                                    1.2<br>
-                                
-                                    1.4<br>
-                                
-                                    1.5<br>
-                                
-                            </td>
-                        </tr>
-                    
-                
-            </table>
-            
-            
-                
-                    <td align="left">
-                        <a href="file:///this_is_ignored/base/implml/name_id_mapping_test.templateml">base\implml\name_id_mapping_test.templateml</a>
-                    </td>
-                    <td align="left">
-                        templateml
-                    </td>
-                    <td align="left">
-                        
-                    </td>
-                    <td align="left">
-                        
-                                <a href="file:///this_is_ignored/name_id_mapping_test.txt">output\name_id_mapping_test.txt</a><br>
-                            
-                    </td>
-                
-                
-            
-        </tr>
-    
-    
-        <tr>
-            <td align="left" rowspan=1>
-                <b><i>TempFeature.Boolean</i></b><br>
-                <b>Name: </b>Boolean<br>
-                <b>Type: </b>boolean<br>
-                <b>ConfML: </b><a href="file:///this_is_ignored/autodata.confml">autodata.confml</a>
-            </td>
-            <td align="left" rowspan=1>
-            <table class="report">
-            
-            
-                
-                    <tr>
-                        <th class="th.header">Layer</th>
-                        <th class="th.header">Value</th>
-                    </tr>
-                    <tr>
-                        <td><a href="file:///this_is_ignored/autodata.confml">autodata.confml</a></td>
-                        <td>true</td>
-                    </tr>
-                
+    <tr>
+        <td>
+        </td>
+        <td>
+            Rule:
+          
+           custom/implml/seq_tempvar.implml:15
+        
+        </td>
+        <td>
+        
+           TempFeature2.FilesToCopy
+        
+        </td>
+    </tr>
+    <tr>
+        <td>
+        </td>
+        <td>
+            Rule:
+          
+           custom/implml/simple_tempvars.implml:12
+        
+        </td>
+        <td>
+        
+           TempFeature.String
+        
+        </td>
+    </tr>
+    <tr>
+        <td>
+        </td>
+        <td>
+            Rule:
+          
+           custom/implml/simple_tempvars.implml:13
+        
+        </td>
+        <td>
+        
+           TempFeature.Int
+        
+        </td>
+    </tr>
+    <tr>
+        <td>
+        </td>
+        <td>
+            Rule:
+          
+           custom/implml/simple_tempvars.implml:14
+        
+        </td>
+        <td>
+        
+           TempFeature.Real
+        
+        </td>
+    </tr>
+    <tr>
+        <td>
+                       <B>
+           MultiSelectionTest.MultiSelectionSetting
+        </B><br>
+        </td>
+        <td>
+          
+           base/implml/multiselection.templateml:2
+        
+        </td>
+        <td>
+        
+           output/multiselection.txt
+        
+        </td>
+    </tr>
+    <tr>
+        <td>
+                       <B>
+           NameIdMappingTestTargetSettings.Selection
+        </B><br>
+                       <B>
+           NameIdMappingTestTargetSettings.Int
+        </B><br>
+                       <B>
+           NameIdMappingTestTargetSettings.Real
+        </B><br>
+                       <B>
+           NameIdMappingTestTargetSettings.Sequence.Selection
+        </B><br>
+                       <B>
+           NameIdMappingTestTargetSettings.Sequence.Int
+        </B><br>
+                       <B>
+           NameIdMappingTestTargetSettings.Sequence.Real
+        </B><br>
+        </td>
+        <td>
+          
+           base/implml/name_id_mapping_test.templateml:2
+        
+        </td>
+        <td>
+        
+           output/name_id_mapping_test.txt
+        
+        </td>
+    </tr>
+    <tr>
+        <td>
+                       <i>
+           TempFeature.String
+        </i><br>
+        </td>
+        <td>
+          
+           custom/implml/conditional_container.implml:12
+        
+        </td>
+        <td>
+        
+           output/content/template_string_condition_true.txt
+        
+        </td>
+    </tr>
+    <tr>
+        <td>
+        </td>
+        <td>
+          
+           custom/implml/conditional_container.implml:34
+        
+        </td>
+        <td>
+        
+           output/sis/app1.txt
+        
+        </td>
+    </tr>
+    <tr>
+        <td>
+                       <B>
+           BasicSettingTypesTest.IntSetting
+        </B><br>
+        </td>
+        <td>
+          
+           custom/implml/impl_override_test.templateml:2
+        
+        </td>
+        <td>
+        
+           output/impl_override_test.txt
+        
+        </td>
+    </tr>
+    <tr>
+        <td>
+        </td>
+        <td>
+          
+           custom/implml/invocation_phase_test.implml:6
+        
+        </td>
+        <td>
+        
+           output/content/invocation_phase_test_common_ns.txt
+        
+        </td>
+    </tr>
+    <tr>
+        <td>
+        </td>
+        <td>
+          
+           custom/implml/invocation_phase_test.implml:25
+        
+        </td>
+        <td>
+        
+           output/content/invocation_phase_test_contentml_ns.txt
+        
+        </td>
+    </tr>
+    <tr>
+        <td>
+                       <i>
+           TempFeatureMissingFile.Test1
+        </i><br>
+                       <i>
+           TempFeatureMissingFile.Test2
+        </i><br>
+        </td>
+        <td>
+          
+           custom/implml/missing_file_in_report_test.implml:11
+        
+        </td>
+        <td>
+        
+           output/content/missing_output_file_test1.txt
+        
+        </td>
+    </tr>
+    <tr>
+        <td>
+                       <i>
+           TempFeatureMissingFile.Test1
+        </i><br>
+                       <i>
+           TempFeatureMissingFile.Test2
+        </i><br>
+        </td>
+        <td>
+          
+           custom/implml/missing_file_in_report_test.implml:11
+        
+        </td>
+        <td>
+        
+           output/content/missing_output_file_test2.txt
+        
+        </td>
+    </tr>
+    <tr>
+        <td>
+        </td>
+        <td>
+          
+           custom/implml/output_override_test.implml:6
+        
+        </td>
+        <td>
+        
+           output/test_subdir/output_subdir_test.txt
+        
+        </td>
+    </tr>
+    <tr>
+        <td>
+        </td>
+        <td>
+          
+           custom/implml/output_override_test.implml:16
+        
+        </td>
+        <td>
+        
+           output/overridden_output/output_rootdir_test.txt
+        
+        </td>
+    </tr>
+    <tr>
+        <td>
+        </td>
+        <td>
+          
+           custom/implml/output_override_test.implml:27
+        
+        </td>
+        <td>
+        
+           output/overridden_output/test_subdir/output_rootdir_test.txt
+        
+        </td>
+    </tr>
+    <tr>
+        <td>
+                       <B>
+           TempFeature2.FilesToCopy.FilePath
+        </B><br>
+        </td>
+        <td>
+          
+           custom/implml/seq_tempvar.implml:21
+        
+        </td>
+        <td>
+        
+           output/content/temp_seq_test/invocation_phase_test_1.txt
+        
+        </td>
+    </tr>
+    <tr>
+        <td>
+                       <B>
+           TempFeature2.FilesToCopy.FilePath
+        </B><br>
+        </td>
+        <td>
+          
+           custom/implml/seq_tempvar.implml:21
+        
+        </td>
+        <td>
+        
+           output/content/temp_seq_test/invocation_phase_test_2.txt
+        
+        </td>
+    </tr>
+    <tr>
+        <td>
+                       <i>
+           TempFeature.String
+        </i><br>
+                       <i>
+           TempFeature.Int
+        </i><br>
+                       <i>
+           TempFeature.Real
+        </i><br>
+                       <i>
+           TempFeature.Boolean
+        </i><br>
+        </td>
+        <td>
+          
+           custom/implml/simple_tempvars.implml:18
+        
+        </td>
+        <td>
+        
+           output/content/simple_tempvars_test.txt
+        
+        </td>
+    </tr>
+    <tr>
+        <td>
+        </td>
+        <td>
+          
+           custom/implml/invocation_phase_test.implml:15
+        
+        </td>
+        <td>
+        
+           output/content/invocation_phase_test_common_ns.txt
+        
+        </td>
+    </tr>
+    <tr>
+        <td>
+        </td>
+        <td>
+          
+           custom/implml/invocation_phase_test.implml:31
+        
+        </td>
+        <td>
+        
+           output/content/invocation_phase_test_contentml_ns.txt
+        
+        </td>
+    </tr>
+    <tr>
+        <td>
+        </td>
+        <td>
+            Rule:
+          
+           custom/implml/missing_file_in_report_test.implml:28
+        
+        </td>
+        <td>
+        
+           TempFeatureMissingFile.Test1
+        
+        </td>
+    </tr>
+    <tr>
+        <td>
+        </td>
+        <td>
+            Rule:
+          
+           custom/implml/missing_file_in_report_test.implml:29
+        
+        </td>
+        <td>
+        
+           TempFeatureMissingFile.Test2
+        
+        </td>
+    </tr>
             
-            </table>
-
-            <table class="report">
-                
-            </table>
-            
-            
-                
-                    <td align="left">
-                        <a href="file:///this_is_ignored/custom/implml/simple_tempvars.implml">custom\implml\simple_tempvars.implml</a>
-                    </td>
-                    <td align="left">
-                        templateml
-                    </td>
-                    <td align="left">
-                        
-                    </td>
-                    <td align="left">
-                        
-                                <a href="file:///this_is_ignored/content/simple_tempvars_test.txt">output\content\simple_tempvars_test.txt</a><br>
-                            
-                    </td>
-                
-                
-            
-        </tr>
-    
-    
-        <tr>
-            <td align="left" rowspan=1>
-                <b><i>TempFeature.Int</i></b><br>
-                <b>Name: </b>Int<br>
-                <b>Type: </b>int<br>
-                <b>ConfML: </b><a href="file:///this_is_ignored/autodata.confml">autodata.confml</a>
-            </td>
-            <td align="left" rowspan=1>
-            <table class="report">
-            
-            
-                
-                    <tr>
-                        <th class="th.header">Layer</th>
-                        <th class="th.header">Value</th>
-                    </tr>
-                    <tr>
-                        <td><a href="file:///this_is_ignored/autodata.confml">autodata.confml</a></td>
-                        <td>501</td>
-                    </tr>
-                
-            
-            </table>
-
-            <table class="report">
-                
-            </table>
-            
-            
-                
-                    <td align="left">
-                        <a href="file:///this_is_ignored/custom/implml/simple_tempvars.implml">custom\implml\simple_tempvars.implml</a>
-                    </td>
-                    <td align="left">
-                        templateml
-                    </td>
-                    <td align="left">
-                        
-                    </td>
-                    <td align="left">
-                        
-                                <a href="file:///this_is_ignored/content/simple_tempvars_test.txt">output\content\simple_tempvars_test.txt</a><br>
-                            
-                    </td>
-                
-                
-            
-        </tr>
-    
-    
-        <tr>
-            <td align="left" rowspan=1>
-                <b><i>TempFeature.Real</i></b><br>
-                <b>Name: </b>Real<br>
-                <b>Type: </b>real<br>
-                <b>ConfML: </b><a href="file:///this_is_ignored/autodata.confml">autodata.confml</a>
-            </td>
-            <td align="left" rowspan=1>
-            <table class="report">
-            
-            
-                
-                    <tr>
-                        <th class="th.header">Layer</th>
-                        <th class="th.header">Value</th>
-                    </tr>
-                    <tr>
-                        <td><a href="file:///this_is_ignored/autodata.confml">autodata.confml</a></td>
-                        <td>1.75</td>
-                    </tr>
-                
-            
-            </table>
-
-            <table class="report">
-                
-            </table>
-            
-            
-                
-                    <td align="left">
-                        <a href="file:///this_is_ignored/custom/implml/simple_tempvars.implml">custom\implml\simple_tempvars.implml</a>
-                    </td>
-                    <td align="left">
-                        templateml
-                    </td>
-                    <td align="left">
-                        
-                    </td>
-                    <td align="left">
-                        
-                                <a href="file:///this_is_ignored/content/simple_tempvars_test.txt">output\content\simple_tempvars_test.txt</a><br>
-                            
-                    </td>
-                
-                
-            
-        </tr>
-    
-    
-        <tr>
-            <td align="left" rowspan=3>
-                <b><i>TempFeature.String</i></b><br>
-                <b>Name: </b>String<br>
-                <b>Type: </b>string<br>
-                <b>ConfML: </b><a href="file:///this_is_ignored/autodata.confml">autodata.confml</a>
-            </td>
-            <td align="left" rowspan=3>
-            <table class="report">
-            
-            
-                
-                    <tr>
-                        <th class="th.header">Layer</th>
-                        <th class="th.header">Value</th>
-                    </tr>
-                    <tr>
-                        <td><a href="file:///this_is_ignored/autodata.confml">autodata.confml</a></td>
-                        <td>testing and more testing</td>
-                    </tr>
-                
-            
-            </table>
-
-            <table class="report">
-                
-            </table>
-            
-            
-                
-                    <td align="left">
-                        <a href="file:///this_is_ignored/custom/implml/\conditional_container.implml">custom\implml\conditional_container.implml</a>
-                    </td>
-                    <td align="left">
-                        templateml
-                    </td>
-                    <td align="left">
-                        
-                    </td>
-                    <td align="left">
-                        
-                                <a href="ignored">output\content\template_string_condition_true.txt</a><br>
-                            
-                    </td>
-                
-                
-            
-                
-                    <tr>
-                    <td align="left">
-                        <a href="file:///this_is_ignored/custom/implml/conditional_container.implml">custom\implml\conditional_container.implml</a>
-                    </td>
-                    <td align="left">
-                        templateml
-                    </td>
-                    <td align="left">
-                        
-                    </td>
-                    <td align="left">
-                        
-                            
-                                <span class="red">output\content\template_string_condition_false.txt</span><br>
-                            
-                        
-                    </td>
-                    </tr>
-                
-                
-            
-                
-                    <tr>
-                    <td align="left">
-                        <a href="file:///this_is_ignored/custom/implml/simple_tempvars.implml">custom\implml\simple_tempvars.implml</a>
-                    </td>
-                    <td align="left">
-                        templateml
-                    </td>
-                    <td align="left">
-                        
-                    </td>
-                    <td align="left">
-                        
-                            
-                                <a href="file:///C|/Users/NoBackup/wc/cone-trunk-temp/source/scripts/tests/temp/gen_ll3/output/content/simple_tempvars_test.txt">output\content\simple_tempvars_test.txt</a><br>
-                            
-                        
-                    </td>
-                    </tr>
-                
-                
-            
-        </tr>
-    
-    
-        <tr>
-            <td align="left" rowspan=1>
-                <b><i>TempFeature2.FilesToCopy</i></b><br>
-                <b>Name: </b>FilesToCopy<br>
-                <b>Type: </b>sequence<br>
-                <b>ConfML: </b><a href="file:///C|/Users/NoBackup/wc/cone-trunk/source/scripts/tests/generation_test_project/autodata.confml">autodata.confml</a>
-            </td>
-            <td align="left" rowspan=1>
-            <table class="report">
-            
-            
-            </table>
-
-            <table class="report">
-                
-                    
-                        <tr>
-                            <th class="th.header">Setting</th>
-                            <th class="th.header">Value</th>
-                        </tr>
-                        <tr>
-                            <td><b>FilePath</b></td>
-                            <td>
-                                
-                                    invocation_phase_test_1.txt<br>
-                                
-                                    invocation_phase_test_2.txt<br>
-                                
-                                    overlay/overlay_folder/overlay.txt<br>
-                                
-                            </td>
-                        </tr>
-                    
-                
-            </table>
-            
-            
-                
-                    <td align="left">
-                        <a href="file:///C|/Users/NoBackup/wc/cone-trunk/source/scripts/tests/generation_test_project/custom/implml/seq_tempvar.implml">custom\implml\seq_tempvar.implml</a>
-                    </td>
-                    <td align="left">
-                        content
-                    </td>
-                    <td align="left">
-                        
-                    </td>
-                    <td align="left">
-                        
-                                <a href="file:///this_is_ignored">output\content\temp_seq_test\invocation_phase_test_2.txt</a><br>
-                            
-                                <a href="file:///this_is_ignored">output\content\temp_seq_test\invocation_phase_test_1.txt</a><br>
-                            
-                    </td>
-                
-                
-            
-        </tr>
-    
-    
-        <tr>
-            <td align="left" rowspan=1>
-                <b><i>TempFeatureMissingFile.Test1</i></b><br>
-                <b>Name: </b>Test1<br>
-                <b>Type: </b>string<br>
-                <b>ConfML: </b><a href="file:///this_is_ignored">autodata.confml</a>
-            </td>
-            <td align="left" rowspan=1>
-            <table class="report">
-            
-            
-                
-                    <tr>
-                        <th class="th.header">Layer</th>
-                        <th class="th.header">Value</th>
-                    </tr>
-                    <tr>
-                        <td><a href="file:///this_is_ignored">autodata.confml</a></td>
-                        <td>None</td>
-                    </tr>
-                
-            
-            </table>
-
-            <table class="report">
-                
-            </table>
-            
-            
-                
-                    <td align="left">
-                        <a href="file:///this_is_ignored">custom\implml\missing_file_in_report_test.implml</a>
-                    </td>
-                    <td align="left">
-                        templateml
-                    </td>
-                    <td align="left">
-                        
-                    </td>
-                    <td align="left">
-                        
-                                <span class="red">output\content\missing_output_file_test1.txt</span><br>
-                            
-                                <span class="red">output\content\missing_output_file_test2.txt</span><br>
-                            
-                    </td>
-                
-                
-            
-        </tr>
-    
-    
-        <tr>
-            <td align="left" rowspan=1>
-                <b><i>TempFeatureMissingFile.Test2</i></b><br>
-                <b>Name: </b>Test2<br>
-                <b>Type: </b>string<br>
-                <b>ConfML: </b><a href="file:///this_is_ignored">autodata.confml</a>
-            </td>
-            <td align="left" rowspan=1>
-            <table class="report">
-            
-            
-                
-                    <tr>
-                        <th class="th.header">Layer</th>
-                        <th class="th.header">Value</th>
-                    </tr>
-                    <tr>
-                        <td><a href="file:///this_is_ignored">autodata.confml</a></td>
-                        <td>None</td>
-                    </tr>
-                
+    <!-- process the refs with no output -->
+    <tr>
+        <td>
+          <B>
             
-            </table>
-
-            <table class="report">
-                
-            </table>
-            
+           BasicSettingTypesTest.StringSetting
+        
+          </B><br>
+        </td>
+        <td>
+            <span class="red">None</span><br>
+        </td>
+        <td>
+            <span class="red">None</span><br> 
+        </td>
+    </tr>
+    <tr>
+        <td>
+          <B>
             
-                
-                    <td align="left">
-                        <a href="file:///this_is_ignored">custom\implml\missing_file_in_report_test.implml</a>
-                    </td>
-                    <td align="left">
-                        templateml
-                    </td>
-                    <td align="left">
-                        
-                    </td>
-                    <td align="left">
-                        
-                                <span class="red">output\content\missing_output_file_test1.txt</span><br>
-                            
-                                <span class="red">output\content\missing_output_file_test2.txt</span><br>
-                            
-                    </td>
-                
-                
-            
-        </tr>
+           Feature1.SequenceSetting
         
-    </table>
-
-    <h1>Refs with no implementation:</h1><br>
-    
-    <table class="report">
-    <tr>
-        <th class="featureName">API</th>
-        <th class="featureName">Data</th>
+          </B><br>
+        </td>
+        <td>
+            <span class="red">None</span><br>
+        </td>
+        <td>
+            <span class="red">None</span><br> 
+        </td>
     </tr>
-    
-        <tr>
-            <td align="left" >
-                <b>BasicSettingTypesTest.IntSetting</b><br>
-                <b>Name: </b>Int setting<br>
-                <b>Type: </b>int<br>
-                <b>ConfML: </b><a href="file:///this_is_ignored/base/confml/basic_setting_types_test.confml">base\confml\basic_setting_types_test.confml</a>
-            </td>
-            <td align="left">
-            <table class="report">
+    <tr>
+        <td>
+          <B>
             
-            
-                
-                    <tr>
-                        <th class="th.header">Layer</th>
-                        <th class="th.header">Value</th>
-                    </tr>
-                    <tr>
-                        <td><a href="file:///this_is_ignored/base/confml/basic_setting_types_test.confml">base\confml\basic_setting_types_test.confml</a></td>
-                        <td>10</td>
-                    </tr>
-                
+           Feature1.SequenceSetting.BooleanSubSetting
+        
+          </B><br>
+        </td>
+        <td>
+            <span class="red">None</span><br>
+        </td>
+        <td>
+            <span class="red">None</span><br> 
+        </td>
+    </tr>
+    <tr>
+        <td>
+          <B>
             
-                
-                    <tr>
-                        <td><a href="file:///this_is_ignored/data/confml/data.confml">data\confml\data.confml</a></td>
-                        <td>555</td>
-                    </tr>
-                
-            
-            </table>
-            
-            <table class="report">
-                
-            </table>
-        </tr>
-    
-        <tr>
-            <td align="left" >
-                <b>BasicSettingTypesTest.StringSetting</b><br>
-                <b>Name: </b>String setting<br>
-                <b>Type: </b>string<br>
-                <b>ConfML: </b><a href="file:///this_is_ignored/base/confml/basic_setting_types_test.confml">base\confml\basic_setting_types_test.confml</a>
-            </td>
-            <td align="left">
-            <table class="report">
-            
-            
-                
-                    <tr>
-                        <th class="th.header">Layer</th>
-                        <th class="th.header">Value</th>
-                    </tr>
-                    <tr>
-                        <td><a href="file:///this_is_ignored/base/confml/basic_setting_types_test.confml">base\confml\basic_setting_types_test.confml</a></td>
-                        <td>default string</td>
-                    </tr>
-                
+           Feature1.SequenceSetting.IntSubSetting
+        
+          </B><br>
+        </td>
+        <td>
+            <span class="red">None</span><br>
+        </td>
+        <td>
+            <span class="red">None</span><br> 
+        </td>
+    </tr>
+    <tr>
+        <td>
+          <B>
             
-                
-                    <tr>
-                        <td><a href="file:///this_is_ignored/data/confml/data.confml">data\confml\data.confml</a></td>
-                        <td>&#12459;&#12479;&#12459;&#12490; &lt;&amp;&gt;</td>
-                    </tr>
-                
-            
-            </table>
+           Feature1.SequenceSetting.RealSubSetting
+        
+          </B><br>
+        </td>
+        <td>
+            <span class="red">None</span><br>
+        </td>
+        <td>
+            <span class="red">None</span><br> 
+        </td>
+    </tr>
+    <tr>
+        <td>
+          <B>
             
-            <table class="report">
-                
-            </table>
-        </tr>
-    
-        <tr>
-            <td align="left" >
-                <b><i>Condition.Boolean</i></b><br>
-                <b>Name: </b>Boolean<br>
-                <b>Type: </b>boolean<br>
-                <b>ConfML: </b><a href="file:///C|/Users/NoBackup/wc/cone-trunk-temp/source/scripts/tests/generation_test_project/autodata.confml">autodata.confml</a>
-            </td>
-            <td align="left">
-            <table class="report">
-            
-            
-                
-                    <tr>
-                        <th class="th.header">Layer</th>
-                        <th class="th.header">Value</th>
-                    </tr>
-                    <tr>
-                        <td><a href="file:///C|/Users/NoBackup/wc/cone-trunk-temp/source/scripts/tests/generation_test_project/autodata.confml">autodata.confml</a></td>
-                        <td>true</td>
-                    </tr>
-                
+           Feature1.SequenceSetting.SelectionSubSetting
+        
+          </B><br>
+        </td>
+        <td>
+            <span class="red">None</span><br>
+        </td>
+        <td>
+            <span class="red">None</span><br> 
+        </td>
+    </tr>
+    <tr>
+        <td>
+          <B>
             
-            </table>
-            
-            <table class="report">
-                
-            </table>
-        </tr>
-    
-        <tr>
-            <td align="left" >
-                <b><i>Condition.Int</i></b><br>
-                <b>Name: </b>Int<br>
-                <b>Type: </b>int<br>
-                <b>ConfML: </b><a href="file:///C|/Users/NoBackup/wc/cone-trunk-temp/source/scripts/tests/generation_test_project/autodata.confml">autodata.confml</a>
-            </td>
-            <td align="left">
-            <table class="report">
-            
-            
-                
-                    <tr>
-                        <th class="th.header">Layer</th>
-                        <th class="th.header">Value</th>
-                    </tr>
-                    <tr>
-                        <td><a href="file:///C|/Users/NoBackup/wc/cone-trunk-temp/source/scripts/tests/generation_test_project/autodata.confml">autodata.confml</a></td>
-                        <td>500</td>
-                    </tr>
-                
+           Feature1.SequenceSetting.StringSubSetting
+        
+          </B><br>
+        </td>
+        <td>
+            <span class="red">None</span><br>
+        </td>
+        <td>
+            <span class="red">None</span><br> 
+        </td>
+    </tr>
+    <tr>
+        <td>
+          <B>
             
-            </table>
+           NameIdMappingTestSourceSequences.StringSequence
+        
+          </B><br>
+        </td>
+        <td>
+            <span class="red">None</span><br>
+        </td>
+        <td>
+            <span class="red">None</span><br> 
+        </td>
+    </tr>
+    <tr>
+        <td>
+          <B>
             
-            <table class="report">
-                
-            </table>
-        </tr>
-    
-        <tr>
-            <td align="left" >
-                <b><i>Condition.Real</i></b><br>
-                <b>Name: </b>Real<br>
-                <b>Type: </b>real<br>
-                <b>ConfML: </b><a href="file:///C|/Users/NoBackup/wc/cone-trunk-temp/source/scripts/tests/generation_test_project/autodata.confml">autodata.confml</a>
-            </td>
-            <td align="left">
-            <table class="report">
-            
-            
-                
-                    <tr>
-                        <th class="th.header">Layer</th>
-                        <th class="th.header">Value</th>
-                    </tr>
-                    <tr>
-                        <td><a href="file:///C|/Users/NoBackup/wc/cone-trunk-temp/source/scripts/tests/generation_test_project/autodata.confml">autodata.confml</a></td>
-                        <td>1.5</td>
-                    </tr>
-                
-            
-            </table>
+           NameIdMappingTestSourceSequences.StringSequence.Value
+        
+          </B><br>
+        </td>
+        <td>
+            <span class="red">None</span><br>
+        </td>
+        <td>
+            <span class="red">None</span><br> 
+        </td>
+    </tr>
+    <tr>
+        <td>
+          <B>
             
-            <table class="report">
-                
-            </table>
-        </tr>
-    
-        <tr>
-            <td align="left" >
-                <b><i>Condition.String</i></b><br>
-                <b>Name: </b>String<br>
-                <b>Type: </b>string<br>
-                <b>ConfML: </b><a href="file:///C|/Users/NoBackup/wc/cone-trunk-temp/source/scripts/tests/generation_test_project/autodata.confml">autodata.confml</a>
-            </td>
-            <td align="left">
-            <table class="report">
+           NameIdMappingTestSourceSequences.StringToIntSequence
+        
+          </B><br>
+        </td>
+        <td>
+            <span class="red">None</span><br>
+        </td>
+        <td>
+            <span class="red">None</span><br> 
+        </td>
+    </tr>
+    <tr>
+        <td>
+          <B>
             
-            
-                
-                    <tr>
-                        <th class="th.header">Layer</th>
-                        <th class="th.header">Value</th>
-                    </tr>
-                    <tr>
-                        <td><a href="file:///C|/Users/NoBackup/wc/cone-trunk-temp/source/scripts/tests/generation_test_project/autodata.confml">autodata.confml</a></td>
-                        <td>testing</td>
-                    </tr>
-                
-            
-            </table>
+           NameIdMappingTestSourceSequences.StringToIntSequence.Name
+        
+          </B><br>
+        </td>
+        <td>
+            <span class="red">None</span><br>
+        </td>
+        <td>
+            <span class="red">None</span><br> 
+        </td>
+    </tr>
+    <tr>
+        <td>
+          <B>
             
-            <table class="report">
-                
-            </table>
-        </tr>
-    
-        <tr>
-            <td align="left" >
-                <b><i>Condition.Unused</i></b><br>
-                <b>Name: </b>Unused<br>
-                <b>Type: </b>boolean<br>
-                <b>ConfML: </b><a href="file:///C|/Users/NoBackup/wc/cone-trunk-temp/source/scripts/tests/generation_test_project/autodata.confml">autodata.confml</a>
-            </td>
-            <td align="left">
-            <table class="report">
-            
+           NameIdMappingTestSourceSequences.StringToIntSequence.Value
+        
+          </B><br>
+        </td>
+        <td>
+            <span class="red">None</span><br>
+        </td>
+        <td>
+            <span class="red">None</span><br> 
+        </td>
+    </tr>
+    <tr>
+        <td>
+          <B>
             
-                
-                    <tr>
-                        <th class="th.header">Layer</th>
-                        <th class="th.header">Value</th>
-                    </tr>
-                    <tr>
-                        <td><a href="file:///C|/Users/NoBackup/wc/cone-trunk-temp/source/scripts/tests/generation_test_project/autodata.confml">autodata.confml</a></td>
-                        <td>false</td>
-                    </tr>
-                
-            
-            </table>
-            
-            <table class="report">
-                
-            </table>
-        </tr>
-    
-        <tr>
-            <td align="left" >
-                <b>Feature1.SequenceSetting</b><br>
-                <b>Name: </b>Sequence setting<br>
-                <b>Type: </b>sequence<br>
-                <b>ConfML: </b><a href="file:///this_is_ignored/base/confml/feature1.confml">base\confml\feature1.confml</a>
-            </td>
-            <td align="left">
-            <table class="report">
-            
-            
-            </table>
+           NameIdMappingTestSourceSequences.StringToRealSequence
+        
+          </B><br>
+        </td>
+        <td>
+            <span class="red">None</span><br>
+        </td>
+        <td>
+            <span class="red">None</span><br> 
+        </td>
+    </tr>
+    <tr>
+        <td>
+          <B>
             
-            <table class="report">
-                
-                    
-                        <tr>
-                            <th class="th.header">Setting</th>
-                            <th class="th.header">Value</th>
-                        </tr>
-                        <tr>
-                            <td><b>Real sub-setting</b></td>
-                            <td>
-                                
-                                    1.25<br>
-                                
-                                    1.5<br>
-                                
-                                    1.5<br>
-                                
-                            </td>
-                        </tr>
-                    
-                
-                    
-                        <tr>
-                            <td><b>Int sub-setting</b></td>
-                            <td>
-                                
-                                    128<br>
-                                
-                                    256<br>
-                                
-                                    256<br>
-                                
-                            </td>
-                        </tr>
-                    
-                
-                    
-                        <tr>
-                            <td><b>String sub-setting</b></td>
-                            <td>
-                                
-                                    def1<br>
-                                
-                                    def2<br>
-                                
-                                    test<br>
-                                
-                            </td>
-                        </tr>
-                    
-                
-                    
-                        <tr>
-                            <td><b>Boolean sub-setting</b></td>
-                            <td>
-                                
-                                    false<br>
-                                
-                                    false<br>
-                                
-                                    true<br>
-                                
-                            </td>
-                        </tr>
-                    
-                
-                    
-                        <tr>
-                            <td><b>Selection sub-setting</b></td>
-                            <td>
-                                
-                                    1<br>
-                                
-                                    1<br>
-                                
-                                    1<br>
-                                
-                            </td>
-                        </tr>
-                    
-                
-            </table>
-        </tr>
-    
-        <tr>
-            <td align="left" >
-                <b>NameIdMappingTestSourceSequences.StringSequence</b><br>
-                <b>Name: </b>String sequence<br>
-                <b>Type: </b>sequence<br>
-                <b>ConfML: </b><a href="file:///this_is_ignored/base/confml/name_id_mapping_test.confml">base\confml\name_id_mapping_test.confml</a>
-            </td>
-            <td align="left">
-            <table class="report">
+           NameIdMappingTestSourceSequences.StringToRealSequence.Name
+        
+          </B><br>
+        </td>
+        <td>
+            <span class="red">None</span><br>
+        </td>
+        <td>
+            <span class="red">None</span><br> 
+        </td>
+    </tr>
+    <tr>
+        <td>
+          <B>
             
+           NameIdMappingTestSourceSequences.StringToRealSequence.Value
+        
+          </B><br>
+        </td>
+        <td>
+            <span class="red">None</span><br>
+        </td>
+        <td>
+            <span class="red">None</span><br> 
+        </td>
+    </tr>
+    <tr>
+        <td>
+          <B>
             
-            </table>
+           NameIdMappingTestTargetSettings.Sequence
+        
+          </B><br>
+        </td>
+        <td>
+            <span class="red">None</span><br>
+        </td>
+        <td>
+            <span class="red">None</span><br> 
+        </td>
+    </tr>
+    <tr>
+        <td>
+          <B>
             
-            <table class="report">
-                
-                    
-                        <tr>
-                            <th class="th.header">Setting</th>
-                            <th class="th.header">Value</th>
-                        </tr>
-                        <tr>
-                            <td><b>Value sub-setting</b></td>
-                            <td>
-                                
-                                    Entry 1<br>
-                                
-                                    Entry 2<br>
-                                
-                                    Entry 3<br>
-                                
-                                    Entry 4 (new)<br>
-                                
-                                    Entry 5 (new)<br>
-                                
-                            </td>
-                        </tr>
-                    
-                
-            </table>
-        </tr>
-    
-        <tr>
-            <td align="left" >
-                <b>NameIdMappingTestSourceSequences.StringToIntSequence</b><br>
-                <b>Name: </b>String-to-int sequence<br>
-                <b>Type: </b>sequence<br>
-                <b>ConfML: </b><a href="file:///this_is_ignored/base/confml/name_id_mapping_test.confml">base\confml\name_id_mapping_test.confml</a>
-            </td>
-            <td align="left">
-            <table class="report">
+           SequenceSettingTest.SequenceSetting
+        
+          </B><br>
+        </td>
+        <td>
+            <span class="red">None</span><br>
+        </td>
+        <td>
+            <span class="red">None</span><br> 
+        </td>
+    </tr>
+    <tr>
+        <td>
+          <B>
             
-            
-            </table>
+           SequenceSettingTest.SequenceSetting.BooleanSubSetting
+        
+          </B><br>
+        </td>
+        <td>
+            <span class="red">None</span><br>
+        </td>
+        <td>
+            <span class="red">None</span><br> 
+        </td>
+    </tr>
+    <tr>
+        <td>
+          <B>
             
-            <table class="report">
-                
-                    
-                        <tr>
-                            <th class="th.header">Setting</th>
-                            <th class="th.header">Value</th>
-                        </tr>
-                        <tr>
-                            <td><b>Name sub-setting</b></td>
-                            <td>
-                                
-                                    Entry 1<br>
-                                
-                                    Entry 2<br>
-                                
-                                    Entry 3<br>
-                                
-                                    Entry 4 (new)<br>
-                                
-                                    Entry 5 (new)<br>
-                                
-                            </td>
-                        </tr>
-                    
-                
-                    
-                        <tr>
-                            <td><b>Value sub-setting</b></td>
-                            <td>
-                                
-                                    100<br>
-                                
-                                    120<br>
-                                
-                                    130<br>
-                                
-                                    140<br>
-                                
-                                    150<br>
-                                
-                            </td>
-                        </tr>
-                    
-                
-            </table>
-        </tr>
-    
-        <tr>
-            <td align="left" >
-                <b>NameIdMappingTestSourceSequences.StringToRealSequence</b><br>
-                <b>Name: </b>String-to-real sequence<br>
-                <b>Type: </b>sequence<br>
-                <b>ConfML: </b><a href="file:///this_is_ignored/base/confml/name_id_mapping_test.confml">base\confml\name_id_mapping_test.confml</a>
-            </td>
-            <td align="left">
-            <table class="report">
+           SequenceSettingTest.SequenceSetting.FileSubSetting.localPath
+        
+          </B><br>
+        </td>
+        <td>
+            <span class="red">None</span><br>
+        </td>
+        <td>
+            <span class="red">None</span><br> 
+        </td>
+    </tr>
+    <tr>
+        <td>
+          <B>
             
-            
-            </table>
+           SequenceSettingTest.SequenceSetting.FileSubSetting.targetPath
+        
+          </B><br>
+        </td>
+        <td>
+            <span class="red">None</span><br>
+        </td>
+        <td>
+            <span class="red">None</span><br> 
+        </td>
+    </tr>
+    <tr>
+        <td>
+          <B>
             
-            <table class="report">
-                
-                    
-                        <tr>
-                            <th class="th.header">Setting</th>
-                            <th class="th.header">Value</th>
-                        </tr>
-                        <tr>
-                            <td><b>Name sub-setting</b></td>
-                            <td>
-                                
-                                    Entry 1<br>
-                                
-                                    Entry 2<br>
-                                
-                                    Entry 3<br>
-                                
-                                    Entry 4 (new)<br>
-                                
-                                    Entry 5 (new)<br>
-                                
-                            </td>
-                        </tr>
-                    
-                
-                    
-                        <tr>
-                            <td><b>Value sub-setting</b></td>
-                            <td>
-                                
-                                    1.1<br>
-                                
-                                    1.2<br>
-                                
-                                    1.3<br>
-                                
-                                    1.4<br>
-                                
-                                    1.5<br>
-                                
-                            </td>
-                        </tr>
-                    
-                
-            </table>
-        </tr>
-    
-        <tr>
-            <td align="left" >
-                <b>SequenceSettingTest.SequenceSetting</b><br>
-                <b>Name: </b>Sequence setting<br>
-                <b>Type: </b>sequence<br>
-                <b>ConfML: </b><a href="file:///this_is_ignored/base/confml/sequence_setting_test.confml">base\confml\sequence_setting_test.confml</a>
-            </td>
-            <td align="left">
-            <table class="report">
+           SequenceSettingTest.SequenceSetting.FolderSubSetting.localPath
+        
+          </B><br>
+        </td>
+        <td>
+            <span class="red">None</span><br>
+        </td>
+        <td>
+            <span class="red">None</span><br> 
+        </td>
+    </tr>
+    <tr>
+        <td>
+          <B>
             
+           SequenceSettingTest.SequenceSetting.FolderSubSetting.targetPath
+        
+          </B><br>
+        </td>
+        <td>
+            <span class="red">None</span><br>
+        </td>
+        <td>
+            <span class="red">None</span><br> 
+        </td>
+    </tr>
+    <tr>
+        <td>
+          <B>
             
-            </table>
+           SequenceSettingTest.SequenceSetting.IntSubSetting
+        
+          </B><br>
+        </td>
+        <td>
+            <span class="red">None</span><br>
+        </td>
+        <td>
+            <span class="red">None</span><br> 
+        </td>
+    </tr>
+    <tr>
+        <td>
+          <B>
             
-            <table class="report">
-                
-                    
-                        <tr>
-                            <th class="th.header">Setting</th>
-                            <th class="th.header">Value</th>
-                        </tr>
-                        <tr>
-                            <td><b>Folder sub-setting</b></td>
-                            <td>
-                                
-                                    [&#39;seq/default_folder&#39;, None]<br>
-                                
-                            </td>
-                        </tr>
-                    
-                
-                    
-                        <tr>
-                            <td><b>localPath</b></td>
-                            <td>
-                                
-                                    seq/default_folder<br>
-                                
-                            </td>
-                        </tr>
-                    
-                
-                    
-                        <tr>
-                            <td><b>targetPath</b></td>
-                            <td>
-                                
-                                    None<br>
-                                
-                            </td>
-                        </tr>
-                    
-                
-                    
-                        <tr>
-                            <td><b>Real sub-setting</b></td>
-                            <td>
-                                
-                                    10.10<br>
-                                
-                            </td>
-                        </tr>
-                    
-                
-                    
-                        <tr>
-                            <td><b>File sub-setting</b></td>
-                            <td>
-                                
-                                    [&#39;seq/default_file.txt&#39;, None]<br>
-                                
-                            </td>
-                        </tr>
-                    
-                
-                    
-                        <tr>
-                            <td><b>localPath</b></td>
-                            <td>
-                                
-                                    seq/default_file.txt<br>
-                                
-                            </td>
-                        </tr>
-                    
-                
-                    
-                        <tr>
-                            <td><b>targetPath</b></td>
-                            <td>
-                                
-                                    None<br>
-                                
-                            </td>
-                        </tr>
-                    
-                
-                    
-                        <tr>
-                            <td><b>Int sub-setting</b></td>
-                            <td>
-                                
-                                    120<br>
-                                
-                            </td>
-                        </tr>
-                    
-                
-                    
-                        <tr>
-                            <td><b>String sub-setting</b></td>
-                            <td>
-                                
-                                    &lt;&amp;&#12459;&#12479;&#12459;&#12490;&gt;<br>
-                                
-                            </td>
-                        </tr>
-                    
-                
-                    
-                        <tr>
-                            <td><b>Boolean sub-setting</b></td>
-                            <td>
-                                
-                                    true<br>
-                                
-                            </td>
-                        </tr>
-                    
-                
-                    
-                        <tr>
-                            <td><b>Selection sub-setting</b></td>
-                            <td>
-                                
-                                    2<br>
-                                
-                            </td>
-                        </tr>
-                    
-                
-            </table>
-        </tr>
-    
-        <tr>
-            <td align="left" >
-                <b><i>TempFeature.Unused</i></b><br>
-                <b>Name: </b>Unused<br>
-                <b>Type: </b>boolean<br>
-                <b>ConfML: </b><a href="file:///this_is_ignored/autodata.confml">autodata.confml</a>
-            </td>
-            <td align="left">
-            <table class="report">
+           SequenceSettingTest.SequenceSetting.RealSubSetting
+        
+          </B><br>
+        </td>
+        <td>
+            <span class="red">None</span><br>
+        </td>
+        <td>
+            <span class="red">None</span><br> 
+        </td>
+    </tr>
+    <tr>
+        <td>
+          <B>
+            
+           SequenceSettingTest.SequenceSetting.SelectionSubSetting
+        
+          </B><br>
+        </td>
+        <td>
+            <span class="red">None</span><br>
+        </td>
+        <td>
+            <span class="red">None</span><br> 
+        </td>
+    </tr>
+    <tr>
+        <td>
+          <B>
             
-            
-                
-                    <tr>
-                        <th class="th.header">Layer</th>
-                        <th class="th.header">Value</th>
-                    </tr>
-                    <tr>
-                        <td><a href="file:///this_is_ignored/autodata.confml">autodata.confml</a></td>
-                        <td>false</td>
-                    </tr>
-                
-            
-            </table>
-            
-            <table class="report">
-                
-            </table>
-        </tr>
+           SequenceSettingTest.SequenceSetting.StringSubSetting
         
+          </B><br>
+        </td>
+        <td>
+            <span class="red">None</span><br>
+        </td>
+        <td>
+            <span class="red">None</span><br> 
+        </td>
+    </tr>
+
     </table>
-    <h1>Not generated output files:</h1><br>
-    
-    <table class="report">
-    <tr>
-        <th class="featureName">Output file</th>
-    </tr>
-    
-        <tr>
-            <td align="left" >
-                output\content\template_string_condition_false.txt
-            </td>
-    
-        <tr>
-            <td align="left" >
-                output\content\missing_output_file_test1.txt
-            </td>
-    
-        <tr>
-            <td align="left" >
-                output\content\missing_output_file_test2.txt
-            </td>
-    
-    </table>
+        
+    <!-- Create extra data divs only when debug is on -->        
+     <!-- verbose 3 -->
+        
+    <script language="javascript" type="text/javascript">
+        //<![CDATA[
+             var output_Props =  {  
+                     paging: false,
+                     highlight_keywords: true,                      
+                     rows_counter: true,  
+                     rows_counter_text: "Rows:",  
+                     btn_reset: true,  
+                     loader: true,  
+                     loader_text: "Filtering data..."  
+                 }; 
+            setFilterGrid("outputs", output_Props);
+            
+            function Showpopup(item_over, popup_ref)
+            {
+                Popup.show(popup_ref, item_over,'top left', {'offsetTop':20});
+            } 
+        //]]>
+    </script>
+
     
 </body>
 </html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/generate/impl_container/expected/data_root.confml/output_test.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,1 @@
+Test!
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/generate/impl_container/expected/data_root.confml/test.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,1 @@
+TestFeature.Target: set from rule
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/generate/impl_container/project/base_root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="ASCII"?>
+<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2 http://www.w3.org/2001/XInclude http://www.s60.com/xml/confml/1#//include">
+  <xi:include href="layer/root.confml"/>
+</confml:configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/generate/impl_container/project/data/confml/data.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/2" name="Data">
+  <data>
+    <TestFeature>
+      <Trigger>foo</Trigger>
+    </TestFeature>
+  </data>
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/generate/impl_container/project/data/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="ASCII"?>
+<confml:configuration xmlns:confml="http://www.s60.com/xml/confml/1" xmlns:xi="http://www.w3.org/2001/XInclude" name="Data layer">
+  <xi:include href="confml/data.confml"/>
+</confml:configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/generate/impl_container/project/data_root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="ASCII"?>
+<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2 http://www.w3.org/2001/XInclude http://www.s60.com/xml/confml/1#//include">
+  <xi:include href="layer/root.confml"/>
+  <xi:include href="data/root.confml"/>
+</confml:configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/generate/impl_container/project/layer/confml/test.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/2" name="Test feature">
+  <feature ref="TestFeature" name="Test feature">
+    <setting ref="Trigger" name="String setting (trigger)" type="string"/>
+    <setting ref="Target" name="String setting (target)" type="string"/>
+  </feature>
+  
+  <data>
+    <TestFeature>
+      <Trigger>foo</Trigger>
+      <Target>bar</Target>
+    </TestFeature>
+  </data>
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/generate/impl_container/project/layer/implml/eval_generation_context.ruleml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ruleml xmlns="http://www.s60.com/xml/ruleml/3">
+  <rule>True configures {% test_add_file_to_output_folder() %}</rule>
+  
+  <eval_globals file="scripts/test_eval_generation_context.py"/>
+</ruleml>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/generate/impl_container/project/layer/implml/scripts/test_eval_generation_context.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,30 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+
+#add file to output folder
+def test_add_file_to_output_folder():
+
+    filename = "output_test.txt"
+    try:
+        output = ruleml.context.output
+        f = open(output + '/' + filename,'w')
+        f.writelines("Test!")
+        f.close()
+    except Exception, e:
+        print e
+        
+    return output + '/' + filename
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/generate/impl_container/project/layer/implml/test.implml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<container xmlns="http://www.symbianfoundation.org/xml/implml/1">
+    <phase name="normal"/>
+    
+    <ruleml xmlns="http://www.s60.com/xml/ruleml/3">
+        <rule>${TestFeature.Trigger} configures ${TestFeature.Target} = 'set from rule'</rule>
+    </ruleml>
+    
+    <templateml xmlns="http://www.s60.com/xml/templateml/1">
+        <output file="test.txt" encoding="UTF-8">
+            <template>TestFeature.Target: {{ feat_tree.TestFeature.Target._value }}</template>
+        </output>
+    </templateml>
+</container>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/generate/impl_container/project/layer/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="ASCII"?>
+<confml:configuration xmlns:confml="http://www.s60.com/xml/confml/1" xmlns:xi="http://www.w3.org/2001/XInclude" name="Base layer">
+  <xi:include href="confml/test.confml"/>
+</confml:configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/generate/layer_filtering_project/assets/base/confml/test_feature.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/1" name="Test feature" version="1">
+  <feature ref="TestFeature" name="Test feature">
+    <setting ref="BaseLayerSetting" name="Base layer setting" type="int"/>
+    <setting ref="Layer1Setting" name="Layer 1 setting" type="int"/>
+    <setting ref="Layer2Setting" name="Layer 2 setting" type="int"/>
+    <setting ref="Layer3Setting" name="Layer 3 setting" type="int"/>
+  </feature>
+  <data>
+    <TestFeature>
+      <BaseLayerSetting>0</BaseLayerSetting>
+      <Layer1Setting>0</Layer1Setting>
+      <Layer2Setting>0</Layer2Setting>
+      <Layer3Setting>0</Layer3Setting>
+    </TestFeature>
+  </data>
+</configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/generate/layer_filtering_project/assets/base/implml/base.templateml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<templateml xmlns="http://www.s60.com/xml/templateml/1">
+    <output file="base.txt" encoding="UTF-8">
+        <template>Value: {{ feat_tree.TestFeature.BaseLayerSetting._value }}</template>
+    </output>
+</templateml>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/generate/layer_filtering_project/assets/base/implml/layer1.templateml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<templateml xmlns="http://www.s60.com/xml/templateml/1">
+    <output file="layer1.txt" encoding="UTF-8">
+        <template>Value: {{ feat_tree.TestFeature.Layer1Setting._value }}</template>
+    </output>
+</templateml>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/generate/layer_filtering_project/assets/base/implml/layer2.templateml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<templateml xmlns="http://www.s60.com/xml/templateml/1">
+    <output file="layer2.txt" encoding="UTF-8">
+        <template>Value: {{ feat_tree.TestFeature.Layer2Setting._value }}</template>
+    </output>
+</templateml>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/generate/layer_filtering_project/assets/base/implml/layer3.templateml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<templateml xmlns="http://www.s60.com/xml/templateml/1">
+    <output file="layer3.txt" encoding="UTF-8">
+        <template>Value: {{ feat_tree.TestFeature.Layer3Setting._value }}</template>
+    </output>
+</templateml>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/generate/layer_filtering_project/assets/base/implml/rule_test.implml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<container xmlns="http://www.symbianfoundation.org/xml/implml/1">
+    <!-- Test for RuleML v2 -->
+    <container>
+        <tempVariable ref="TempFooV2" type="string"/>
+        
+        <container>
+            <phase name="pre"/>
+            <ruleml xmlns="http://www.s60.com/xml/ruleml/2">
+                <rule>TestFeature.BaseLayerSetting configures TempFooV2 = TempFooV2 + ' base'</rule>
+                <rule>TestFeature.Layer1Setting configures TempFooV2 = TempFooV2 + ' layer1'</rule>
+                <rule>{% ${TestFeature.Layer2Setting} %} configures TempFooV2 = TempFooV2 + ' layer2'</rule>
+                <rule>TestFeature.Layer3Setting configures TempFooV2 = TempFooV2 + ' layer3'</rule>
+                <rule>True configures TempFooV2 = TempFooV2 + ' x'</rule>
+            </ruleml>
+        </container>
+
+        <container>
+            <phase name="normal"/>
+            <templateml xmlns="http://www.s60.com/xml/templateml/1">
+                <output file="rule_test_v2.txt" encoding="UTF-8">
+                    <template>{{ feat_tree.TempFooV2._value }}</template>
+                </output>
+            </templateml>
+        </container>
+    </container>
+    
+    <!-- Test for RuleML v3 -->
+    <container>
+        <tempVariable ref="TempFooV3" type="string"/>
+        
+        <container>
+            <phase name="pre"/>
+            <ruleml xmlns="http://www.s60.com/xml/ruleml/3">
+                <rule>${TestFeature.BaseLayerSetting} configures ${TempFooV3} = ${TempFooV3} + ' base'</rule>
+                <rule>${TestFeature.Layer1Setting} configures ${TempFooV3} = ${TempFooV3} + ' layer1'</rule>
+                <rule>{% ${TestFeature.Layer2Setting} %} configures ${TempFooV3} = ${TempFooV3} + ' layer2'</rule>
+                <rule>${TestFeature.Layer3Setting} configures ${TempFooV3} = ${TempFooV3} + ' layer3'</rule>
+                <rule>True configures ${TempFooV3} = ${TempFooV3} + ' x'</rule>
+            </ruleml>
+        </container>
+
+        <container>
+            <phase name="normal"/>
+            <templateml xmlns="http://www.s60.com/xml/templateml/1">
+                <output file="rule_test_v3.txt" encoding="UTF-8">
+                    <template>{{ feat_tree.TempFooV3._value }}</template>
+                </output>
+            </templateml>
+        </container>
+    </container>
+</container>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/generate/layer_filtering_project/assets/base/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2 http://www.w3.org/2001/XInclude http://www.s60.com/xml/confml/1#//include">
+<xi:include href="confml/test_feature.confml" />
+</confml:configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/generate/layer_filtering_project/assets/layer1/confml/data.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/2" name="data">
+  <data>
+    <TestFeature>
+      <Layer1Setting>1</Layer1Setting>
+    </TestFeature>
+  </data>
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/generate/layer_filtering_project/assets/layer1/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="ASCII"?>
+<configuration xmlns="http://www.s60.com/xml/confml/1" xmlns:xi="http://www.w3.org/2001/XInclude" name="Layer 1">
+  <xi:include href="confml/data.confml"/>
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/generate/layer_filtering_project/assets/layer2/confml/data.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/2" name="data">
+  <data>
+    <TestFeature>
+      <Layer2Setting>2</Layer2Setting>
+    </TestFeature>
+  </data>
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/generate/layer_filtering_project/assets/layer2/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="ASCII"?>
+<configuration xmlns="http://www.s60.com/xml/confml/1" xmlns:xi="http://www.w3.org/2001/XInclude" name="Layer 2">
+  <xi:include href="confml/data.confml"/>
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/generate/layer_filtering_project/assets/layer3/confml/data.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/2" name="data">
+  <data>
+    <TestFeature>
+      <Layer3Setting>2</Layer3Setting>
+    </TestFeature>
+  </data>
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/generate/layer_filtering_project/assets/layer3/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="ASCII"?>
+<configuration xmlns="http://www.s60.com/xml/confml/1" xmlns:xi="http://www.w3.org/2001/XInclude" name="Layer 3">
+  <xi:include href="confml/data.confml"/>
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/generate/layer_filtering_project/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="ASCII"?>
+<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2 http://www.w3.org/2001/XInclude http://www.s60.com/xml/confml/1#//include">
+  <xi:include href="assets/base/root.confml"/>
+  <xi:include href="assets/layer1/root.confml"/>
+  <xi:include href="assets/layer2/root.confml"/>
+  <xi:include href="assets/layer3/root.confml"/>
+</confml:configuration>
\ No newline at end of file
--- a/configurationengine/source/scripts/tests/testdata/info/expected/api_report.html	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/tests/testdata/info/expected/api_report.html	Tue Aug 10 14:29:28 2010 +0300
@@ -110,7 +110,28 @@
     .currentValue {
         background-color: #e8f2fe;
     }
+
+.fltrow{ /* filter grid row appearance */
+    height:20px;
+    background-color:#f4f4f4;
+}
+.btnflt{ /* button appearance */
+    font-size:11px;
+    margin:0 2px 0 2px; padding:0 1px 0 1px;
+    text-decoration:none; color: #fff;
+    background-color:#666;
+}
+.flt{ /* filter (input) appearance */
+    background-color:#f4f4f4; border:1px inset #ccc; 
+    margin:0; width:100%;
+}
+.flt_s{ /* small filter (input) appearance */
+    background-color:#f4f4f4; border:1px inset #ccc; 
+    margin:0; width:80%;
+}
+
 </style>
+<script language="javascript" type="text/javascript" src="http://www.javascriptkit.com/script/script2/tablefilter.js"></script>
 <title>API info - ConE</title>
 
 </head>
@@ -118,7 +139,7 @@
 <div id="content">
     <h1>Configuration API info</h1><br>
 
-    <table class="report">
+    <table class="report" id="report_data">
     <tr>
         <th class="featureName">File</th>
         
@@ -853,6 +874,12 @@
     
     
     </table>
+
+<script language="javascript" type="text/javascript">
+//<![CDATA[
+    setFilterGrid("report_data");
+//]]>
+</script>
 </div>
 <div id="footer"></div>
 </body>
--- a/configurationengine/source/scripts/tests/testdata/info/expected/content_report.html	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/tests/testdata/info/expected/content_report.html	Tue Aug 10 14:29:28 2010 +0300
@@ -110,7 +110,28 @@
     .currentValue {
         background-color: #e8f2fe;
     }
+
+.fltrow{ /* filter grid row appearance */
+    height:20px;
+    background-color:#f4f4f4;
+}
+.btnflt{ /* button appearance */
+    font-size:11px;
+    margin:0 2px 0 2px; padding:0 1px 0 1px;
+    text-decoration:none; color: #fff;
+    background-color:#666;
+}
+.flt{ /* filter (input) appearance */
+    background-color:#f4f4f4; border:1px inset #ccc; 
+    margin:0; width:100%;
+}
+.flt_s{ /* small filter (input) appearance */
+    background-color:#f4f4f4; border:1px inset #ccc; 
+    margin:0; width:80%;
+}
+
 </style>
+<script language="javascript" type="text/javascript" src="http://www.javascriptkit.com/script/script2/tablefilter.js"></script>
 <title>Content info - ConE</title>
 
 </head>
@@ -118,7 +139,7 @@
 <div id="content">
     <h1>Configuration content files</h1><br>
 
-    <table class="report">
+    <table class="report" id="report_data">
     <tr>
         <th class="featureName">Content file</th>
 		<th class="featureName">Actual files (used one last)</th>
@@ -171,6 +192,11 @@
     
     
     </table>
+    <script language="javascript" type="text/javascript">
+//<![CDATA[
+    setFilterGrid("report_data");
+//]]>
+</script>
 </div>
 <div id="footer"></div>
 </body>
--- a/configurationengine/source/scripts/tests/testdata/info/expected/impl_report.html	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/tests/testdata/info/expected/impl_report.html	Tue Aug 10 14:29:28 2010 +0300
@@ -110,7 +110,28 @@
     .currentValue {
         background-color: #e8f2fe;
     }
+
+.fltrow{ /* filter grid row appearance */
+    height:20px;
+    background-color:#f4f4f4;
+}
+.btnflt{ /* button appearance */
+    font-size:11px;
+    margin:0 2px 0 2px; padding:0 1px 0 1px;
+    text-decoration:none; color: #fff;
+    background-color:#666;
+}
+.flt{ /* filter (input) appearance */
+    background-color:#f4f4f4; border:1px inset #ccc; 
+    margin:0; width:100%;
+}
+.flt_s{ /* small filter (input) appearance */
+    background-color:#f4f4f4; border:1px inset #ccc; 
+    margin:0; width:80%;
+}
+
 </style>
+<script language="javascript" type="text/javascript" src="http://www.javascriptkit.com/script/script2/tablefilter.js"></script>
 <title>Implementation info - ConE</title>
 
 </head>
@@ -118,10 +139,10 @@
 <div id="content">
     <h1>Implementations</h1><br>
 
-    <table class="report">
+    <table class="report" id="report_data">
     <tr>
         <th class="featureName">File</th>
-		<th class="featureName">Index</th>
+		<th class="featureName">Line</th>
 		<th class="featureName">Type</th>
 		<th class="featureName">Phase</th>
 		<th class="featureName">Tags</th>
@@ -130,7 +151,7 @@
     
     <tr>
         <td>Layer1/implml/bitmask_test.templateml</td>
-		<td>0</td>
+		<td>2</td>
 		<td>templateml</td>
 		<td>normal</td>
 		<td></td>
@@ -139,7 +160,7 @@
     
     <tr>
         <td>Layer1/implml/feature1_1.templateml</td>
-		<td>0</td>
+		<td>2</td>
 		<td>templateml</td>
 		<td>normal</td>
 		<td></td>
@@ -148,7 +169,7 @@
     
     <tr>
         <td>Layer1/implml/feature1_2.templateml</td>
-		<td>0</td>
+		<td>2</td>
 		<td>templateml</td>
 		<td>normal</td>
 		<td></td>
@@ -157,7 +178,7 @@
     
     <tr>
         <td>Layer1/implml/feature1_sequence.templateml</td>
-		<td>0</td>
+		<td>2</td>
 		<td>templateml</td>
 		<td>normal</td>
 		<td></td>
@@ -166,7 +187,7 @@
     
     <tr>
         <td>Layer1/implml/feature2.templateml</td>
-		<td>0</td>
+		<td>2</td>
 		<td>templateml</td>
 		<td>normal</td>
 		<td></td>
@@ -175,7 +196,7 @@
     
     <tr>
         <td>Layer1/implml/time_types_test.templateml</td>
-		<td>0</td>
+		<td>2</td>
 		<td>templateml</td>
 		<td>normal</td>
 		<td></td>
@@ -184,6 +205,12 @@
     
     
     </table>
+    <script language="javascript" type="text/javascript">
+//<![CDATA[
+    setFilterGrid("report_data");
+//]]>
+</script>
+    
 </div>
 <div id="footer"></div>
 </body>
--- a/configurationengine/source/scripts/tests/testdata/info/expected/impl_report_with_containers.html	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/tests/testdata/info/expected/impl_report_with_containers.html	Tue Aug 10 14:29:28 2010 +0300
@@ -110,7 +110,28 @@
     .currentValue {
         background-color: #e8f2fe;
     }
+
+.fltrow{ /* filter grid row appearance */
+    height:20px;
+    background-color:#f4f4f4;
+}
+.btnflt{ /* button appearance */
+    font-size:11px;
+    margin:0 2px 0 2px; padding:0 1px 0 1px;
+    text-decoration:none; color: #fff;
+    background-color:#666;
+}
+.flt{ /* filter (input) appearance */
+    background-color:#f4f4f4; border:1px inset #ccc; 
+    margin:0; width:100%;
+}
+.flt_s{ /* small filter (input) appearance */
+    background-color:#f4f4f4; border:1px inset #ccc; 
+    margin:0; width:80%;
+}
+
 </style>
+<script language="javascript" type="text/javascript" src="http://www.javascriptkit.com/script/script2/tablefilter.js"></script>
 <title>Implementation info - ConE</title>
 
 </head>
@@ -118,10 +139,10 @@
 <div id="content">
     <h1>Implementations</h1><br>
 
-    <table class="report">
+    <table class="report" id="report_data">
     <tr>
         <th class="featureName">File</th>
-		<th class="featureName">Index</th>
+		<th class="featureName">Line</th>
 		<th class="featureName">Type</th>
 		<th class="featureName">Phase</th>
 		<th class="featureName">Tags</th>
@@ -130,7 +151,7 @@
     
     <tr>
         <td>base/implml/multiselection.templateml</td>
-		<td>0</td>
+		<td>2</td>
 		<td>templateml</td>
 		<td>normal</td>
 		<td></td>
@@ -139,7 +160,7 @@
     
     <tr>
         <td>base/implml/name_id_mapping_test.templateml</td>
-		<td>0</td>
+		<td>2</td>
 		<td>templateml</td>
 		<td>normal</td>
 		<td></td>
@@ -148,7 +169,7 @@
     
     <tr>
         <td>custom/implml/conditional_container.implml</td>
-		<td>0</td>
+		<td>12</td>
 		<td>templateml</td>
 		<td>normal</td>
 		<td></td>
@@ -157,7 +178,7 @@
     
     <tr>
         <td>custom/implml/conditional_container.implml</td>
-		<td>1</td>
+		<td>23</td>
 		<td>templateml</td>
 		<td>normal</td>
 		<td></td>
@@ -166,7 +187,7 @@
     
     <tr>
         <td>custom/implml/conditional_container.implml</td>
-		<td>2</td>
+		<td>34</td>
 		<td>content</td>
 		<td>normal</td>
 		<td>target = ['rofs3']<br/></td>
@@ -175,7 +196,25 @@
     
     <tr>
         <td>custom/implml/conditional_container.implml</td>
-		<td>3</td>
+		<td>43</td>
+		<td>content</td>
+		<td>normal</td>
+		<td>target = ['rofs3']<br/></td>
+		<td>None</td>
+    </tr>
+    
+    <tr>
+        <td>custom/implml/impl_override_test.templateml</td>
+		<td>2</td>
+		<td>templateml</td>
+		<td>normal</td>
+		<td></td>
+		<td>BasicSettingTypesTest.IntSetting<br/></td>
+    </tr>
+    
+    <tr>
+        <td>custom/implml/invocation_phase_test.implml</td>
+		<td>6</td>
 		<td>content</td>
 		<td>normal</td>
 		<td>target = ['rofs3']<br/></td>
@@ -184,16 +223,7 @@
     
     <tr>
         <td>custom/implml/invocation_phase_test.implml</td>
-		<td>0</td>
-		<td>content</td>
-		<td>normal</td>
-		<td>target = ['rofs3']<br/></td>
-		<td>None</td>
-    </tr>
-    
-    <tr>
-        <td>custom/implml/invocation_phase_test.implml</td>
-		<td>1</td>
+		<td>15</td>
 		<td>content</td>
 		<td>post</td>
 		<td>target = ['rofs3']<br/></td>
@@ -202,7 +232,7 @@
     
     <tr>
         <td>custom/implml/invocation_phase_test.implml</td>
-		<td>2</td>
+		<td>25</td>
 		<td>content</td>
 		<td>normal</td>
 		<td>target = ['rofs3']<br/></td>
@@ -211,7 +241,7 @@
     
     <tr>
         <td>custom/implml/invocation_phase_test.implml</td>
-		<td>3</td>
+		<td>31</td>
 		<td>content</td>
 		<td>post</td>
 		<td>target = ['rofs3']<br/></td>
@@ -220,7 +250,7 @@
     
     <tr>
         <td>custom/implml/missing_file_in_report_test.implml</td>
-		<td>0</td>
+		<td>11</td>
 		<td>templateml</td>
 		<td>normal</td>
 		<td></td>
@@ -229,7 +259,16 @@
     
     <tr>
         <td>custom/implml/missing_file_in_report_test.implml</td>
-		<td>1</td>
+		<td>28</td>
+		<td>ruleml</td>
+		<td>post</td>
+		<td></td>
+		<td>None</td>
+    </tr>
+    
+    <tr>
+        <td>custom/implml/missing_file_in_report_test.implml</td>
+		<td>29</td>
 		<td>ruleml</td>
 		<td>post</td>
 		<td></td>
@@ -238,7 +277,16 @@
     
     <tr>
         <td>custom/implml/output_override_test.implml</td>
-		<td>0</td>
+		<td>6</td>
+		<td>content</td>
+		<td>normal</td>
+		<td>target = ['rofs3']<br/></td>
+		<td>None</td>
+    </tr>
+    
+    <tr>
+        <td>custom/implml/output_override_test.implml</td>
+		<td>16</td>
 		<td>content</td>
 		<td>normal</td>
 		<td>target = ['rofs3']<br/></td>
@@ -247,16 +295,7 @@
     
     <tr>
         <td>custom/implml/output_override_test.implml</td>
-		<td>1</td>
-		<td>content</td>
-		<td>normal</td>
-		<td>target = ['rofs3']<br/></td>
-		<td>None</td>
-    </tr>
-    
-    <tr>
-        <td>custom/implml/output_override_test.implml</td>
-		<td>2</td>
+		<td>27</td>
 		<td>content</td>
 		<td>normal</td>
 		<td>target = ['rofs3']<br/></td>
@@ -265,7 +304,7 @@
     
     <tr>
         <td>custom/implml/seq_tempvar.implml</td>
-		<td>0</td>
+		<td>15</td>
 		<td>ruleml</td>
 		<td>pre</td>
 		<td></td>
@@ -274,7 +313,7 @@
     
     <tr>
         <td>custom/implml/seq_tempvar.implml</td>
-		<td>1</td>
+		<td>21</td>
 		<td>content</td>
 		<td>normal</td>
 		<td>target = ['rofs3']<br/></td>
@@ -283,7 +322,16 @@
     
     <tr>
         <td>custom/implml/simple_tempvars.implml</td>
-		<td>0</td>
+		<td>12</td>
+		<td>ruleml</td>
+		<td>pre</td>
+		<td></td>
+		<td>None</td>
+    </tr>
+    
+    <tr>
+        <td>custom/implml/simple_tempvars.implml</td>
+		<td>13</td>
 		<td>ruleml</td>
 		<td>pre</td>
 		<td></td>
@@ -292,7 +340,16 @@
     
     <tr>
         <td>custom/implml/simple_tempvars.implml</td>
-		<td>1</td>
+		<td>14</td>
+		<td>ruleml</td>
+		<td>pre</td>
+		<td></td>
+		<td>None</td>
+    </tr>
+    
+    <tr>
+        <td>custom/implml/simple_tempvars.implml</td>
+		<td>18</td>
 		<td>templateml</td>
 		<td>normal</td>
 		<td></td>
@@ -301,6 +358,12 @@
     
     
     </table>
+    <script language="javascript" type="text/javascript">
+//<![CDATA[
+    setFilterGrid("report_data");
+//]]>
+</script>
+    
 </div>
 <div id="footer"></div>
 </body>
--- a/configurationengine/source/scripts/tests/testdata/info/expected/value_report.csv	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/tests/testdata/info/expected/value_report.csv	Tue Aug 10 14:29:28 2010 +0300
@@ -1,9 +1,9 @@
-Name,Type,Possible values,product_langpack_01_root.confml,product_langpack_02_root.confml,product_langpack_03_root.confml,
+Name,Type,Possible values,Lang 1 (product_langpack_01_root.confml),product_langpack_02_root.confml,Lang 3 (product_langpack_03_root.confml),
 
 All settings
-Real setting,real,"",3.14,3.14,3.14,
+Real setting,real,"",3.14,2.5,3.14,
 Int setting,int,"",10,10,10,
-String setting,string,"",string from product (langpack 01) config,string from product (langpack 02) config,string from product (langpack 03) config,
+String setting,string,"",string from product (langpack 01) config,string from product config,string from product (langpack 03) config,
 Boolean setting,boolean,"",True,True,True,
 Selection setting,selection,"Option0
 Option1
--- a/configurationengine/source/scripts/tests/testdata/info/expected/value_report_custom.html	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/tests/testdata/info/expected/value_report_custom.html	Tue Aug 10 14:29:28 2010 +0300
@@ -110,7 +110,28 @@
     .currentValue {
         background-color: #e8f2fe;
     }
+
+.fltrow{ /* filter grid row appearance */
+    height:20px;
+    background-color:#f4f4f4;
+}
+.btnflt{ /* button appearance */
+    font-size:11px;
+    margin:0 2px 0 2px; padding:0 1px 0 1px;
+    text-decoration:none; color: #fff;
+    background-color:#666;
+}
+.flt{ /* filter (input) appearance */
+    background-color:#f4f4f4; border:1px inset #ccc; 
+    margin:0; width:100%;
+}
+.flt_s{ /* small filter (input) appearance */
+    background-color:#f4f4f4; border:1px inset #ccc; 
+    margin:0; width:80%;
+}
+
 </style>
+<script language="javascript" type="text/javascript" src="http://www.javascriptkit.com/script/script2/tablefilter.js"></script>
 <title>Data value info - ConE</title>
 
 </head>
@@ -191,7 +212,7 @@
         <td>sequence</td>
         
         
-        <td>SequenceData(columns=[SequenceColumn(ref='RealSubSetting', name='Real sub-setting', type='real'), SequenceColumn(ref='IntSubSetting', name='Int sub-setting', type='int'), SequenceColumn(ref='StringSubSetting', name='String sub-setting', type='string'), SequenceColumn(ref='BooleanSubSetting', name='Boolean sub-setting', type='boolean'), SequenceColumn(ref='SelectionSubSetting', name='Selection sub-setting', type='selection')], rows=[{'RealSubSetting': '1.5', 'IntSubSetting': '256', 'SelectionSubSetting': 'Op1', 'StringSubSetting': 'test (product)', 'BooleanSubSetting': 'false'}, {'RealSubSetting': '1.25', 'IntSubSetting': '128', 'SelectionSubSetting': 'Op1', 'StringSubSetting': 'def1', 'BooleanSubSetting': 'false'}, {'RealSubSetting': '1.5', 'IntSubSetting': '256', 'SelectionSubSetting': 'Op1', 'StringSubSetting': 'def2', 'BooleanSubSetting': 'false'}, {'RealSubSetting': '1.5', 'IntSubSetting': '256', 'SelectionSubSetting': 'Op1', 'StringSubSetting': 'test', 'BooleanSubSetting': 'true'}])</td>
+        <td>SequenceData(columns=[SequenceColumn(ref='RealSubSetting', name='Real sub-setting', type='real'), SequenceColumn(ref='IntSubSetting', name='Int sub-setting', type='int'), SequenceColumn(ref='StringSubSetting', name='String sub-setting', type='string'), SequenceColumn(ref='BooleanSubSetting', name='Boolean sub-setting', type='boolean'), SequenceColumn(ref='SelectionSubSetting', name='Selection sub-setting', type='selection')], rows=[{'RealSubSetting': 1.5, 'IntSubSetting': 256, 'SelectionSubSetting': 'Op1', 'StringSubSetting': 'test (product)', 'BooleanSubSetting': False}, {'RealSubSetting': 1.25, 'IntSubSetting': 128, 'SelectionSubSetting': 'Op1', 'StringSubSetting': 'def1', 'BooleanSubSetting': False}, {'RealSubSetting': 1.5, 'IntSubSetting': 256, 'SelectionSubSetting': 'Op1', 'StringSubSetting': 'def2', 'BooleanSubSetting': False}, {'RealSubSetting': 1.5, 'IntSubSetting': 256, 'SelectionSubSetting': 'Op1', 'StringSubSetting': 'test', 'BooleanSubSetting': True}])</td>
         
         
     </tr>
@@ -202,7 +223,7 @@
         <td>sequence</td>
         
         
-        <td>SequenceData(columns=[SequenceColumn(ref='IntSubSetting', name='Int sub-setting', type='int'), SequenceColumn(ref='StringSubSetting', name='String sub-setting', type='string')], rows=[{'IntSubSetting': '1', 'StringSubSetting': 'default 1'}, {'IntSubSetting': '2', 'StringSubSetting': 'default 2'}])</td>
+        <td>SequenceData(columns=[SequenceColumn(ref='IntSubSetting', name='Int sub-setting', type='int'), SequenceColumn(ref='StringSubSetting', name='String sub-setting', type='string')], rows=[{'IntSubSetting': 1, 'StringSubSetting': 'default 1'}, {'IntSubSetting': 2, 'StringSubSetting': 'default 2'}])</td>
         
         
     </tr>
@@ -268,7 +289,7 @@
         <td>sequence</td>
         
         
-        <td>SequenceData(columns=[SequenceColumn(ref='RealSubSetting', name='Real sub-setting', type='real'), SequenceColumn(ref='IntSubSetting', name='Int sub-setting', type='int'), SequenceColumn(ref='StringSubSetting', name='String sub-setting', type='string'), SequenceColumn(ref='BooleanSubSetting', name='Boolean sub-setting', type='boolean'), SequenceColumn(ref='SelectionSubSetting', name='Selection sub-setting', type='selection')], rows=[{'RealSubSetting': '1.25', 'IntSubSetting': '128', 'SelectionSubSetting': 'Op1', 'StringSubSetting': 'def1', 'BooleanSubSetting': 'false'}, {'RealSubSetting': '1.5', 'IntSubSetting': '256', 'SelectionSubSetting': 'Op1', 'StringSubSetting': 'def2', 'BooleanSubSetting': 'false'}])</td>
+        <td>SequenceData(columns=[SequenceColumn(ref='RealSubSetting', name='Real sub-setting', type='real'), SequenceColumn(ref='IntSubSetting', name='Int sub-setting', type='int'), SequenceColumn(ref='StringSubSetting', name='String sub-setting', type='string'), SequenceColumn(ref='BooleanSubSetting', name='Boolean sub-setting', type='boolean'), SequenceColumn(ref='SelectionSubSetting', name='Selection sub-setting', type='selection')], rows=[{'RealSubSetting': 1.25, 'IntSubSetting': 128, 'SelectionSubSetting': 'Op1', 'StringSubSetting': 'def1', 'BooleanSubSetting': False}, {'RealSubSetting': 1.5, 'IntSubSetting': 256, 'SelectionSubSetting': 'Op1', 'StringSubSetting': 'def2', 'BooleanSubSetting': False}])</td>
         
         
     </tr>
@@ -279,7 +300,7 @@
         <td>sequence</td>
         
         
-        <td>SequenceData(columns=[SequenceColumn(ref='IntSubSetting', name='Int sub-setting', type='int'), SequenceColumn(ref='StringSubSetting', name='String sub-setting', type='string')], rows=[{'IntSubSetting': '1', 'StringSubSetting': 'default 1'}, {'IntSubSetting': '2', 'StringSubSetting': 'default 2'}])</td>
+        <td>SequenceData(columns=[SequenceColumn(ref='IntSubSetting', name='Int sub-setting', type='int'), SequenceColumn(ref='StringSubSetting', name='String sub-setting', type='string')], rows=[{'IntSubSetting': 1, 'StringSubSetting': 'default 1'}, {'IntSubSetting': 2, 'StringSubSetting': 'default 2'}])</td>
         
         
     </tr>
--- a/configurationengine/source/scripts/tests/testdata/info/expected/value_report_langpacks.html	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/tests/testdata/info/expected/value_report_langpacks.html	Tue Aug 10 14:29:28 2010 +0300
@@ -110,7 +110,28 @@
     .currentValue {
         background-color: #e8f2fe;
     }
+
+.fltrow{ /* filter grid row appearance */
+    height:20px;
+    background-color:#f4f4f4;
+}
+.btnflt{ /* button appearance */
+    font-size:11px;
+    margin:0 2px 0 2px; padding:0 1px 0 1px;
+    text-decoration:none; color: #fff;
+    background-color:#666;
+}
+.flt{ /* filter (input) appearance */
+    background-color:#f4f4f4; border:1px inset #ccc; 
+    margin:0; width:100%;
+}
+.flt_s{ /* small filter (input) appearance */
+    background-color:#f4f4f4; border:1px inset #ccc; 
+    margin:0; width:80%;
+}
+
 </style>
+<script language="javascript" type="text/javascript" src="http://www.javascriptkit.com/script/script2/tablefilter.js"></script>
 <title>Data value info - ConE</title>
 
 </head>
@@ -118,23 +139,23 @@
 <div id="content">
     <h1>Configuration data value info</h1><br>
 
-    <table class="report">
+    <table class="report" id="report_data">
     <tr>
         <th class="featureName">Name</th>
         <th class="featureName">Type</th>
         <th class="featureName">Possible values</th>
         
-        <th class="featureName">product_langpack_01_root.confml</th>
+        <th class="featureName">Lang 1 (product_langpack_01_root.confml)</th>
         
         <th class="featureName">product_langpack_02_root.confml</th>
         
-        <th class="featureName">product_langpack_03_root.confml</th>
+        <th class="featureName">Lang 3 (product_langpack_03_root.confml)</th>
         
     </tr>
     
     <tr><th colspan="6">All settings</th></tr>
     
-    <tr>
+    <tr bgcolor="#CCCCFF">
         <td>Real setting</td>
         <td>real</td>
         <td></td>
@@ -142,7 +163,7 @@
         
         <td>3.14</td>
         
-        <td>3.14</td>
+        <td><b>2.5</b></td>
         
         <td>3.14</td>
         
@@ -170,11 +191,11 @@
         <td></td>
         
         
-        <td>string from product (langpack 01) config</td>
+        <td><b>string from product (langpack 01) config</b></td>
         
-        <td>string from product (langpack 02) config</td>
+        <td>string from product config</td>
         
-        <td>string from product (langpack 03) config</td>
+        <td><b>string from product (langpack 03) config</b></td>
         
         
     </tr>
@@ -223,20 +244,84 @@
         <td>
                     <table><tr><td colspan="2"><b>Item 1</b></td></tr><tr>
                             <td><b>Real sub-setting</b></td>
-                            <td>10001.5</td>
+                            <td><b>10001.5</b></td>
                             </tr><tr>
                             <td><b>Int sub-setting</b></td>
-                            <td>10001</td>
+                            <td><b>10001</b></td>
+                            </tr><tr>
+                            <td><b>String sub-setting</b></td>
+                            <td><b>test (product, lang 01)</b></td>
+                            </tr><tr>
+                            <td><b>Boolean sub-setting</b></td>
+                            <td><b>False</b></td>
+                            </tr><tr>
+                            <td><b>Selection sub-setting</b></td>
+                            <td><b>Op1</b></td>
+                            </tr><tr><td colspan="2"><b>Item 2</b></td></tr><tr>
+                            <td><b>Real sub-setting</b></td>
+                            <td><b>1.5</b></td>
+                            </tr><tr>
+                            <td><b>Int sub-setting</b></td>
+                            <td><b>256</b></td>
+                            </tr><tr>
+                            <td><b>String sub-setting</b></td>
+                            <td><b>test (product)</b></td>
+                            </tr><tr>
+                            <td><b>Boolean sub-setting</b></td>
+                            <td><b>False</b></td>
+                            </tr><tr>
+                            <td><b>Selection sub-setting</b></td>
+                            <td><b>Op1</b></td>
+                            </tr><tr><td colspan="2"><b>Item 3</b></td></tr><tr>
+                            <td><b>Real sub-setting</b></td>
+                            <td><b>1.25</b></td>
+                            </tr><tr>
+                            <td><b>Int sub-setting</b></td>
+                            <td><b>128</b></td>
                             </tr><tr>
                             <td><b>String sub-setting</b></td>
-                            <td>test (product, lang 01)</td>
+                            <td><b>def1</b></td>
+                            </tr><tr>
+                            <td><b>Boolean sub-setting</b></td>
+                            <td><b>False</b></td>
+                            </tr><tr>
+                            <td><b>Selection sub-setting</b></td>
+                            <td><b>Op1</b></td>
+                            </tr><tr><td colspan="2"><b>Item 4</b></td></tr><tr>
+                            <td><b>Real sub-setting</b></td>
+                            <td><b>1.5</b></td>
+                            </tr><tr>
+                            <td><b>Int sub-setting</b></td>
+                            <td><b>256</b></td>
+                            </tr><tr>
+                            <td><b>String sub-setting</b></td>
+                            <td><b>def2</b></td>
                             </tr><tr>
                             <td><b>Boolean sub-setting</b></td>
-                            <td>false</td>
+                            <td><b>False</b></td>
                             </tr><tr>
                             <td><b>Selection sub-setting</b></td>
-                            <td>Op1</td>
-                            </tr><tr><td colspan="2"><b>Item 2</b></td></tr><tr>
+                            <td><b>Op1</b></td>
+                            </tr><tr><td colspan="2"><b>Item 5</b></td></tr><tr>
+                            <td><b>Real sub-setting</b></td>
+                            <td><b>1.5</b></td>
+                            </tr><tr>
+                            <td><b>Int sub-setting</b></td>
+                            <td><b>256</b></td>
+                            </tr><tr>
+                            <td><b>String sub-setting</b></td>
+                            <td><b>test</b></td>
+                            </tr><tr>
+                            <td><b>Boolean sub-setting</b></td>
+                            <td><b>True</b></td>
+                            </tr><tr>
+                            <td><b>Selection sub-setting</b></td>
+                            <td><b>Op1</b></td>
+                            </tr></table>
+                </td>
+        
+        <td>
+                    <table><tr><td colspan="2"><b>Item 1</b></td></tr><tr>
                             <td><b>Real sub-setting</b></td>
                             <td>1.5</td>
                             </tr><tr>
@@ -247,11 +332,11 @@
                             <td>test (product)</td>
                             </tr><tr>
                             <td><b>Boolean sub-setting</b></td>
-                            <td>false</td>
+                            <td>False</td>
                             </tr><tr>
                             <td><b>Selection sub-setting</b></td>
                             <td>Op1</td>
-                            </tr><tr><td colspan="2"><b>Item 3</b></td></tr><tr>
+                            </tr><tr><td colspan="2"><b>Item 2</b></td></tr><tr>
                             <td><b>Real sub-setting</b></td>
                             <td>1.25</td>
                             </tr><tr>
@@ -262,7 +347,22 @@
                             <td>def1</td>
                             </tr><tr>
                             <td><b>Boolean sub-setting</b></td>
-                            <td>false</td>
+                            <td>False</td>
+                            </tr><tr>
+                            <td><b>Selection sub-setting</b></td>
+                            <td>Op1</td>
+                            </tr><tr><td colspan="2"><b>Item 3</b></td></tr><tr>
+                            <td><b>Real sub-setting</b></td>
+                            <td>1.5</td>
+                            </tr><tr>
+                            <td><b>Int sub-setting</b></td>
+                            <td>256</td>
+                            </tr><tr>
+                            <td><b>String sub-setting</b></td>
+                            <td>def2</td>
+                            </tr><tr>
+                            <td><b>Boolean sub-setting</b></td>
+                            <td>False</td>
                             </tr><tr>
                             <td><b>Selection sub-setting</b></td>
                             <td>Op1</td>
@@ -274,25 +374,10 @@
                             <td>256</td>
                             </tr><tr>
                             <td><b>String sub-setting</b></td>
-                            <td>def2</td>
-                            </tr><tr>
-                            <td><b>Boolean sub-setting</b></td>
-                            <td>false</td>
-                            </tr><tr>
-                            <td><b>Selection sub-setting</b></td>
-                            <td>Op1</td>
-                            </tr><tr><td colspan="2"><b>Item 5</b></td></tr><tr>
-                            <td><b>Real sub-setting</b></td>
-                            <td>1.5</td>
-                            </tr><tr>
-                            <td><b>Int sub-setting</b></td>
-                            <td>256</td>
-                            </tr><tr>
-                            <td><b>String sub-setting</b></td>
                             <td>test</td>
                             </tr><tr>
                             <td><b>Boolean sub-setting</b></td>
-                            <td>true</td>
+                            <td>True</td>
                             </tr><tr>
                             <td><b>Selection sub-setting</b></td>
                             <td>Op1</td>
@@ -302,158 +387,79 @@
         <td>
                     <table><tr><td colspan="2"><b>Item 1</b></td></tr><tr>
                             <td><b>Real sub-setting</b></td>
-                            <td>10002.5</td>
-                            </tr><tr>
-                            <td><b>Int sub-setting</b></td>
-                            <td>10002</td>
-                            </tr><tr>
-                            <td><b>String sub-setting</b></td>
-                            <td>test (product, lang 02)</td>
-                            </tr><tr>
-                            <td><b>Boolean sub-setting</b></td>
-                            <td>false</td>
-                            </tr><tr>
-                            <td><b>Selection sub-setting</b></td>
-                            <td>Op1</td>
-                            </tr><tr><td colspan="2"><b>Item 2</b></td></tr><tr>
-                            <td><b>Real sub-setting</b></td>
-                            <td>1.5</td>
-                            </tr><tr>
-                            <td><b>Int sub-setting</b></td>
-                            <td>256</td>
-                            </tr><tr>
-                            <td><b>String sub-setting</b></td>
-                            <td>test (product)</td>
-                            </tr><tr>
-                            <td><b>Boolean sub-setting</b></td>
-                            <td>false</td>
-                            </tr><tr>
-                            <td><b>Selection sub-setting</b></td>
-                            <td>Op1</td>
-                            </tr><tr><td colspan="2"><b>Item 3</b></td></tr><tr>
-                            <td><b>Real sub-setting</b></td>
-                            <td>1.25</td>
+                            <td><b>10003.5</b></td>
                             </tr><tr>
                             <td><b>Int sub-setting</b></td>
-                            <td>128</td>
-                            </tr><tr>
-                            <td><b>String sub-setting</b></td>
-                            <td>def1</td>
-                            </tr><tr>
-                            <td><b>Boolean sub-setting</b></td>
-                            <td>false</td>
-                            </tr><tr>
-                            <td><b>Selection sub-setting</b></td>
-                            <td>Op1</td>
-                            </tr><tr><td colspan="2"><b>Item 4</b></td></tr><tr>
-                            <td><b>Real sub-setting</b></td>
-                            <td>1.5</td>
-                            </tr><tr>
-                            <td><b>Int sub-setting</b></td>
-                            <td>256</td>
+                            <td><b>10003</b></td>
                             </tr><tr>
                             <td><b>String sub-setting</b></td>
-                            <td>def2</td>
+                            <td><b>test (product, lang 03)</b></td>
                             </tr><tr>
                             <td><b>Boolean sub-setting</b></td>
-                            <td>false</td>
+                            <td><b>False</b></td>
                             </tr><tr>
                             <td><b>Selection sub-setting</b></td>
-                            <td>Op1</td>
-                            </tr><tr><td colspan="2"><b>Item 5</b></td></tr><tr>
+                            <td><b>Op1</b></td>
+                            </tr><tr><td colspan="2"><b>Item 2</b></td></tr><tr>
                             <td><b>Real sub-setting</b></td>
-                            <td>1.5</td>
+                            <td><b>1.5</b></td>
                             </tr><tr>
                             <td><b>Int sub-setting</b></td>
-                            <td>256</td>
+                            <td><b>256</b></td>
                             </tr><tr>
                             <td><b>String sub-setting</b></td>
-                            <td>test</td>
+                            <td><b>test (product)</b></td>
                             </tr><tr>
                             <td><b>Boolean sub-setting</b></td>
-                            <td>true</td>
+                            <td><b>False</b></td>
                             </tr><tr>
                             <td><b>Selection sub-setting</b></td>
-                            <td>Op1</td>
-                            </tr></table>
-                </td>
-        
-        <td>
-                    <table><tr><td colspan="2"><b>Item 1</b></td></tr><tr>
+                            <td><b>Op1</b></td>
+                            </tr><tr><td colspan="2"><b>Item 3</b></td></tr><tr>
                             <td><b>Real sub-setting</b></td>
-                            <td>10003.5</td>
+                            <td><b>1.25</b></td>
                             </tr><tr>
                             <td><b>Int sub-setting</b></td>
-                            <td>10003</td>
+                            <td><b>128</b></td>
                             </tr><tr>
                             <td><b>String sub-setting</b></td>
-                            <td>test (product, lang 03)</td>
+                            <td><b>def1</b></td>
                             </tr><tr>
                             <td><b>Boolean sub-setting</b></td>
-                            <td>false</td>
+                            <td><b>False</b></td>
                             </tr><tr>
                             <td><b>Selection sub-setting</b></td>
-                            <td>Op1</td>
-                            </tr><tr><td colspan="2"><b>Item 2</b></td></tr><tr>
+                            <td><b>Op1</b></td>
+                            </tr><tr><td colspan="2"><b>Item 4</b></td></tr><tr>
                             <td><b>Real sub-setting</b></td>
-                            <td>1.5</td>
-                            </tr><tr>
-                            <td><b>Int sub-setting</b></td>
-                            <td>256</td>
-                            </tr><tr>
-                            <td><b>String sub-setting</b></td>
-                            <td>test (product)</td>
-                            </tr><tr>
-                            <td><b>Boolean sub-setting</b></td>
-                            <td>false</td>
-                            </tr><tr>
-                            <td><b>Selection sub-setting</b></td>
-                            <td>Op1</td>
-                            </tr><tr><td colspan="2"><b>Item 3</b></td></tr><tr>
-                            <td><b>Real sub-setting</b></td>
-                            <td>1.25</td>
+                            <td><b>1.5</b></td>
                             </tr><tr>
                             <td><b>Int sub-setting</b></td>
-                            <td>128</td>
-                            </tr><tr>
-                            <td><b>String sub-setting</b></td>
-                            <td>def1</td>
-                            </tr><tr>
-                            <td><b>Boolean sub-setting</b></td>
-                            <td>false</td>
-                            </tr><tr>
-                            <td><b>Selection sub-setting</b></td>
-                            <td>Op1</td>
-                            </tr><tr><td colspan="2"><b>Item 4</b></td></tr><tr>
-                            <td><b>Real sub-setting</b></td>
-                            <td>1.5</td>
-                            </tr><tr>
-                            <td><b>Int sub-setting</b></td>
-                            <td>256</td>
+                            <td><b>256</b></td>
                             </tr><tr>
                             <td><b>String sub-setting</b></td>
-                            <td>def2</td>
+                            <td><b>def2</b></td>
                             </tr><tr>
                             <td><b>Boolean sub-setting</b></td>
-                            <td>false</td>
+                            <td><b>False</b></td>
                             </tr><tr>
                             <td><b>Selection sub-setting</b></td>
-                            <td>Op1</td>
+                            <td><b>Op1</b></td>
                             </tr><tr><td colspan="2"><b>Item 5</b></td></tr><tr>
                             <td><b>Real sub-setting</b></td>
-                            <td>1.5</td>
+                            <td><b>1.5</b></td>
                             </tr><tr>
                             <td><b>Int sub-setting</b></td>
-                            <td>256</td>
+                            <td><b>256</b></td>
                             </tr><tr>
                             <td><b>String sub-setting</b></td>
-                            <td>test</td>
+                            <td><b>test</b></td>
                             </tr><tr>
                             <td><b>Boolean sub-setting</b></td>
-                            <td>true</td>
+                            <td><b>True</b></td>
                             </tr><tr>
                             <td><b>Selection sub-setting</b></td>
-                            <td>Op1</td>
+                            <td><b>Op1</b></td>
                             </tr></table>
                 </td>
         
@@ -538,11 +544,11 @@
         <td></td>
         
         
-        <td>1001</td>
+        <td><b>1001</b></td>
         
-        <td>1002</td>
+        <td><b>1002</b></td>
         
-        <td>1003</td>
+        <td><b>1003</b></td>
         
         
     </tr>
@@ -553,11 +559,11 @@
         <td></td>
         
         
-        <td>langpack 01 string</td>
+        <td><b>langpack 01 string</b></td>
         
-        <td>langpack 02 string</td>
+        <td><b>langpack 02 string</b></td>
         
-        <td>langpack 03 string</td>
+        <td><b>langpack 03 string</b></td>
         
         
     </tr>
@@ -615,7 +621,7 @@
                             <td>def1</td>
                             </tr><tr>
                             <td><b>Boolean sub-setting</b></td>
-                            <td>false</td>
+                            <td>False</td>
                             </tr><tr>
                             <td><b>Selection sub-setting</b></td>
                             <td>Op1</td>
@@ -630,7 +636,7 @@
                             <td>def2</td>
                             </tr><tr>
                             <td><b>Boolean sub-setting</b></td>
-                            <td>false</td>
+                            <td>False</td>
                             </tr><tr>
                             <td><b>Selection sub-setting</b></td>
                             <td>Op1</td>
@@ -649,7 +655,7 @@
                             <td>def1</td>
                             </tr><tr>
                             <td><b>Boolean sub-setting</b></td>
-                            <td>false</td>
+                            <td>False</td>
                             </tr><tr>
                             <td><b>Selection sub-setting</b></td>
                             <td>Op1</td>
@@ -664,7 +670,7 @@
                             <td>def2</td>
                             </tr><tr>
                             <td><b>Boolean sub-setting</b></td>
-                            <td>false</td>
+                            <td>False</td>
                             </tr><tr>
                             <td><b>Selection sub-setting</b></td>
                             <td>Op1</td>
@@ -683,7 +689,7 @@
                             <td>def1</td>
                             </tr><tr>
                             <td><b>Boolean sub-setting</b></td>
-                            <td>false</td>
+                            <td>False</td>
                             </tr><tr>
                             <td><b>Selection sub-setting</b></td>
                             <td>Op1</td>
@@ -698,7 +704,7 @@
                             <td>def2</td>
                             </tr><tr>
                             <td><b>Boolean sub-setting</b></td>
-                            <td>false</td>
+                            <td>False</td>
                             </tr><tr>
                             <td><b>Selection sub-setting</b></td>
                             <td>Op1</td>
@@ -767,6 +773,11 @@
     
     
     </table>
+    <script language="javascript" type="text/javascript">
+//<![CDATA[
+    setFilterGrid("report_data");
+//]]>
+</script>
 </div>
 <div id="footer"></div>
 </body>
--- a/configurationengine/source/scripts/tests/testdata/info/expected/value_report_multi_mixed.html	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/tests/testdata/info/expected/value_report_multi_mixed.html	Tue Aug 10 14:29:28 2010 +0300
@@ -110,7 +110,28 @@
     .currentValue {
         background-color: #e8f2fe;
     }
+
+.fltrow{ /* filter grid row appearance */
+    height:20px;
+    background-color:#f4f4f4;
+}
+.btnflt{ /* button appearance */
+    font-size:11px;
+    margin:0 2px 0 2px; padding:0 1px 0 1px;
+    text-decoration:none; color: #fff;
+    background-color:#666;
+}
+.flt{ /* filter (input) appearance */
+    background-color:#f4f4f4; border:1px inset #ccc; 
+    margin:0; width:100%;
+}
+.flt_s{ /* small filter (input) appearance */
+    background-color:#f4f4f4; border:1px inset #ccc; 
+    margin:0; width:80%;
+}
+
 </style>
+<script language="javascript" type="text/javascript" src="http://www.javascriptkit.com/script/script2/tablefilter.js"></script>
 <title>Data value info - ConE</title>
 
 </head>
@@ -118,25 +139,25 @@
 <div id="content">
     <h1>Configuration data value info</h1><br>
 
-    <table class="report">
+    <table class="report" id="report_data">
     <tr>
         <th class="featureName">Name</th>
         <th class="featureName">Type</th>
         <th class="featureName">Possible values</th>
         
-        <th class="featureName">product_root.confml</th>
+        <th class="featureName">Some Product X (product_root.confml)</th>
         
-        <th class="featureName">product_langpack_01_root.confml</th>
+        <th class="featureName">Lang 1 (product_langpack_01_root.confml)</th>
         
         <th class="featureName">product_langpack_02_root.confml</th>
         
-        <th class="featureName">product_langpack_03_root.confml</th>
+        <th class="featureName">Lang 3 (product_langpack_03_root.confml)</th>
         
     </tr>
     
     <tr><th colspan="7">All settings</th></tr>
     
-    <tr>
+    <tr bgcolor="#CCCCFF">
         <td>Real setting</td>
         <td>real</td>
         <td></td>
@@ -146,7 +167,7 @@
         
         <td>3.14</td>
         
-        <td>3.14</td>
+        <td><b>2.5</b></td>
         
         <td>3.14</td>
         
@@ -176,13 +197,13 @@
         <td></td>
         
         
+        <td><b>string from product config</b></td>
+        
+        <td><b>string from product (langpack 01) config</b></td>
+        
         <td>string from product config</td>
         
-        <td>string from product (langpack 01) config</td>
-        
-        <td>string from product (langpack 02) config</td>
-        
-        <td>string from product (langpack 03) config</td>
+        <td><b>string from product (langpack 03) config</b></td>
         
         
     </tr>
@@ -235,6 +256,149 @@
         <td>
                     <table><tr><td colspan="2"><b>Item 1</b></td></tr><tr>
                             <td><b>Real sub-setting</b></td>
+                            <td><b>1.5</b></td>
+                            </tr><tr>
+                            <td><b>Int sub-setting</b></td>
+                            <td><b>256</b></td>
+                            </tr><tr>
+                            <td><b>String sub-setting</b></td>
+                            <td><b>test (product)</b></td>
+                            </tr><tr>
+                            <td><b>Boolean sub-setting</b></td>
+                            <td><b>False</b></td>
+                            </tr><tr>
+                            <td><b>Selection sub-setting</b></td>
+                            <td><b>Op1</b></td>
+                            </tr><tr><td colspan="2"><b>Item 2</b></td></tr><tr>
+                            <td><b>Real sub-setting</b></td>
+                            <td><b>1.25</b></td>
+                            </tr><tr>
+                            <td><b>Int sub-setting</b></td>
+                            <td><b>128</b></td>
+                            </tr><tr>
+                            <td><b>String sub-setting</b></td>
+                            <td><b>def1</b></td>
+                            </tr><tr>
+                            <td><b>Boolean sub-setting</b></td>
+                            <td><b>False</b></td>
+                            </tr><tr>
+                            <td><b>Selection sub-setting</b></td>
+                            <td><b>Op1</b></td>
+                            </tr><tr><td colspan="2"><b>Item 3</b></td></tr><tr>
+                            <td><b>Real sub-setting</b></td>
+                            <td><b>1.5</b></td>
+                            </tr><tr>
+                            <td><b>Int sub-setting</b></td>
+                            <td><b>256</b></td>
+                            </tr><tr>
+                            <td><b>String sub-setting</b></td>
+                            <td><b>def2</b></td>
+                            </tr><tr>
+                            <td><b>Boolean sub-setting</b></td>
+                            <td><b>False</b></td>
+                            </tr><tr>
+                            <td><b>Selection sub-setting</b></td>
+                            <td><b>Op1</b></td>
+                            </tr><tr><td colspan="2"><b>Item 4</b></td></tr><tr>
+                            <td><b>Real sub-setting</b></td>
+                            <td><b>1.5</b></td>
+                            </tr><tr>
+                            <td><b>Int sub-setting</b></td>
+                            <td><b>256</b></td>
+                            </tr><tr>
+                            <td><b>String sub-setting</b></td>
+                            <td><b>test</b></td>
+                            </tr><tr>
+                            <td><b>Boolean sub-setting</b></td>
+                            <td><b>True</b></td>
+                            </tr><tr>
+                            <td><b>Selection sub-setting</b></td>
+                            <td><b>Op1</b></td>
+                            </tr></table>
+                </td>
+        
+        <td>
+                    <table><tr><td colspan="2"><b>Item 1</b></td></tr><tr>
+                            <td><b>Real sub-setting</b></td>
+                            <td><b>10001.5</b></td>
+                            </tr><tr>
+                            <td><b>Int sub-setting</b></td>
+                            <td><b>10001</b></td>
+                            </tr><tr>
+                            <td><b>String sub-setting</b></td>
+                            <td><b>test (product, lang 01)</b></td>
+                            </tr><tr>
+                            <td><b>Boolean sub-setting</b></td>
+                            <td><b>False</b></td>
+                            </tr><tr>
+                            <td><b>Selection sub-setting</b></td>
+                            <td><b>Op1</b></td>
+                            </tr><tr><td colspan="2"><b>Item 2</b></td></tr><tr>
+                            <td><b>Real sub-setting</b></td>
+                            <td><b>1.5</b></td>
+                            </tr><tr>
+                            <td><b>Int sub-setting</b></td>
+                            <td><b>256</b></td>
+                            </tr><tr>
+                            <td><b>String sub-setting</b></td>
+                            <td><b>test (product)</b></td>
+                            </tr><tr>
+                            <td><b>Boolean sub-setting</b></td>
+                            <td><b>False</b></td>
+                            </tr><tr>
+                            <td><b>Selection sub-setting</b></td>
+                            <td><b>Op1</b></td>
+                            </tr><tr><td colspan="2"><b>Item 3</b></td></tr><tr>
+                            <td><b>Real sub-setting</b></td>
+                            <td><b>1.25</b></td>
+                            </tr><tr>
+                            <td><b>Int sub-setting</b></td>
+                            <td><b>128</b></td>
+                            </tr><tr>
+                            <td><b>String sub-setting</b></td>
+                            <td><b>def1</b></td>
+                            </tr><tr>
+                            <td><b>Boolean sub-setting</b></td>
+                            <td><b>False</b></td>
+                            </tr><tr>
+                            <td><b>Selection sub-setting</b></td>
+                            <td><b>Op1</b></td>
+                            </tr><tr><td colspan="2"><b>Item 4</b></td></tr><tr>
+                            <td><b>Real sub-setting</b></td>
+                            <td><b>1.5</b></td>
+                            </tr><tr>
+                            <td><b>Int sub-setting</b></td>
+                            <td><b>256</b></td>
+                            </tr><tr>
+                            <td><b>String sub-setting</b></td>
+                            <td><b>def2</b></td>
+                            </tr><tr>
+                            <td><b>Boolean sub-setting</b></td>
+                            <td><b>False</b></td>
+                            </tr><tr>
+                            <td><b>Selection sub-setting</b></td>
+                            <td><b>Op1</b></td>
+                            </tr><tr><td colspan="2"><b>Item 5</b></td></tr><tr>
+                            <td><b>Real sub-setting</b></td>
+                            <td><b>1.5</b></td>
+                            </tr><tr>
+                            <td><b>Int sub-setting</b></td>
+                            <td><b>256</b></td>
+                            </tr><tr>
+                            <td><b>String sub-setting</b></td>
+                            <td><b>test</b></td>
+                            </tr><tr>
+                            <td><b>Boolean sub-setting</b></td>
+                            <td><b>True</b></td>
+                            </tr><tr>
+                            <td><b>Selection sub-setting</b></td>
+                            <td><b>Op1</b></td>
+                            </tr></table>
+                </td>
+        
+        <td>
+                    <table><tr><td colspan="2"><b>Item 1</b></td></tr><tr>
+                            <td><b>Real sub-setting</b></td>
                             <td>1.5</td>
                             </tr><tr>
                             <td><b>Int sub-setting</b></td>
@@ -244,7 +408,7 @@
                             <td>test (product)</td>
                             </tr><tr>
                             <td><b>Boolean sub-setting</b></td>
-                            <td>false</td>
+                            <td>False</td>
                             </tr><tr>
                             <td><b>Selection sub-setting</b></td>
                             <td>Op1</td>
@@ -259,7 +423,7 @@
                             <td>def1</td>
                             </tr><tr>
                             <td><b>Boolean sub-setting</b></td>
-                            <td>false</td>
+                            <td>False</td>
                             </tr><tr>
                             <td><b>Selection sub-setting</b></td>
                             <td>Op1</td>
@@ -274,7 +438,7 @@
                             <td>def2</td>
                             </tr><tr>
                             <td><b>Boolean sub-setting</b></td>
-                            <td>false</td>
+                            <td>False</td>
                             </tr><tr>
                             <td><b>Selection sub-setting</b></td>
                             <td>Op1</td>
@@ -289,86 +453,7 @@
                             <td>test</td>
                             </tr><tr>
                             <td><b>Boolean sub-setting</b></td>
-                            <td>true</td>
-                            </tr><tr>
-                            <td><b>Selection sub-setting</b></td>
-                            <td>Op1</td>
-                            </tr></table>
-                </td>
-        
-        <td>
-                    <table><tr><td colspan="2"><b>Item 1</b></td></tr><tr>
-                            <td><b>Real sub-setting</b></td>
-                            <td>10001.5</td>
-                            </tr><tr>
-                            <td><b>Int sub-setting</b></td>
-                            <td>10001</td>
-                            </tr><tr>
-                            <td><b>String sub-setting</b></td>
-                            <td>test (product, lang 01)</td>
-                            </tr><tr>
-                            <td><b>Boolean sub-setting</b></td>
-                            <td>false</td>
-                            </tr><tr>
-                            <td><b>Selection sub-setting</b></td>
-                            <td>Op1</td>
-                            </tr><tr><td colspan="2"><b>Item 2</b></td></tr><tr>
-                            <td><b>Real sub-setting</b></td>
-                            <td>1.5</td>
-                            </tr><tr>
-                            <td><b>Int sub-setting</b></td>
-                            <td>256</td>
-                            </tr><tr>
-                            <td><b>String sub-setting</b></td>
-                            <td>test (product)</td>
-                            </tr><tr>
-                            <td><b>Boolean sub-setting</b></td>
-                            <td>false</td>
-                            </tr><tr>
-                            <td><b>Selection sub-setting</b></td>
-                            <td>Op1</td>
-                            </tr><tr><td colspan="2"><b>Item 3</b></td></tr><tr>
-                            <td><b>Real sub-setting</b></td>
-                            <td>1.25</td>
-                            </tr><tr>
-                            <td><b>Int sub-setting</b></td>
-                            <td>128</td>
-                            </tr><tr>
-                            <td><b>String sub-setting</b></td>
-                            <td>def1</td>
-                            </tr><tr>
-                            <td><b>Boolean sub-setting</b></td>
-                            <td>false</td>
-                            </tr><tr>
-                            <td><b>Selection sub-setting</b></td>
-                            <td>Op1</td>
-                            </tr><tr><td colspan="2"><b>Item 4</b></td></tr><tr>
-                            <td><b>Real sub-setting</b></td>
-                            <td>1.5</td>
-                            </tr><tr>
-                            <td><b>Int sub-setting</b></td>
-                            <td>256</td>
-                            </tr><tr>
-                            <td><b>String sub-setting</b></td>
-                            <td>def2</td>
-                            </tr><tr>
-                            <td><b>Boolean sub-setting</b></td>
-                            <td>false</td>
-                            </tr><tr>
-                            <td><b>Selection sub-setting</b></td>
-                            <td>Op1</td>
-                            </tr><tr><td colspan="2"><b>Item 5</b></td></tr><tr>
-                            <td><b>Real sub-setting</b></td>
-                            <td>1.5</td>
-                            </tr><tr>
-                            <td><b>Int sub-setting</b></td>
-                            <td>256</td>
-                            </tr><tr>
-                            <td><b>String sub-setting</b></td>
-                            <td>test</td>
-                            </tr><tr>
-                            <td><b>Boolean sub-setting</b></td>
-                            <td>true</td>
+                            <td>True</td>
                             </tr><tr>
                             <td><b>Selection sub-setting</b></td>
                             <td>Op1</td>
@@ -378,158 +463,79 @@
         <td>
                     <table><tr><td colspan="2"><b>Item 1</b></td></tr><tr>
                             <td><b>Real sub-setting</b></td>
-                            <td>10002.5</td>
-                            </tr><tr>
-                            <td><b>Int sub-setting</b></td>
-                            <td>10002</td>
-                            </tr><tr>
-                            <td><b>String sub-setting</b></td>
-                            <td>test (product, lang 02)</td>
-                            </tr><tr>
-                            <td><b>Boolean sub-setting</b></td>
-                            <td>false</td>
-                            </tr><tr>
-                            <td><b>Selection sub-setting</b></td>
-                            <td>Op1</td>
-                            </tr><tr><td colspan="2"><b>Item 2</b></td></tr><tr>
-                            <td><b>Real sub-setting</b></td>
-                            <td>1.5</td>
-                            </tr><tr>
-                            <td><b>Int sub-setting</b></td>
-                            <td>256</td>
-                            </tr><tr>
-                            <td><b>String sub-setting</b></td>
-                            <td>test (product)</td>
-                            </tr><tr>
-                            <td><b>Boolean sub-setting</b></td>
-                            <td>false</td>
-                            </tr><tr>
-                            <td><b>Selection sub-setting</b></td>
-                            <td>Op1</td>
-                            </tr><tr><td colspan="2"><b>Item 3</b></td></tr><tr>
-                            <td><b>Real sub-setting</b></td>
-                            <td>1.25</td>
+                            <td><b>10003.5</b></td>
                             </tr><tr>
                             <td><b>Int sub-setting</b></td>
-                            <td>128</td>
-                            </tr><tr>
-                            <td><b>String sub-setting</b></td>
-                            <td>def1</td>
-                            </tr><tr>
-                            <td><b>Boolean sub-setting</b></td>
-                            <td>false</td>
-                            </tr><tr>
-                            <td><b>Selection sub-setting</b></td>
-                            <td>Op1</td>
-                            </tr><tr><td colspan="2"><b>Item 4</b></td></tr><tr>
-                            <td><b>Real sub-setting</b></td>
-                            <td>1.5</td>
-                            </tr><tr>
-                            <td><b>Int sub-setting</b></td>
-                            <td>256</td>
+                            <td><b>10003</b></td>
                             </tr><tr>
                             <td><b>String sub-setting</b></td>
-                            <td>def2</td>
+                            <td><b>test (product, lang 03)</b></td>
                             </tr><tr>
                             <td><b>Boolean sub-setting</b></td>
-                            <td>false</td>
+                            <td><b>False</b></td>
                             </tr><tr>
                             <td><b>Selection sub-setting</b></td>
-                            <td>Op1</td>
-                            </tr><tr><td colspan="2"><b>Item 5</b></td></tr><tr>
+                            <td><b>Op1</b></td>
+                            </tr><tr><td colspan="2"><b>Item 2</b></td></tr><tr>
                             <td><b>Real sub-setting</b></td>
-                            <td>1.5</td>
+                            <td><b>1.5</b></td>
                             </tr><tr>
                             <td><b>Int sub-setting</b></td>
-                            <td>256</td>
+                            <td><b>256</b></td>
                             </tr><tr>
                             <td><b>String sub-setting</b></td>
-                            <td>test</td>
+                            <td><b>test (product)</b></td>
                             </tr><tr>
                             <td><b>Boolean sub-setting</b></td>
-                            <td>true</td>
+                            <td><b>False</b></td>
                             </tr><tr>
                             <td><b>Selection sub-setting</b></td>
-                            <td>Op1</td>
-                            </tr></table>
-                </td>
-        
-        <td>
-                    <table><tr><td colspan="2"><b>Item 1</b></td></tr><tr>
+                            <td><b>Op1</b></td>
+                            </tr><tr><td colspan="2"><b>Item 3</b></td></tr><tr>
                             <td><b>Real sub-setting</b></td>
-                            <td>10003.5</td>
+                            <td><b>1.25</b></td>
                             </tr><tr>
                             <td><b>Int sub-setting</b></td>
-                            <td>10003</td>
+                            <td><b>128</b></td>
                             </tr><tr>
                             <td><b>String sub-setting</b></td>
-                            <td>test (product, lang 03)</td>
+                            <td><b>def1</b></td>
                             </tr><tr>
                             <td><b>Boolean sub-setting</b></td>
-                            <td>false</td>
+                            <td><b>False</b></td>
                             </tr><tr>
                             <td><b>Selection sub-setting</b></td>
-                            <td>Op1</td>
-                            </tr><tr><td colspan="2"><b>Item 2</b></td></tr><tr>
+                            <td><b>Op1</b></td>
+                            </tr><tr><td colspan="2"><b>Item 4</b></td></tr><tr>
                             <td><b>Real sub-setting</b></td>
-                            <td>1.5</td>
-                            </tr><tr>
-                            <td><b>Int sub-setting</b></td>
-                            <td>256</td>
-                            </tr><tr>
-                            <td><b>String sub-setting</b></td>
-                            <td>test (product)</td>
-                            </tr><tr>
-                            <td><b>Boolean sub-setting</b></td>
-                            <td>false</td>
-                            </tr><tr>
-                            <td><b>Selection sub-setting</b></td>
-                            <td>Op1</td>
-                            </tr><tr><td colspan="2"><b>Item 3</b></td></tr><tr>
-                            <td><b>Real sub-setting</b></td>
-                            <td>1.25</td>
+                            <td><b>1.5</b></td>
                             </tr><tr>
                             <td><b>Int sub-setting</b></td>
-                            <td>128</td>
-                            </tr><tr>
-                            <td><b>String sub-setting</b></td>
-                            <td>def1</td>
-                            </tr><tr>
-                            <td><b>Boolean sub-setting</b></td>
-                            <td>false</td>
-                            </tr><tr>
-                            <td><b>Selection sub-setting</b></td>
-                            <td>Op1</td>
-                            </tr><tr><td colspan="2"><b>Item 4</b></td></tr><tr>
-                            <td><b>Real sub-setting</b></td>
-                            <td>1.5</td>
-                            </tr><tr>
-                            <td><b>Int sub-setting</b></td>
-                            <td>256</td>
+                            <td><b>256</b></td>
                             </tr><tr>
                             <td><b>String sub-setting</b></td>
-                            <td>def2</td>
+                            <td><b>def2</b></td>
                             </tr><tr>
                             <td><b>Boolean sub-setting</b></td>
-                            <td>false</td>
+                            <td><b>False</b></td>
                             </tr><tr>
                             <td><b>Selection sub-setting</b></td>
-                            <td>Op1</td>
+                            <td><b>Op1</b></td>
                             </tr><tr><td colspan="2"><b>Item 5</b></td></tr><tr>
                             <td><b>Real sub-setting</b></td>
-                            <td>1.5</td>
+                            <td><b>1.5</b></td>
                             </tr><tr>
                             <td><b>Int sub-setting</b></td>
-                            <td>256</td>
+                            <td><b>256</b></td>
                             </tr><tr>
                             <td><b>String sub-setting</b></td>
-                            <td>test</td>
+                            <td><b>test</b></td>
                             </tr><tr>
                             <td><b>Boolean sub-setting</b></td>
-                            <td>true</td>
+                            <td><b>True</b></td>
                             </tr><tr>
                             <td><b>Selection sub-setting</b></td>
-                            <td>Op1</td>
+                            <td><b>Op1</b></td>
                             </tr></table>
                 </td>
         
@@ -632,13 +638,13 @@
         <td></td>
         
         
-        <td>1200</td>
+        <td><b>1200</b></td>
         
-        <td>1001</td>
+        <td><b>1001</b></td>
         
-        <td>1002</td>
+        <td><b>1002</b></td>
         
-        <td>1003</td>
+        <td><b>1003</b></td>
         
         
     </tr>
@@ -651,11 +657,11 @@
         
         <td>default string</td>
         
-        <td>langpack 01 string</td>
+        <td><b>langpack 01 string</b></td>
         
-        <td>langpack 02 string</td>
+        <td><b>langpack 02 string</b></td>
         
-        <td>langpack 03 string</td>
+        <td><b>langpack 03 string</b></td>
         
         
     </tr>
@@ -717,7 +723,7 @@
                             <td>def1</td>
                             </tr><tr>
                             <td><b>Boolean sub-setting</b></td>
-                            <td>false</td>
+                            <td>False</td>
                             </tr><tr>
                             <td><b>Selection sub-setting</b></td>
                             <td>Op1</td>
@@ -732,7 +738,7 @@
                             <td>def2</td>
                             </tr><tr>
                             <td><b>Boolean sub-setting</b></td>
-                            <td>false</td>
+                            <td>False</td>
                             </tr><tr>
                             <td><b>Selection sub-setting</b></td>
                             <td>Op1</td>
@@ -751,7 +757,7 @@
                             <td>def1</td>
                             </tr><tr>
                             <td><b>Boolean sub-setting</b></td>
-                            <td>false</td>
+                            <td>False</td>
                             </tr><tr>
                             <td><b>Selection sub-setting</b></td>
                             <td>Op1</td>
@@ -766,7 +772,7 @@
                             <td>def2</td>
                             </tr><tr>
                             <td><b>Boolean sub-setting</b></td>
-                            <td>false</td>
+                            <td>False</td>
                             </tr><tr>
                             <td><b>Selection sub-setting</b></td>
                             <td>Op1</td>
@@ -785,7 +791,7 @@
                             <td>def1</td>
                             </tr><tr>
                             <td><b>Boolean sub-setting</b></td>
-                            <td>false</td>
+                            <td>False</td>
                             </tr><tr>
                             <td><b>Selection sub-setting</b></td>
                             <td>Op1</td>
@@ -800,7 +806,7 @@
                             <td>def2</td>
                             </tr><tr>
                             <td><b>Boolean sub-setting</b></td>
-                            <td>false</td>
+                            <td>False</td>
                             </tr><tr>
                             <td><b>Selection sub-setting</b></td>
                             <td>Op1</td>
@@ -819,7 +825,7 @@
                             <td>def1</td>
                             </tr><tr>
                             <td><b>Boolean sub-setting</b></td>
-                            <td>false</td>
+                            <td>False</td>
                             </tr><tr>
                             <td><b>Selection sub-setting</b></td>
                             <td>Op1</td>
@@ -834,7 +840,7 @@
                             <td>def2</td>
                             </tr><tr>
                             <td><b>Boolean sub-setting</b></td>
-                            <td>false</td>
+                            <td>False</td>
                             </tr><tr>
                             <td><b>Selection sub-setting</b></td>
                             <td>Op1</td>
@@ -919,6 +925,11 @@
     
     
     </table>
+    <script language="javascript" type="text/javascript">
+//<![CDATA[
+    setFilterGrid("report_data");
+//]]>
+</script>
 </div>
 <div id="footer"></div>
 </body>
--- a/configurationengine/source/scripts/tests/testdata/info/expected/value_report_single.html	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/tests/testdata/info/expected/value_report_single.html	Tue Aug 10 14:29:28 2010 +0300
@@ -110,7 +110,28 @@
     .currentValue {
         background-color: #e8f2fe;
     }
+
+.fltrow{ /* filter grid row appearance */
+    height:20px;
+    background-color:#f4f4f4;
+}
+.btnflt{ /* button appearance */
+    font-size:11px;
+    margin:0 2px 0 2px; padding:0 1px 0 1px;
+    text-decoration:none; color: #fff;
+    background-color:#666;
+}
+.flt{ /* filter (input) appearance */
+    background-color:#f4f4f4; border:1px inset #ccc; 
+    margin:0; width:100%;
+}
+.flt_s{ /* small filter (input) appearance */
+    background-color:#f4f4f4; border:1px inset #ccc; 
+    margin:0; width:80%;
+}
+
 </style>
+<script language="javascript" type="text/javascript" src="http://www.javascriptkit.com/script/script2/tablefilter.js"></script>
 <title>Data value info - ConE</title>
 
 </head>
@@ -118,13 +139,13 @@
 <div id="content">
     <h1>Configuration data value info</h1><br>
 
-    <table class="report">
+    <table class="report" id="report_data">
     <tr>
         <th class="featureName">Name</th>
         <th class="featureName">Type</th>
         <th class="featureName">Possible values</th>
         
-        <th class="featureName">product_root.confml</th>
+        <th class="featureName">Some Product X (product_root.confml)</th>
         
     </tr>
     
@@ -158,7 +179,7 @@
         <td></td>
         
         
-        <td>string from product config</td>
+        <td><b>string from product config</b></td>
         
         
     </tr>
@@ -199,64 +220,64 @@
         <td>
                     <table><tr><td colspan="2"><b>Item 1</b></td></tr><tr>
                             <td><b>Real sub-setting</b></td>
-                            <td>1.5</td>
+                            <td><b>1.5</b></td>
                             </tr><tr>
                             <td><b>Int sub-setting</b></td>
-                            <td>256</td>
+                            <td><b>256</b></td>
                             </tr><tr>
                             <td><b>String sub-setting</b></td>
-                            <td>test (product)</td>
+                            <td><b>test (product)</b></td>
                             </tr><tr>
                             <td><b>Boolean sub-setting</b></td>
-                            <td>false</td>
+                            <td><b>False</b></td>
                             </tr><tr>
                             <td><b>Selection sub-setting</b></td>
-                            <td>Op1</td>
+                            <td><b>Op1</b></td>
                             </tr><tr><td colspan="2"><b>Item 2</b></td></tr><tr>
                             <td><b>Real sub-setting</b></td>
-                            <td>1.25</td>
+                            <td><b>1.25</b></td>
                             </tr><tr>
                             <td><b>Int sub-setting</b></td>
-                            <td>128</td>
+                            <td><b>128</b></td>
                             </tr><tr>
                             <td><b>String sub-setting</b></td>
-                            <td>def1</td>
+                            <td><b>def1</b></td>
                             </tr><tr>
                             <td><b>Boolean sub-setting</b></td>
-                            <td>false</td>
+                            <td><b>False</b></td>
                             </tr><tr>
                             <td><b>Selection sub-setting</b></td>
-                            <td>Op1</td>
+                            <td><b>Op1</b></td>
                             </tr><tr><td colspan="2"><b>Item 3</b></td></tr><tr>
                             <td><b>Real sub-setting</b></td>
-                            <td>1.5</td>
+                            <td><b>1.5</b></td>
                             </tr><tr>
                             <td><b>Int sub-setting</b></td>
-                            <td>256</td>
+                            <td><b>256</b></td>
                             </tr><tr>
                             <td><b>String sub-setting</b></td>
-                            <td>def2</td>
+                            <td><b>def2</b></td>
                             </tr><tr>
                             <td><b>Boolean sub-setting</b></td>
-                            <td>false</td>
+                            <td><b>False</b></td>
                             </tr><tr>
                             <td><b>Selection sub-setting</b></td>
-                            <td>Op1</td>
+                            <td><b>Op1</b></td>
                             </tr><tr><td colspan="2"><b>Item 4</b></td></tr><tr>
                             <td><b>Real sub-setting</b></td>
-                            <td>1.5</td>
+                            <td><b>1.5</b></td>
                             </tr><tr>
                             <td><b>Int sub-setting</b></td>
-                            <td>256</td>
+                            <td><b>256</b></td>
                             </tr><tr>
                             <td><b>String sub-setting</b></td>
-                            <td>test</td>
+                            <td><b>test</b></td>
                             </tr><tr>
                             <td><b>Boolean sub-setting</b></td>
-                            <td>true</td>
+                            <td><b>True</b></td>
                             </tr><tr>
                             <td><b>Selection sub-setting</b></td>
-                            <td>Op1</td>
+                            <td><b>Op1</b></td>
                             </tr></table>
                 </td>
         
@@ -305,7 +326,7 @@
         <td></td>
         
         
-        <td>1200</td>
+        <td><b>1200</b></td>
         
         
     </tr>
@@ -366,7 +387,7 @@
                             <td>def1</td>
                             </tr><tr>
                             <td><b>Boolean sub-setting</b></td>
-                            <td>false</td>
+                            <td>False</td>
                             </tr><tr>
                             <td><b>Selection sub-setting</b></td>
                             <td>Op1</td>
@@ -381,7 +402,7 @@
                             <td>def2</td>
                             </tr><tr>
                             <td><b>Boolean sub-setting</b></td>
-                            <td>false</td>
+                            <td>False</td>
                             </tr><tr>
                             <td><b>Selection sub-setting</b></td>
                             <td>Op1</td>
@@ -418,6 +439,11 @@
     
     
     </table>
+    <script language="javascript" type="text/javascript">
+//<![CDATA[
+    setFilterGrid("report_data");
+//]]>
+</script>
 </div>
 <div id="footer"></div>
 </body>
--- a/configurationengine/source/scripts/tests/testdata/info/expected/value_report_single_with_view.html	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/tests/testdata/info/expected/value_report_single_with_view.html	Tue Aug 10 14:29:28 2010 +0300
@@ -110,7 +110,28 @@
     .currentValue {
         background-color: #e8f2fe;
     }
+
+.fltrow{ /* filter grid row appearance */
+    height:20px;
+    background-color:#f4f4f4;
+}
+.btnflt{ /* button appearance */
+    font-size:11px;
+    margin:0 2px 0 2px; padding:0 1px 0 1px;
+    text-decoration:none; color: #fff;
+    background-color:#666;
+}
+.flt{ /* filter (input) appearance */
+    background-color:#f4f4f4; border:1px inset #ccc; 
+    margin:0; width:100%;
+}
+.flt_s{ /* small filter (input) appearance */
+    background-color:#f4f4f4; border:1px inset #ccc; 
+    margin:0; width:80%;
+}
+
 </style>
+<script language="javascript" type="text/javascript" src="http://www.javascriptkit.com/script/script2/tablefilter.js"></script>
 <title>Data value info - ConE</title>
 
 </head>
@@ -118,13 +139,13 @@
 <div id="content">
     <h1>Configuration data value info</h1><br>
 
-    <table class="report">
+    <table class="report" id="report_data">
     <tr>
         <th class="featureName">Name</th>
         <th class="featureName">Type</th>
         <th class="featureName">Possible values</th>
         
-        <th class="featureName">product_root.confml</th>
+        <th class="featureName">Some Product X (product_root.confml)</th>
         
     </tr>
     
@@ -189,7 +210,7 @@
         <td></td>
         
         
-        <td>string from product config</td>
+        <td><b>string from product config</b></td>
         
         
     </tr>
@@ -213,7 +234,7 @@
         <td></td>
         
         
-        <td>1200</td>
+        <td><b>1200</b></td>
         
         
     </tr>
@@ -274,6 +295,11 @@
     
     
     </table>
+    <script language="javascript" type="text/javascript">
+//<![CDATA[
+    setFilterGrid("report_data");
+//]]>
+</script>
 </div>
 <div id="footer"></div>
 </body>
--- a/configurationengine/source/scripts/tests/testdata/info/expected/value_report_special_chars.csv	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/tests/testdata/info/expected/value_report_special_chars.csv	Tue Aug 10 14:29:28 2010 +0300
@@ -1,4 +1,4 @@
-Name,Type,Possible values,csv_test_root.confml,
+Name,Type,Possible values,Some Variant Y (csv_test_root.confml),
 
 All settings
 Real setting,real,"",3.14,
Binary file configurationengine/source/scripts/tests/testdata/info/no_active_root.cpf has changed
--- a/configurationengine/source/scripts/tests/testdata/info/value_report_project/asset1_root.confml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/tests/testdata/info/value_report_project/asset1_root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="ASCII"?>
-<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2 http://www.w3.org/2001/XInclude http://www.s60.com/xml/confml/1#//include">
+<confml:configuration name="Asset1 Name" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2 http://www.w3.org/2001/XInclude http://www.s60.com/xml/confml/1#//include">
   <xi:include href="assets/asset1/root.confml"/>
 </confml:configuration>
\ No newline at end of file
--- a/configurationengine/source/scripts/tests/testdata/info/value_report_project/asset2_root.confml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/tests/testdata/info/value_report_project/asset2_root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="ASCII"?>
-<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2 http://www.w3.org/2001/XInclude http://www.s60.com/xml/confml/1#//include">
+<confml:configuration name="Asset2 Name" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2 http://www.w3.org/2001/XInclude http://www.s60.com/xml/confml/1#//include">
   <xi:include href="assets/asset2/root.confml"/>
 </confml:configuration>
\ No newline at end of file
--- a/configurationengine/source/scripts/tests/testdata/info/value_report_project/csv_test_root.confml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/tests/testdata/info/value_report_project/csv_test_root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="ASCII"?>
-<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2 http://www.w3.org/2001/XInclude http://www.s60.com/xml/confml/1#//include">
+<confml:configuration name="Some Variant Y" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2 http://www.w3.org/2001/XInclude http://www.s60.com/xml/confml/1#//include">
   <xi:include href="assets/asset1/root.confml"/>
   <xi:include href="assets/asset2/root.confml"/>
   <xi:include href="family/root.confml"/>
--- a/configurationengine/source/scripts/tests/testdata/info/value_report_project/family_root.confml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/tests/testdata/info/value_report_project/family_root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="ASCII"?>
-<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2 http://www.w3.org/2001/XInclude http://www.s60.com/xml/confml/1#//include">
+<confml:configuration name="Some Family X" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2 http://www.w3.org/2001/XInclude http://www.s60.com/xml/confml/1#//include">
   <xi:include href="assets/asset1/root.confml"/>
   <xi:include href="assets/asset2/root.confml"/>
   <xi:include href="family/root.confml"/>
--- a/configurationengine/source/scripts/tests/testdata/info/value_report_project/product/language/langpack_02/confml/data.confml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/tests/testdata/info/value_report_project/product/language/langpack_02/confml/data.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -2,15 +2,7 @@
 <configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.s60.com/xml/confml/2" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2" name="data">
     <data>
         <Asset1Feature1>
-            <StringSetting>string from product (langpack 02) config</StringSetting>
-            
-            <SequenceSetting extensionPolicy="prefix">
-                <RealSubSetting>10002.5</RealSubSetting>
-                <IntSubSetting>10002</IntSubSetting>
-                <StringSubSetting>test (product, lang 02)</StringSubSetting>
-                <BooleanSubSetting>false</BooleanSubSetting>
-                <SelectionSubSetting>1</SelectionSubSetting>
-            </SequenceSetting>
+            <RealSetting>2.5</RealSetting>
         </Asset1Feature1>
         
         <Asset2Feature1>
--- a/configurationengine/source/scripts/tests/testdata/info/value_report_project/product_langpack_01_root.confml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/tests/testdata/info/value_report_project/product_langpack_01_root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="ASCII"?>
-<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2 http://www.w3.org/2001/XInclude http://www.s60.com/xml/confml/1#//include">
+<confml:configuration name="Lang 1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2 http://www.w3.org/2001/XInclude http://www.s60.com/xml/confml/1#//include">
   <xi:include href="assets/asset1/root.confml"/>
   <xi:include href="assets/asset2/root.confml"/>
   <xi:include href="family/root.confml"/>
--- a/configurationengine/source/scripts/tests/testdata/info/value_report_project/product_langpack_03_root.confml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/tests/testdata/info/value_report_project/product_langpack_03_root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="ASCII"?>
-<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2 http://www.w3.org/2001/XInclude http://www.s60.com/xml/confml/1#//include">
+<confml:configuration name="Lang 3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2 http://www.w3.org/2001/XInclude http://www.s60.com/xml/confml/1#//include">
   <xi:include href="assets/asset1/root.confml"/>
   <xi:include href="assets/asset2/root.confml"/>
   <xi:include href="family/root.confml"/>
--- a/configurationengine/source/scripts/tests/testdata/info/value_report_project/product_root.confml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/tests/testdata/info/value_report_project/product_root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="ASCII"?>
-<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2 http://www.w3.org/2001/XInclude http://www.s60.com/xml/confml/1#//include">
+<confml:configuration name="Some Product X" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2 http://www.w3.org/2001/XInclude http://www.s60.com/xml/confml/1#//include">
   <xi:include href="assets/asset1/root.confml"/>
   <xi:include href="assets/asset2/root.confml"/>
   <xi:include href="family/root.confml"/>
--- a/configurationengine/source/scripts/tests/testdata/info/value_report_project/variant_root.confml	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/tests/testdata/info/value_report_project/variant_root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="ASCII"?>
-<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2 http://www.w3.org/2001/XInclude http://www.s60.com/xml/confml/1#//include">
+<confml:configuration name="Some Variant X" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2 http://www.w3.org/2001/XInclude http://www.s60.com/xml/confml/1#//include">
   <xi:include href="assets/asset1/root.confml"/>
   <xi:include href="assets/asset2/root.confml"/>
   <xi:include href="family/root.confml"/>
Binary file configurationengine/source/scripts/tests/testdata/initvariant/expected.zip has changed
Binary file configurationengine/source/scripts/tests/testdata/initvariant/expected2.zip has changed
Binary file configurationengine/source/scripts/tests/testdata/initvariant/expected3.zip has changed
Binary file configurationengine/source/scripts/tests/testdata/initvariant/test_project.zip has changed
Binary file configurationengine/source/scripts/tests/testdata/initvariant/variant.cpf has changed
Binary file configurationengine/source/scripts/tests/testdata/merge/last_layer_expected.zip has changed
Binary file configurationengine/source/scripts/tests/testdata/merge/last_layer_rename_expected.zip has changed
Binary file configurationengine/source/scripts/tests/testdata/merge/last_layer_variant_v1_expected.zip has changed
Binary file configurationengine/source/scripts/tests/testdata/merge/last_layer_variant_v1_v2_expected.zip has changed
Binary file configurationengine/source/scripts/tests/testdata/merge/last_layer_variant_v2_expected.zip has changed
Binary file configurationengine/source/scripts/tests/testdata/merge/multiple_last_layers_expected.zip has changed
Binary file configurationengine/source/scripts/tests/testdata/merge/test_variant_v1.cpf has changed
Binary file configurationengine/source/scripts/tests/testdata/merge/test_variant_v2.cpf has changed
Binary file configurationengine/source/scripts/tests/testdata/packvariant/expected/packvariant.zip has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/packvariant/project/Layer1/confml/basic_setting_types_test.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/2" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2" name="Basic setting types test">
+  <confml:feature ref="BasicSettingTypesTest" name="Basic setting types test">
+    <confml:desc>Feature with basic setting types (ConfML v2.0)</confml:desc>
+    <confml:setting ref="RealSetting" name="Real setting" type="real">
+      <confml:desc>A real setting</confml:desc>
+    </confml:setting>
+    <confml:setting ref="IntSetting" name="Int setting" type="int">
+      <confml:desc>An int setting</confml:desc>
+    </confml:setting>
+    <confml:setting ref="StringSetting" name="String setting" type="string">
+      <confml:desc>A string setting</confml:desc>
+    </confml:setting>
+    <confml:setting ref="BooleanSetting" name="Boolean setting" type="boolean">
+      <confml:desc>A boolean setting</confml:desc>
+    </confml:setting>
+    <confml:setting ref="SelectionSetting" name="Selection setting" type="selection">
+      <confml:desc>A selection setting</confml:desc>
+      <confml:option name="Option0" value="0"/>
+      <confml:option name="Option1" value="1"/>
+      <confml:option name="Option2" value="2"/>
+      <confml:option name="Option3" value="3"/>
+      <confml:option name="Option4" value="4"/>
+    </confml:setting>
+  </confml:feature>
+  
+  <confml:data>
+    <confml:BasicSettingTypesTest>
+      <confml:RealSetting>3.14</confml:RealSetting>
+      <confml:IntSetting>10</confml:IntSetting>
+      <confml:StringSetting>default string</confml:StringSetting>
+      <confml:BooleanSetting>true</confml:BooleanSetting>
+      <confml:SelectionSetting>1</confml:SelectionSetting>
+    </confml:BasicSettingTypesTest>
+  </confml:data>
+  
+  <confml:rfs>
+    <confml:BasicSettingTypesTest>
+      <confml:RealSetting>true</confml:RealSetting>
+      <confml:IntSetting>false</confml:IntSetting>
+      <confml:StringSetting>false</confml:StringSetting>
+      <confml:BooleanSetting>true</confml:BooleanSetting>
+      <confml:SelectionSetting>true</confml:SelectionSetting>
+    </confml:BasicSettingTypesTest>
+  </confml:rfs>
+</confml:configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/packvariant/project/Layer1/confml/bitmask_test.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/1" name="Bitmask test" version="1">
+  <feature ref="BitmaskTest" name="Bitmask test">
+    <desc>Feature with bitmask flags</desc>
+    <setting ref="Bit0" name="Bit 0" type="boolean">
+      <desc>A boolean setting for bit 0</desc>
+    </setting>
+    <setting ref="Bit1" name="Bit 1" type="boolean">
+      <desc>A boolean setting for bit 1</desc>
+    </setting>
+    <setting ref="Bit2" name="Bit 2" type="boolean">
+      <desc>A boolean setting for bit 2</desc>
+    </setting>
+    <setting ref="Bit3" name="Bit 3" type="boolean">
+      <desc>A boolean setting for bit 3</desc>
+    </setting>
+    <setting ref="Bit4" name="Bit 4" type="boolean">
+      <desc>A boolean setting for bit 4</desc>
+    </setting>
+    <setting ref="Bit5" name="Bit 5" type="boolean">
+      <desc>A boolean setting for bit 5</desc>
+    </setting>
+  </feature>
+  <data>
+    <BitmaskTest>
+      <Bit0>true</Bit0>
+      <Bit1>false</Bit1>
+      <Bit2>true</Bit2>
+      <Bit3>false</Bit3>
+      <Bit4>true</Bit4>
+      <Bit5>false</Bit5>
+    </BitmaskTest>
+  </data>
+  
+  <rfs>
+    <BitmaskTest>
+      <Bit0>false</Bit0>
+      <Bit1>true</Bit1>
+      <Bit2>false</Bit2>
+      <Bit3>true</Bit3>
+      <Bit4>false</Bit4>
+      <Bit5>true</Bit5>
+    </BitmaskTest>
+  </rfs>
+</configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/packvariant/project/Layer1/confml/feature1.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/1" name="Feature 1" version="1">
+  <feature ref="Feature1" name="Feature 1 (ConfML v1.0)">
+    <desc>Feature with all supported setting types for ConfML v1.0</desc>
+    <setting ref="RealSetting" name="Real setting" type="real">
+      <desc>A real setting</desc>
+    </setting>
+    <setting ref="IntSetting" name="Int setting" type="int">
+      <desc>An int setting</desc>
+    </setting>
+    <setting ref="StringSetting" name="String setting" type="string">
+      <desc>A string setting</desc>
+    </setting>
+    <setting ref="BooleanSetting" name="Boolean setting" type="boolean">
+      <desc>A boolean setting</desc>
+    </setting>
+    <setting ref="SelectionSetting" name="Selection setting" type="selection">
+      <desc>A selection setting</desc>
+      <option name="Option0" value="0"/>
+      <option name="Option1" value="1"/>
+      <option name="Option2" value="2"/>
+      <option name="Option3" value="3"/>
+      <option name="Option4" value="4"/>
+    </setting>
+    <setting ref="SequenceSetting" name="Sequence setting" type="sequence">
+      <desc>A sequence setting</desc>
+      <setting ref="RealSubSetting" name="Real sub-setting" type="real">
+        <desc>A real sub-setting</desc>
+      </setting>
+      <setting ref="IntSubSetting" name="Int sub-setting" type="int">
+        <desc>An int sub-setting</desc>
+      </setting>
+      <setting ref="StringSubSetting" name="String sub-setting" type="string">
+        <desc>A string sub-setting</desc>
+      </setting>
+      <setting ref="BooleanSubSetting" name="Boolean sub-setting" type="boolean">
+        <desc>A boolean sub-setting</desc>
+      </setting>
+      <setting ref="SelectionSubSetting" name="Selection sub-setting" type="selection">
+        <desc>A selection sub-setting</desc>
+        <option name="Op0" value="0"/>
+        <option name="Op1" value="1"/>
+        <option name="Op2" value="2"/>
+        <option name="Op3" value="3"/>
+        <option name="Op4" value="4"/>
+      </setting>
+    </setting>
+  </feature>
+  <data>
+    <Feature1>
+      <RealSetting>3.14</RealSetting>
+      <IntSetting>10</IntSetting>
+      <StringSetting>default string</StringSetting>
+      <BooleanSetting>true</BooleanSetting>
+      <SelectionSetting>1</SelectionSetting>
+      <SequenceSetting template="true">
+        <RealSubSetting>1.0</RealSubSetting>
+        <IntSubSetting>1</IntSubSetting>
+        <StringSubSetting>template</StringSubSetting>
+        <BooleanSubSetting>false</BooleanSubSetting>
+        <SelectionSubSetting>0</SelectionSubSetting>
+      </SequenceSetting>
+      <SequenceSetting>
+        <RealSubSetting>1.25</RealSubSetting>
+        <IntSubSetting>128</IntSubSetting>
+        <StringSubSetting>def1</StringSubSetting>
+        <BooleanSubSetting>false</BooleanSubSetting>
+        <SelectionSubSetting>1</SelectionSubSetting>
+      </SequenceSetting>
+      <SequenceSetting>
+        <RealSubSetting>1.5</RealSubSetting>
+        <IntSubSetting>256</IntSubSetting>
+        <StringSubSetting>def2</StringSubSetting>
+        <BooleanSubSetting>false</BooleanSubSetting>
+        <SelectionSubSetting>1</SelectionSubSetting>
+      </SequenceSetting>
+    </Feature1>
+  </data>
+  
+  <rfs>
+    <Feature1>
+      <RealSetting>true</RealSetting>
+      <IntSetting>false</IntSetting>
+      <StringSetting>false</StringSetting>
+      <BooleanSetting>true</BooleanSetting>
+      <SelectionSetting>true</SelectionSetting>
+    </Feature1>
+  </rfs>
+</configuration>
Binary file configurationengine/source/scripts/tests/testdata/packvariant/project/Layer1/confml/feature2.confml has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/packvariant/project/Layer1/confml/file_folder_test.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/2" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2" name="Time types test">
+  <confml:feature ref="FileFolderTest" name="File &amp; folder types test">
+    <confml:desc>Feature with file and folder setting types</confml:desc>
+    <confml:setting ref="FolderSetting" name="Folder setting" type="folder">
+      <confml:desc>A folder setting</confml:desc>
+      <confml:localPath/>
+      <confml:targetPath/>
+    </confml:setting>
+    <confml:setting ref="FileSetting" name="File setting" type="file">
+      <confml:desc>A file setting</confml:desc>
+      <confml:localPath/>
+      <confml:targetPath/>
+    </confml:setting>
+  </confml:feature>
+  <confml:data>
+    <confml:FileFolderTest>
+      <confml:FolderSetting>
+        <confml:localPath>default_folder</confml:localPath>
+        <confml:targetPath>default_target_folder/</confml:targetPath>
+      </confml:FolderSetting>
+      <confml:FileSetting>
+        <confml:localPath>default_file.txt</confml:localPath>
+        <confml:targetPath>default_target_folder/default_file_renamed.txt</confml:targetPath>
+      </confml:FileSetting>
+    </confml:FileFolderTest>
+  </confml:data>
+</confml:configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/packvariant/project/Layer1/confml/imaker_api.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-16"?>
+<configuration name="imaker interface" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+<feature name="iMaker API" ref="imakerapi">
+  <setting name="PRODUCT_NAME" ref="productname" type="string">
+    <property name="cone-report-ignore" value="true"/>
+  </setting>
+  </feature>
+<data>
+  <imakerapi>
+    <productname>testprod</productname>
+    </imakerapi>
+  </data>
+</configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/packvariant/project/Layer1/confml/sequence_setting_test.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/2" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2" name="Basic setting types test">
+  <confml:feature ref="SequenceSettingTest" name="Sequence setting test">
+    <confml:desc>Feature with a sequence setting (ConfML v2.0)</confml:desc>
+    <confml:setting ref="SequenceSetting" name="Sequence setting" type="sequence">
+      <confml:desc>A sequence setting</confml:desc>
+      <confml:setting ref="FolderSubSetting" name="Folder sub-setting" type="folder">
+        <confml:desc>A folder sub-setting</confml:desc>
+        <confml:localPath/>
+        <confml:targetPath/>
+      </confml:setting>
+      <confml:setting ref="RealSubSetting" name="Real sub-setting" type="real">
+        <confml:desc>A real sub-setting</confml:desc>
+      </confml:setting>
+      <confml:setting ref="FileSubSetting" name="File sub-setting" type="file">
+        <confml:desc>A file sub-setting</confml:desc>
+        <confml:localPath/>
+        <confml:targetPath/>
+      </confml:setting>
+      <confml:setting ref="IntSubSetting" name="Int sub-setting" type="int">
+        <confml:desc>An int sub-setting</confml:desc>
+      </confml:setting>
+      <confml:setting ref="StringSubSetting" name="String sub-setting" type="string">
+        <confml:desc>A string sub-setting</confml:desc>
+      </confml:setting>
+      <confml:setting ref="BooleanSubSetting" name="Boolean sub-setting" type="boolean">
+        <confml:desc>A boolean sub-setting</confml:desc>
+      </confml:setting>
+      <confml:setting ref="SelectionSubSetting" name="Selection sub-setting" type="selection">
+        <confml:desc>A selection sub-setting</confml:desc>
+        <confml:option name="Op0" value="0"/>
+        <confml:option name="Op1" value="1"/>
+        <confml:option name="Op2" value="2"/>
+        <confml:option name="Op3" value="3"/>
+        <confml:option name="Op4" value="4"/>
+      </confml:setting>
+    </confml:setting>
+  </confml:feature>
+  
+  <confml:data>
+    <confml:SequenceSettingTest>
+      <confml:SequenceSetting template="true">
+        <confml:FolderSubSetting><confml:localPath>seq/default_folder</confml:localPath></confml:FolderSubSetting>
+        <confml:RealSubSetting>1.0</confml:RealSubSetting>
+        <confml:FileSubSetting><confml:localPath>seq/default_file.txt</confml:localPath></confml:FileSubSetting>
+        <confml:IntSubSetting>1</confml:IntSubSetting>
+        <confml:StringSubSetting>template</confml:StringSubSetting>
+        <confml:BooleanSubSetting>false</confml:BooleanSubSetting>
+        <confml:SelectionSubSetting>0</confml:SelectionSubSetting>
+      </confml:SequenceSetting>
+      <confml:SequenceSetting>
+        <confml:FolderSubSetting><confml:localPath>seq/def1_folder</confml:localPath></confml:FolderSubSetting>
+        <confml:RealSubSetting>1.25</confml:RealSubSetting>
+        <confml:FileSubSetting><confml:localPath>seq/def1_file.txt</confml:localPath></confml:FileSubSetting>
+        <confml:IntSubSetting>128</confml:IntSubSetting>
+        <confml:StringSubSetting>def1</confml:StringSubSetting>
+        <confml:BooleanSubSetting>false</confml:BooleanSubSetting>
+        <confml:SelectionSubSetting>1</confml:SelectionSubSetting>
+      </confml:SequenceSetting>
+      <confml:SequenceSetting>
+        <confml:FolderSubSetting><confml:localPath>seq/def2_folder</confml:localPath></confml:FolderSubSetting>
+        <confml:RealSubSetting>1.5</confml:RealSubSetting>
+        <confml:FileSubSetting><confml:localPath>seq/def2_file.txt</confml:localPath></confml:FileSubSetting>
+        <confml:IntSubSetting>256</confml:IntSubSetting>
+        <confml:StringSubSetting>def2</confml:StringSubSetting>
+        <confml:BooleanSubSetting>false</confml:BooleanSubSetting>
+        <confml:SelectionSubSetting>1</confml:SelectionSubSetting>
+      </confml:SequenceSetting>
+    </confml:SequenceSettingTest>
+  </confml:data>
+</confml:configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/packvariant/project/Layer1/confml/time_types_test.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/2" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2" name="Time types test">
+  <confml:feature ref="TimeTypesTest" name="Time types test">
+    <confml:desc>Feature with date-time etc. setting types</confml:desc>
+    <confml:setting ref="DateSetting" name="Date setting" type="date">
+      <confml:desc>A date setting</confml:desc>
+    </confml:setting>
+    <confml:setting ref="TimeSetting" name="Time setting" type="time">
+      <confml:desc>A time setting</confml:desc>
+    </confml:setting>
+    <confml:setting ref="DateTimeSetting" name="Date-time setting" type="dateTime">
+      <confml:desc>A date-time setting</confml:desc>
+    </confml:setting>
+    <confml:setting ref="DurationSetting" name="Duration setting" type="duration">
+      <confml:desc>A duration setting</confml:desc>
+    </confml:setting>
+  </confml:feature>
+  <confml:data>
+    <confml:TimeTypesTest>
+      <confml:DateSetting>2009-02-02</confml:DateSetting>
+      <confml:TimeSetting>07:30:15</confml:TimeSetting>
+      <confml:DateTimeSetting>2009-02-02-07:00:00</confml:DateTimeSetting>
+      <confml:DurationSetting>P5Y4M3DT12H25M15S</confml:DurationSetting>
+    </confml:TimeTypesTest>
+  </confml:data>
+</confml:configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/packvariant/project/Layer1/confml/view.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/2" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2">
+  <confml:view name="Layer 1 view">
+    <confml:desc>Testing view located on layer 1.</confml:desc>
+    <confml:group name="ConfML v1.0 settings">
+      <confml:desc>Sample Description</confml:desc>
+      <confml:setting ref="Feature1/RealSetting"/>
+      <confml:setting ref="Feature1/IntSetting"/>
+      <confml:setting ref="Feature1/StringSetting"/>
+      <confml:setting ref="Feature1/BooleanSetting"/>
+      <confml:setting ref="Feature1/SelectionSetting"/>
+      <confml:setting ref="Feature1/SequenceSetting"/>
+      <confml:setting ref="Feature2/SequenceSetting"/>
+    </confml:group>
+    <confml:group name="ConfML v2.0 settings">
+      <confml:desc>Sample Description</confml:desc>
+      <confml:setting ref="BasicSettingTypesTest/RealSetting"/>
+      <confml:setting ref="BasicSettingTypesTest/IntSetting"/>
+      <confml:setting ref="BasicSettingTypesTest/StringSetting"/>
+      <confml:setting ref="BasicSettingTypesTest/BooleanSetting"/>
+      <confml:setting ref="BasicSettingTypesTest/SelectionSetting"/>
+      <confml:setting ref="FileFolderTest/FolderSetting"/>
+      <confml:setting ref="FileFolderTest/FileSetting"/>
+      <confml:setting ref="SequenceSettingTest/SequenceSetting"/>
+    </confml:group>
+  </confml:view>
+</confml:configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/packvariant/project/Layer1/content/override_test.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,1 @@
+Test
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/packvariant/project/Layer1/implml/bitmask_test.templateml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<templateml xmlns="http://www.s60.com/xml/templateml/1" xmlns:xi="http://www.w3.org/2001/XInclude">
+    <output file="bitmask_test.txt" encoding="UTF-8">
+<template>
+Bit 0: {{ feat_tree.BitmaskTest.Bit0._value }}
+Bit 1: {{ feat_tree.BitmaskTest.Bit1._value }}
+Bit 2: {{ feat_tree.BitmaskTest.Bit2._value }}
+Bit 3: {{ feat_tree.BitmaskTest.Bit3._value }}
+Bit 4: {{ feat_tree.BitmaskTest.Bit4._value }}
+Bit 5: {{ feat_tree.BitmaskTest.Bit5._value }}
+</template>
+    </output>
+</templateml>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/packvariant/project/Layer1/implml/feature1_1.templateml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<templateml xmlns="http://www.s60.com/xml/templateml/1" xmlns:xi="http://www.w3.org/2001/XInclude">
+    <output file="feature1_1.txt" encoding="UTF-8">
+<template>
+Feature1.IntSetting: {{ feat_tree.Feature1.IntSetting._value }}
+</template>
+    </output>
+</templateml>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/packvariant/project/Layer1/implml/feature1_2.templateml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<templateml xmlns="http://www.s60.com/xml/templateml/1" xmlns:xi="http://www.w3.org/2001/XInclude">
+    <output file="feature1_1.txt" encoding="UTF-8">
+<template>
+Feature1.StringSetting: {{ feat_tree.Feature1.StringSetting._value }}
+</template>
+    </output>
+</templateml>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/packvariant/project/Layer1/implml/feature1_sequence.templateml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<templateml xmlns="http://www.s60.com/xml/templateml/1" xmlns:xi="http://www.w3.org/2001/XInclude">
+    <output file="feature1_sequence.txt" encoding="UTF-8">
+<template>
+Feature1 sequence items:
+{% for value in feat_tree.Feature1.SequenceSetting._value -%}
+    {{ value }}
+{% endfor %}
+</template>
+    </output>
+</templateml>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/packvariant/project/Layer1/implml/feature2.templateml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<templateml xmlns="http://www.s60.com/xml/templateml/1" xmlns:xi="http://www.w3.org/2001/XInclude">
+    <output file="feature2.txt" encoding="UTF-8">
+<template>
+Number of items in sequence: {{ feat_tree.Feature2.SequenceSetting._value|length }}
+</template>
+    </output>
+</templateml>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/packvariant/project/Layer1/implml/time_types_test.templateml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<templateml xmlns="http://www.s60.com/xml/templateml/1" xmlns:xi="http://www.w3.org/2001/XInclude">
+    <output file="time_types.txt" encoding="UTF-8">
+<template>
+Date setting:      {{ feat_tree.TimeTypesTest.DateSetting._value }}
+Time setting:      {{ feat_tree.TimeTypesTest.TimeSetting._value }}
+Date-time setting: {{ feat_tree.TimeTypesTest.DateTimeSetting._value }}
+Duration setting:  {{ feat_tree.TimeTypesTest.DurationSetting._value }}
+</template>
+    </output>
+</templateml>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/packvariant/project/Layer1/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="ASCII"?>
+<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/1" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="http://www.w3.org/2001/XInclude http://www.s60.com/xml/confml/1#//include" name="Layer 1">
+  <xi:include href="confml/feature1.confml"/>
+  <xi:include href="confml/feature2.confml"/>
+  <xi:include href="confml/bitmask_test.confml"/>
+  <xi:include href="confml/time_types_test.confml"/>
+  <xi:include href="confml/file_folder_test.confml"/>
+  <xi:include href="confml/basic_setting_types_test.confml"/>
+  <xi:include href="confml/sequence_setting_test.confml"/>
+  <xi:include href="confml/imaker_api.confml"/>
+  <xi:include href="confml/view.confml"/>
+</confml:configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/packvariant/project/Layer2/confml/data.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/2" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2" name="data">
+  <confml:data>
+  
+    <confml:BasicSettingTypesTest>
+      <confml:RealSetting>3.145</confml:RealSetting>
+      <confml:IntSetting>222</confml:IntSetting>
+    </confml:BasicSettingTypesTest>
+    
+    <confml:FileFolderTest>
+      <confml:FileSetting>
+        <confml:localPath>layer2_file.txt</confml:localPath>
+      </confml:FileSetting>
+    </confml:FileFolderTest>
+    
+    <confml:SequenceSettingTest>
+      <confml:SequenceSetting extensionPolicy="prefix">
+        <confml:FolderSubSetting><confml:localPath>seq/layer2_folder</confml:localPath></confml:FolderSubSetting>
+		<confml:RealSubSetting>2.0</confml:RealSubSetting>
+		<confml:FileSubSetting><confml:localPath>seq/layer2_file.txt</confml:localPath></confml:FileSubSetting>
+		<confml:IntSubSetting>22</confml:IntSubSetting>
+		<confml:StringSubSetting>L21</confml:StringSubSetting>
+		<confml:BooleanSubSetting>true</confml:BooleanSubSetting>
+		<confml:SelectionSubSetting>2</confml:SelectionSubSetting>
+	  </confml:SequenceSetting>
+	  
+	  <confml:SequenceSetting>
+        <confml:FolderSubSetting><confml:localPath>seq/layer2_folder2</confml:localPath></confml:FolderSubSetting>
+		<confml:RealSubSetting>2.1</confml:RealSubSetting>
+		<confml:FileSubSetting><confml:localPath>seq/layer2_file2.txt</confml:localPath></confml:FileSubSetting>
+		<confml:IntSubSetting>222</confml:IntSubSetting>
+		<confml:StringSubSetting>L22</confml:StringSubSetting>
+		<confml:BooleanSubSetting>true</confml:BooleanSubSetting>
+		<confml:SelectionSubSetting>1</confml:SelectionSubSetting>
+	  </confml:SequenceSetting>
+    </confml:SequenceSettingTest>
+    
+    <confml:Feature1>
+      <confml:IntSetting>222</confml:IntSetting>
+      <confml:RealSetting>3.145</confml:RealSetting>
+	  
+      <confml:SequenceSetting extensionPolicy="prefix">
+		<confml:RealSubSetting>2.0</confml:RealSubSetting>
+		<confml:IntSubSetting>22</confml:IntSubSetting>
+		<confml:StringSubSetting>L21</confml:StringSubSetting>
+		<confml:BooleanSubSetting>true</confml:BooleanSubSetting>
+		<confml:SelectionSubSetting>2</confml:SelectionSubSetting>
+	  </confml:SequenceSetting>
+	  
+	  <confml:SequenceSetting>
+		<confml:RealSubSetting>2.1</confml:RealSubSetting>
+		<confml:IntSubSetting>222</confml:IntSubSetting>
+		<confml:StringSubSetting>L22</confml:StringSubSetting>
+		<confml:BooleanSubSetting>true</confml:BooleanSubSetting>
+		<confml:SelectionSubSetting>1</confml:SelectionSubSetting>
+	  </confml:SequenceSetting>
+    </confml:Feature1>
+	
+	<confml:Feature2>
+	  <confml:SequenceSetting extensionPolicy="append">
+	    <confml:IntSubSetting>222</confml:IntSubSetting>
+		<confml:StringSubSetting>layer2 (1)</confml:StringSubSetting>
+	  </confml:SequenceSetting>
+	  <confml:SequenceSetting>
+	    <confml:IntSubSetting>222</confml:IntSubSetting>
+		<confml:StringSubSetting>layer2 (2)</confml:StringSubSetting>
+	  </confml:SequenceSetting>
+	  <confml:SequenceSetting>
+	    <confml:IntSubSetting>222</confml:IntSubSetting>
+		<confml:StringSubSetting>layer2 (3)</confml:StringSubSetting>
+	  </confml:SequenceSetting>
+	</confml:Feature2>
+	
+  </confml:data>
+</confml:configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/packvariant/project/Layer2/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="ASCII"?>
+<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/1" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2 http://www.w3.org/2001/XInclude http://www.s60.com/xml/confml/1#//include"  name="Layer 2">
+  <xi:include href="confml/data.confml"/>
+</confml:configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/packvariant/project/Layer3/confml/data.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/2" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2" name="data">
+  <confml:data>
+  
+    <confml:BasicSettingTypesTest>
+      <confml:IntSetting>333</confml:IntSetting>
+      <confml:BooleanSetting>false</confml:BooleanSetting>
+      <confml:RealSetting>3.1456</confml:RealSetting>
+      <confml:SelectionSetting>3</confml:SelectionSetting>
+      <confml:StringSetting>layer 3 string</confml:StringSetting>
+    </confml:BasicSettingTypesTest>
+    
+    <confml:SequenceSettingTest>
+      <confml:SequenceSetting extensionPolicy="append">
+        <confml:FolderSubSetting><confml:localPath>seq/layer3_folder</confml:localPath></confml:FolderSubSetting>
+		<confml:RealSubSetting>3.0</confml:RealSubSetting>
+		<confml:FileSubSetting><confml:localPath>seq/layer3_file.txt</confml:localPath></confml:FileSubSetting>
+		<confml:IntSubSetting>33</confml:IntSubSetting>
+		<confml:StringSubSetting>L31</confml:StringSubSetting>
+		<confml:BooleanSubSetting>false</confml:BooleanSubSetting>
+		<confml:SelectionSubSetting>0</confml:SelectionSubSetting>
+      </confml:SequenceSetting>
+      <confml:SequenceSetting>
+        <confml:FolderSubSetting><confml:localPath>seq/layer3_folder</confml:localPath></confml:FolderSubSetting>
+        <confml:RealSubSetting>3.35</confml:RealSubSetting>
+		<confml:FileSubSetting><confml:localPath></confml:localPath></confml:FileSubSetting>
+		<confml:IntSubSetting>1</confml:IntSubSetting>
+		<confml:StringSubSetting>L32</confml:StringSubSetting>
+		<confml:BooleanSubSetting>true</confml:BooleanSubSetting>
+		<confml:SelectionSubSetting>2</confml:SelectionSubSetting>
+	  </confml:SequenceSetting>
+    </confml:SequenceSettingTest>
+    
+    <confml:Feature1>
+      <confml:IntSetting>333</confml:IntSetting>
+      <confml:BooleanSetting>false</confml:BooleanSetting>
+      <confml:RealSetting>3.1456</confml:RealSetting>
+      <confml:SelectionSetting>3</confml:SelectionSetting>
+      <confml:StringSetting>layer 3 string</confml:StringSetting>
+	  
+      <confml:SequenceSetting extensionPolicy="append">
+		<confml:RealSubSetting>3.0</confml:RealSubSetting>
+		<confml:IntSubSetting>33</confml:IntSubSetting>
+		<confml:StringSubSetting>L31</confml:StringSubSetting>
+		<confml:BooleanSubSetting>false</confml:BooleanSubSetting>
+		<confml:SelectionSubSetting>0</confml:SelectionSubSetting>
+      </confml:SequenceSetting>
+      <confml:SequenceSetting>
+        <confml:RealSubSetting>3.35</confml:RealSubSetting>
+		<confml:IntSubSetting>1</confml:IntSubSetting>
+		<confml:StringSubSetting>L32</confml:StringSubSetting>
+		<confml:BooleanSubSetting>true</confml:BooleanSubSetting>
+		<confml:SelectionSubSetting>2</confml:SelectionSubSetting>
+	  </confml:SequenceSetting>
+    </confml:Feature1>
+	
+	<confml:Feature2>
+	  <confml:SequenceSetting extensionPolicy="prefix">
+	    <confml:IntSubSetting>333</confml:IntSubSetting>
+		<confml:StringSubSetting>layer3 (1)</confml:StringSubSetting>
+	  </confml:SequenceSetting>
+	</confml:Feature2>
+	
+  </confml:data>
+</confml:configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/packvariant/project/Layer3/content/override_test.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,1 @@
+Test
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/packvariant/project/Layer3/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="ASCII"?>
+<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/1" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2 http://www.w3.org/2001/XInclude http://www.s60.com/xml/confml/1#//include"  name="Layer 3">
+  <xi:include href="confml/data.confml"/>
+</confml:configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/packvariant/project/Layer4/confml/data.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/2" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2" name="data">
+  <confml:data>
+  
+    <confml:BasicSettingTypesTest>
+      <confml:IntSetting>444</confml:IntSetting>
+      <confml:RealSetting>3.14567</confml:RealSetting>
+      <confml:SelectionSetting>4</confml:SelectionSetting>
+      <confml:StringSetting>layer 4 string</confml:StringSetting>
+    </confml:BasicSettingTypesTest>
+    
+    <confml:SequenceSettingTest>
+      <confml:SequenceSetting extensionPolicy="replace">
+        <confml:FolderSubSetting><confml:localPath>seq/layer4_folder</confml:localPath></confml:FolderSubSetting>
+		<confml:RealSubSetting>4.0</confml:RealSubSetting>
+		<confml:FileSubSetting><confml:localPath>seq/layer4_file.txt</confml:localPath></confml:FileSubSetting>
+		<confml:IntSubSetting>44</confml:IntSubSetting>
+		<confml:StringSubSetting>L41</confml:StringSubSetting>
+		<confml:BooleanSubSetting>false</confml:BooleanSubSetting>
+		<confml:SelectionSubSetting>1</confml:SelectionSubSetting>
+      </confml:SequenceSetting>
+      <confml:SequenceSetting>
+        <confml:FolderSubSetting><confml:localPath>seq/layer4_folder</confml:localPath></confml:FolderSubSetting>
+        <confml:RealSubSetting>4.45</confml:RealSubSetting>
+		<confml:FileSubSetting><confml:localPath>seq/layer4_file.txt</confml:localPath></confml:FileSubSetting>
+		<confml:IntSubSetting>1</confml:IntSubSetting>
+		<confml:StringSubSetting>L42</confml:StringSubSetting>
+		<confml:BooleanSubSetting>true</confml:BooleanSubSetting>
+		<confml:SelectionSubSetting>3</confml:SelectionSubSetting>
+	  </confml:SequenceSetting>
+    </confml:SequenceSettingTest>
+    
+    <confml:Feature1>
+      <confml:IntSetting>444</confml:IntSetting>
+      <confml:RealSetting>3.14567</confml:RealSetting>
+      <confml:SelectionSetting>4</confml:SelectionSetting>
+      <confml:StringSetting>layer 4 string</confml:StringSetting>
+	  
+      <confml:SequenceSetting extensionPolicy="replace">
+		<confml:RealSubSetting>4.0</confml:RealSubSetting>
+		<confml:IntSubSetting>44</confml:IntSubSetting>
+		<confml:StringSubSetting>L41</confml:StringSubSetting>
+		<confml:BooleanSubSetting>false</confml:BooleanSubSetting>
+		<confml:SelectionSubSetting>1</confml:SelectionSubSetting>
+      </confml:SequenceSetting>
+      <confml:SequenceSetting>
+        <confml:RealSubSetting>4.45</confml:RealSubSetting>
+		<confml:IntSubSetting>1</confml:IntSubSetting>
+		<confml:StringSubSetting>L42</confml:StringSubSetting>
+		<confml:BooleanSubSetting>true</confml:BooleanSubSetting>
+		<confml:SelectionSubSetting>3</confml:SelectionSubSetting>
+	  </confml:SequenceSetting>
+    </confml:Feature1>
+	
+	<confml:Feature2>
+	  <confml:SequenceSetting extensionPolicy="replace">
+	    <confml:IntSubSetting>444</confml:IntSubSetting>
+		<confml:StringSubSetting>layer4 (1)</confml:StringSubSetting>
+	  </confml:SequenceSetting>
+	  <confml:SequenceSetting>
+	    <confml:IntSubSetting>444</confml:IntSubSetting>
+		<confml:StringSubSetting>layer4 (2)</confml:StringSubSetting>
+	  </confml:SequenceSetting>
+	</confml:Feature2>
+	
+  </confml:data>
+</confml:configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/packvariant/project/Layer4/confml/layer4_feature.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/1" name="Layer 4 feature" version="1">
+  <feature ref="Layer4Feature" name="Layer 4 Feature">
+    <desc>Feature with some setting types</desc>
+    <setting ref="RealSetting" name="Real setting" type="real">
+      <desc>A real setting</desc>
+    </setting>
+    <setting ref="IntSetting" name="Int setting" type="int">
+      <desc>An int setting</desc>
+    </setting>
+    <setting ref="StringSetting" name="String setting" type="string">
+      <desc>A string setting</desc>
+    </setting>
+    <setting ref="BooleanSetting" name="Boolean setting" type="boolean">
+      <desc>A boolean setting</desc>
+    </setting>
+    <setting ref="SelectionSetting" name="Selection setting" type="selection">
+      <desc>A selection setting</desc>
+      <option name="Option0" value="opt0"/>
+      <option name="Option1" value="opt1"/>
+      <option name="Option2" value="opt2"/>
+      <option name="Option3" value="opt3"/>
+      <option name="Option4" value="opt4"/>
+    </setting>
+    <setting ref="SequenceSetting" name="Sequence setting" type="sequence">
+      <desc>A sequence setting</desc>
+      <setting ref="StringSubSetting" name="String sub-setting" type="string">
+        <desc>A string sub-setting</desc>
+      </setting>
+    </setting>
+  </feature>
+  <data>
+    <Layer4Feature>
+      <RealSetting>10.5</RealSetting>
+      <IntSetting>150</IntSetting>
+      <StringSetting>the default</StringSetting>
+      <BooleanSetting>true</BooleanSetting>
+      <SelectionSetting>opt2</SelectionSetting>
+      <SequenceSetting template="true">
+        <StringSubSetting>template</StringSubSetting>
+      </SequenceSetting>
+      <SequenceSetting>
+        <StringSubSetting>def1</StringSubSetting>
+      </SequenceSetting>
+      <SequenceSetting>
+        <StringSubSetting>def2</StringSubSetting>
+      </SequenceSetting>
+    </Layer4Feature>
+  </data>
+  
+  <rfs>
+    <Layer4Feature>
+      <RealSetting>true</RealSetting>
+      <IntSetting>false</IntSetting>
+      <StringSetting>false</StringSetting>
+      <BooleanSetting>true</BooleanSetting>
+      <SelectionSetting>true</SelectionSetting>
+      <SequenceSetting>true</SequenceSetting>
+    </Layer4Feature>
+  </rfs>
+</configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/packvariant/project/Layer4/confml/view.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<confml:configuration xmlns:confml="http://www.s60.com/xml/confml/1" name="Layer 4 view">
+  <confml:view name="Test view">
+    <confml:desc>Test view desc</confml:desc>
+    <confml:group name="Group 1">
+      <confml:desc>Sample Description</confml:desc>
+      <confml:group name="Sub-group 1">
+        <confml:desc>Sub-group 1 desc</confml:desc>
+        <confml:setting ref="Feature1/BooleanSetting"/>
+        <confml:setting ref="FileFolderTest/FolderSetting"/>
+      </confml:group>
+      <confml:group name="Sub-group 2">
+        <confml:desc>Sub-group 2 desc</confml:desc>
+        <confml:setting ref="FileFolderTest/FileSetting"/>
+        <confml:setting ref="Feature1/IntSetting"/>
+      </confml:group>
+    </confml:group>
+    <confml:group name="Group 2">
+      <confml:desc>Group 2</confml:desc>
+      <confml:group name="Sub-group 1">
+        <confml:desc>Sub-group 1 desc</confml:desc>
+        <confml:setting ref="Feature1/SelectionSetting"/>
+        <confml:setting ref="Feature1/RealSetting"/>
+        <confml:setting ref="Feature2/SequenceSetting"/>
+      </confml:group>
+      <confml:group name="Sub-group 2">
+        <confml:desc>Sub-group 2 desc</confml:desc>
+        <confml:setting ref="Feature1/SequenceSetting"/>
+        <confml:setting ref="Feature1/StringSetting"/>
+      </confml:group>
+    </confml:group>
+  </confml:view>
+</confml:configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/packvariant/project/Layer4/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="ASCII"?>
+<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/1" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="http://www.w3.org/2001/XInclude http://www.s60.com/xml/confml/1#//include" name="Layer 4">
+  <xi:include href="confml/layer4_feature.confml"/>
+  <xi:include href="confml/view.confml"/>
+  <xi:include href="confml/data.confml"/>
+</confml:configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/packvariant/project/Layer5/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="ASCII"?>
+<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/1" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2 http://www.w3.org/2001/XInclude http://www.s60.com/xml/confml/1#//include"  name="Layer 5">
+</confml:configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/packvariant/project/root1.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="ASCII"?>
+<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2 http://www.w3.org/2001/XInclude http://www.s60.com/xml/confml/1#//include">
+  <xi:include href="Layer1/root.confml"/>
+</confml:configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/packvariant/project/root2.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="ASCII"?>
+<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2 http://www.w3.org/2001/XInclude http://www.s60.com/xml/confml/1#//include">
+  <xi:include href="Layer1/root.confml"/>
+  <xi:include href="Layer2/root.confml"/>
+</confml:configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/packvariant/project/root3.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="ASCII"?>
+<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2 http://www.w3.org/2001/XInclude http://www.s60.com/xml/confml/1#//include">
+  <xi:include href="Layer1/root.confml"/>
+  <xi:include href="Layer2/root.confml"/>
+  <xi:include href="Layer3/root.confml"/>
+</confml:configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/packvariant/project/root4.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="ASCII"?>
+<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/1" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="http://www.s60.com/xml/confml/1 http://www.s60.com/xml/confml/1#//confml2 http://www.w3.org/2001/XInclude http://www.s60.com/xml/confml/1#//include">
+  <xi:include href="Layer1/root.confml"/>
+  <xi:include href="Layer2/root.confml"/>
+  <xi:include href="Layer3/root.confml"/>
+  <xi:include href="Layer4/root.confml"/>
+</confml:configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/packvariant/project/root5.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="ASCII"?>
+<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2 http://www.w3.org/2001/XInclude http://www.s60.com/xml/confml/1#//include">
+  <xi:include href="Layer1/root.confml"/>
+  <xi:include href="Layer2/root.confml"/>
+  <xi:include href="Layer3/root.confml"/>
+  <xi:include href="Layer4/root.confml"/>
+  <xi:include href="Layer5/root.confml"/>
+</confml:configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/packvariant/project/testprod/custvariant/configurator/confml/data.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<confml:configuration xmlns:confml="http://www.s60.com/xml/confml/1" name="data">
+  <confml:data>
+  </confml:data>
+</confml:configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/packvariant/project/testprod/custvariant/configurator/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,3 @@
+<configuration name="configurator" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
+  <xi:include href="confml/data.confml" />
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/packvariant/project/testprod/custvariant/manual/confml/data.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<confml:configuration xmlns:confml="http://www.s60.com/xml/confml/1" name="data">
+  <confml:data>
+  </confml:data>
+</confml:configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/packvariant/project/testprod/custvariant/manual/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,3 @@
+<configuration name="manual" xmlns="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
+  <xi:include href="confml/data.confml" />
+</configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/packvariant/project/testprod_custvariant_root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="ASCII"?>
+<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2 http://www.w3.org/2001/XInclude http://www.s60.com/xml/confml/1#//include">
+  <xi:include href="Layer1/root.confml"/>
+  <xi:include href="Layer2/root.confml"/>
+  <xi:include href="Layer3/root.confml"/>
+  <xi:include href="Layer4/root.confml"/>
+  <xi:include href="Layer5/root.confml"/>
+  <xi:include href="testprod/custvariant/manual/root.confml"/>
+  <xi:include href="testprod/custvariant/configurator/root.confml"/>
+  <meta xmlns:cv="http://www.nokia.com/xml/cpf-id/1">
+    <platform>Fooplat 21</platform>
+  <product>ABC-123</product>
+  <cv:configuration-property name="coreplat_name" value="foo21" />
+  <cv:configuration-property name="coreplat_version" value="21" />
+  <cv:configuration-property name="product_name" value="bar" />
+  <cv:configuration-property name="product_type" value="ABC-123" />
+  <cv:configuration-property name="sw_version" value="001.001" />
+  </meta>
+</confml:configuration>
\ No newline at end of file
--- a/configurationengine/source/scripts/tests/testdata/report/expected/both.txt	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/tests/testdata/report/expected/both.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -3,23 +3,29 @@
 
 Ref: Feature1.BooleanSetting
 Impls:
-File = "base\implml\booleansetting_rofs3.templateml", type = "templateml", gen_runs = ['rofs3']
-File = "base\implml\booleansetting_uda.templateml", type = "templateml", gen_runs = ['uda']
+File = "base/implml/booleansetting_rofs3.templateml", type = "templateml"
+File = "base/implml/booleansetting_uda.templateml", type = "templateml"
 -------------------------------------------------
 Ref: Feature1.IntSetting
 Impls:
-File = "base\implml\intsetting_rofs3.templateml", type = "templateml", gen_runs = ['rofs3']
+File = "base/implml/intsetting_rofs3.templateml", type = "templateml"
 -------------------------------------------------
 Ref: Feature1.RealSetting
 Impls:
-File = "base\implml\realsetting_rofs3_uda.templateml", type = "templateml", gen_runs = ['rofs3', 'uda']
+File = "base/implml/realsetting_rofs3_uda.templateml", type = "templateml"
 -------------------------------------------------
 Ref: Feature1.StringSetting
 Impls:
-File = "base\implml\stringsetting_uda.templateml", type = "templateml", gen_runs = ['uda']
+File = "base/implml/stringsetting_uda.templateml", type = "templateml"
 
 
 
 Refs with no implementation
 ===========================
 Feature1.SelectionSetting
+Feature1.SequenceSetting
+Feature1.SequenceSetting.BooleanSubSetting
+Feature1.SequenceSetting.IntSubSetting
+Feature1.SequenceSetting.RealSubSetting
+Feature1.SequenceSetting.SelectionSubSetting
+Feature1.SequenceSetting.StringSubSetting
--- a/configurationengine/source/scripts/tests/testdata/report/expected/rofs3.txt	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/tests/testdata/report/expected/rofs3.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -3,19 +3,30 @@
 
 Ref: Feature1.BooleanSetting
 Impls:
-File = "base\implml\booleansetting_rofs3.templateml", type = "templateml", gen_runs = []
+File = "base/implml/booleansetting_rofs3.templateml", type = "templateml"
+File = "base/implml/booleansetting_uda.templateml", type = "templateml"
 -------------------------------------------------
 Ref: Feature1.IntSetting
 Impls:
-File = "base\implml\intsetting_rofs3.templateml", type = "templateml", gen_runs = []
+File = "base/implml/intsetting_rofs3.templateml", type = "templateml"
 -------------------------------------------------
 Ref: Feature1.RealSetting
 Impls:
-File = "base\implml\realsetting_rofs3_uda.templateml", type = "templateml", gen_runs = []
+File = "base/implml/realsetting_rofs3_uda.templateml", type = "templateml"
+-------------------------------------------------
+Ref: Feature1.StringSetting
+Impls:
+File = "base/implml/stringsetting_uda.templateml", type = "templateml"
 
 
 
 Refs with no implementation
 ===========================
 Feature1.SelectionSetting
+Feature1.SequenceSetting
+Feature1.SequenceSetting.BooleanSubSetting
+Feature1.SequenceSetting.IntSubSetting
+Feature1.SequenceSetting.RealSubSetting
+Feature1.SequenceSetting.SelectionSubSetting
+Feature1.SequenceSetting.StringSubSetting
 Feature1.StringSetting
--- a/configurationengine/source/scripts/tests/testdata/report/expected/uda.txt	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/tests/testdata/report/expected/uda.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -3,15 +3,20 @@
 
 Ref: Feature1.BooleanSetting
 Impls:
-File = "base\implml\booleansetting_uda.templateml", type = "templateml", gen_runs = []
+File = "base/implml/booleansetting_rofs3.templateml", type = "templateml"
+File = "base/implml/booleansetting_uda.templateml", type = "templateml"
+-------------------------------------------------
+Ref: Feature1.IntSetting
+Impls:
+File = "base/implml/intsetting_rofs3.templateml", type = "templateml"
 -------------------------------------------------
 Ref: Feature1.RealSetting
 Impls:
-File = "base\implml\realsetting_rofs3_uda.templateml", type = "templateml", gen_runs = []
+File = "base/implml/realsetting_rofs3_uda.templateml", type = "templateml"
 -------------------------------------------------
 Ref: Feature1.StringSetting
 Impls:
-File = "base\implml\stringsetting_uda.templateml", type = "templateml", gen_runs = []
+File = "base/implml/stringsetting_uda.templateml", type = "templateml"
 
 
 
@@ -19,3 +24,9 @@
 ===========================
 Feature1.IntSetting
 Feature1.SelectionSetting
+Feature1.SequenceSetting
+Feature1.SequenceSetting.BooleanSubSetting
+Feature1.SequenceSetting.IntSubSetting
+Feature1.SequenceSetting.RealSubSetting
+Feature1.SequenceSetting.SelectionSubSetting
+Feature1.SequenceSetting.StringSubSetting
--- a/configurationengine/source/scripts/tests/testdata/report/template.txt	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/tests/testdata/report/template.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -1,19 +1,19 @@
 Refs with implementations
 =========================
-{% for feat in rep_data.lines -%}
+{% for feat in merged_context.features.get_features(merged_context.impl_set.get_implemented_refs()) -%}
 {% if not loop.first -%}
 -------------------------------------------------
 {%- endif %}
-Ref: {{ feat.ref }}
+Ref: {{ feat.fqr }}
 Impls:
-{% for impl in feat.impls -%}
-    File = "{{ impl.name }}", type = "{{ impl.type }}", gen_runs = {{impl.generation_runs}}
+{% for impl in merged_context.impl_set.get_implementations_with_ref(feat.fqr) -%}
+    File = "{{ impl.ref }}", type = "{{ impl.IMPL_TYPE_ID }}"
 {% endfor -%}
 {% endfor %}
 
 
 Refs with no implementation
 ===========================
-{% for feat in rep_data.ref_noimpl -%}
-    {{ feat.ref }}
+{% for fearef in merged_context.get_refs_with_no_output() -%}
+    {{ fearef }}
 {% endfor %}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/validate/expected/invalid_config_report.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,52 @@
+Validation problems
+-------------------
+File: assets/invalid/confml/broken.confml
+Line: 1
+Type: xml.confml
+Msg:  no element found: line 1, column 0
+
+File: assets/invalid/confml/invalid_element.confml
+Line: 8
+Type: schema.confml
+Msg:  Element '{http://www.s60.com/xml/confml/2}foo': This element is not expected. Expected is one of ( {http://www.s60.com/xml/confml/2}desc, {http://www.s60.com/xml/confml/2}icon, {http://www.s60.com/xml/confml/2}link, {http://www.s60.com/xml/confml/2}option, {http://www.s60.com/xml/confml/2}property, {http://www.s60.com/xml/confml/2}setting, {http://www.s60.com/xml/confml/2}localPath, {http://www.s60.com/xml/confml/2}targetPath, {http://www.w3.org/2001/XMLSchema}minInclusive, {http://www.w3.org/2001/XMLSchema}maxInclusive ).
+
+File: assets/invalid/confml/invalid_type.confml
+Line: 4
+Type: schema.confml
+Msg:  Element '{http://www.s60.com/xml/confml/2}setting', attribute 'type': 'invalid_type' is not a valid value of the atomic type '{http://www.s60.com/xml/confml/2}typeType'.
+
+File: assets/invalid/confml/model_level_validation_test.confml
+Line: 10
+Type: model.confml.invalid_value.maxlength
+Msg:  Setting ValidationTest.Foo: Maximum number of characters is 3 (value has 6)
+
+File: assets/invalid/confml/model_level_validation_test.confml
+Line: 11
+Type: model.confml.missing_feature_for_data
+Msg:  Feature 'ValidationTest.Bar' not found
+
+File: assets/invalid/implml/broken.implml
+Line: 1
+Type: xml.implml
+Msg:  no element found: line 1, column 0
+
+File: assets/invalid/implml/duplicate_tempvar_ref.implml
+Line: 6
+Type: model.implml.container.duplicate_tempvar
+Msg:  Duplicate temporary variable ref 'Temp.Foo'
+
+File: assets/invalid/implml/duplicate_tempvar_ref.implml
+Line: 10
+Type: model.implml.container.duplicate_tempvar
+Msg:  Duplicate temporary variable ref 'Temp.Foo'
+
+File: assets/invalid/implml/invalid_attribute.implml
+Line: 4
+Type: schema.implml.implml
+Msg:  Element '{http://www.symbianfoundation.org/xml/implml/1}container', attribute 'foo': The attribute 'foo' is not allowed.
+
+File: assets/invalid/confml/invalid_element.confml
+Line: 8
+Type: model.confml.unknown_element
+Msg:  Unknown element '{http://www.s60.com/xml/confml/2}foo'
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/validate/expected/invalid_file_report.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,7 @@
+Validation problems
+-------------------
+File: testdata/validate/project/assets/invalid/confml/invalid_type.confml
+Line: 4
+Type: schema.confml
+Msg:  Element '{http://www.s60.com/xml/confml/2}setting', attribute 'type': 'invalid_type' is not a valid value of the atomic type '{http://www.s60.com/xml/confml/2}typeType'.
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/validate/expected/report.xml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<diamonds-build>
+	<quality aspect="SW Configurability">
+		<summary message="Total Problems" value="10"/>
+		<summary message="Total Errors" value="9"/>
+		<summary message="Total Warnings" value="1"/>
+    
+		<message severity="error" type="xml.confml" message="no element found: line 1, column 0" />
+    
+		<message severity="error" type="schema.confml" message="Element &#39;{http://www.s60.com/xml/confml/2}foo&#39;: This element is not expected. Expected is one of ( {http://www.s60.com/xml/confml/2}desc, {http://www.s60.com/xml/confml/2}icon, {http://www.s60.com/xml/confml/2}link, {http://www.s60.com/xml/confml/2}option, {http://www.s60.com/xml/confml/2}property, {http://www.s60.com/xml/confml/2}setting, {http://www.s60.com/xml/confml/2}localPath, {http://www.s60.com/xml/confml/2}targetPath, {http://www.w3.org/2001/XMLSchema}minInclusive, {http://www.w3.org/2001/XMLSchema}maxInclusive )." />
+    
+		<message severity="error" type="schema.confml" message="Element &#39;{http://www.s60.com/xml/confml/2}setting&#39;, attribute &#39;type&#39;: &#39;invalid_type&#39; is not a valid value of the atomic type &#39;{http://www.s60.com/xml/confml/2}typeType&#39;." />
+    
+		<message severity="error" type="model.confml.invalid_value.maxlength" message="Setting ValidationTest.Foo: Maximum number of characters is 3 (value has 6)" />
+    
+		<message severity="error" type="model.confml.missing_feature_for_data" message="Feature &#39;ValidationTest.Bar&#39; not found" />
+    
+		<message severity="error" type="xml.implml" message="no element found: line 1, column 0" />
+    
+		<message severity="error" type="model.implml.container.duplicate_tempvar" message="Duplicate temporary variable ref &#39;Temp.Foo&#39;" />
+    
+		<message severity="error" type="model.implml.container.duplicate_tempvar" message="Duplicate temporary variable ref &#39;Temp.Foo&#39;" />
+    
+		<message severity="error" type="schema.implml.implml" message="Element &#39;{http://www.symbianfoundation.org/xml/implml/1}container&#39;, attribute &#39;foo&#39;: The attribute &#39;foo&#39; is not allowed." />
+    
+		<message severity="warning" type="model.confml.unknown_element" message="Unknown element &#39;{http://www.s60.com/xml/confml/2}foo&#39;" />
+    
+	</quality> 
+</diamonds-build>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/validate/expected/report_multiple_filters.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,17 @@
+Validation problems
+-------------------
+File: assets/invalid/confml/model_level_validation_test.confml
+Line: 10
+Type: model.confml.invalid_value.maxlength
+Msg:  Setting ValidationTest.Foo: Maximum number of characters is 3 (value has 6)
+
+File: assets/invalid/implml/invalid_attribute.implml
+Line: 4
+Type: schema.implml.implml
+Msg:  Element '{http://www.symbianfoundation.org/xml/implml/1}container', attribute 'foo': The attribute 'foo' is not allowed.
+
+File: assets/invalid/confml/invalid_element.confml
+Line: 8
+Type: model.confml.unknown_element
+Msg:  Unknown element '{http://www.s60.com/xml/confml/2}foo'
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/validate/expected/report_only_confml.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,32 @@
+Validation problems
+-------------------
+File: assets/invalid/confml/broken.confml
+Line: 1
+Type: xml.confml
+Msg:  no element found: line 1, column 0
+
+File: assets/invalid/confml/invalid_element.confml
+Line: 8
+Type: schema.confml
+Msg:  Element '{http://www.s60.com/xml/confml/2}foo': This element is not expected. Expected is one of ( {http://www.s60.com/xml/confml/2}desc, {http://www.s60.com/xml/confml/2}icon, {http://www.s60.com/xml/confml/2}link, {http://www.s60.com/xml/confml/2}option, {http://www.s60.com/xml/confml/2}property, {http://www.s60.com/xml/confml/2}setting, {http://www.s60.com/xml/confml/2}localPath, {http://www.s60.com/xml/confml/2}targetPath, {http://www.w3.org/2001/XMLSchema}minInclusive, {http://www.w3.org/2001/XMLSchema}maxInclusive ).
+
+File: assets/invalid/confml/invalid_type.confml
+Line: 4
+Type: schema.confml
+Msg:  Element '{http://www.s60.com/xml/confml/2}setting', attribute 'type': 'invalid_type' is not a valid value of the atomic type '{http://www.s60.com/xml/confml/2}typeType'.
+
+File: assets/invalid/confml/model_level_validation_test.confml
+Line: 10
+Type: model.confml.invalid_value.maxlength
+Msg:  Setting ValidationTest.Foo: Maximum number of characters is 3 (value has 6)
+
+File: assets/invalid/confml/model_level_validation_test.confml
+Line: 11
+Type: model.confml.missing_feature_for_data
+Msg:  Feature 'ValidationTest.Bar' not found
+
+File: assets/invalid/confml/invalid_element.confml
+Line: 8
+Type: model.confml.unknown_element
+Msg:  Unknown element '{http://www.s60.com/xml/confml/2}foo'
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/validate/expected/report_only_implml.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,22 @@
+Validation problems
+-------------------
+File: assets/invalid/implml/broken.implml
+Line: 1
+Type: xml.implml
+Msg:  no element found: line 1, column 0
+
+File: assets/invalid/implml/duplicate_tempvar_ref.implml
+Line: 6
+Type: model.implml.container.duplicate_tempvar
+Msg:  Duplicate temporary variable ref 'Temp.Foo'
+
+File: assets/invalid/implml/duplicate_tempvar_ref.implml
+Line: 10
+Type: model.implml.container.duplicate_tempvar
+Msg:  Duplicate temporary variable ref 'Temp.Foo'
+
+File: assets/invalid/implml/invalid_attribute.implml
+Line: 4
+Type: schema.implml.implml
+Msg:  Element '{http://www.symbianfoundation.org/xml/implml/1}container', attribute 'foo': The attribute 'foo' is not allowed.
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/validate/expected/report_only_model.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,27 @@
+Validation problems
+-------------------
+File: assets/invalid/confml/model_level_validation_test.confml
+Line: 10
+Type: model.confml.invalid_value.maxlength
+Msg:  Setting ValidationTest.Foo: Maximum number of characters is 3 (value has 6)
+
+File: assets/invalid/confml/model_level_validation_test.confml
+Line: 11
+Type: model.confml.missing_feature_for_data
+Msg:  Feature 'ValidationTest.Bar' not found
+
+File: assets/invalid/implml/duplicate_tempvar_ref.implml
+Line: 6
+Type: model.implml.container.duplicate_tempvar
+Msg:  Duplicate temporary variable ref 'Temp.Foo'
+
+File: assets/invalid/implml/duplicate_tempvar_ref.implml
+Line: 10
+Type: model.implml.container.duplicate_tempvar
+Msg:  Duplicate temporary variable ref 'Temp.Foo'
+
+File: assets/invalid/confml/invalid_element.confml
+Line: 8
+Type: model.confml.unknown_element
+Msg:  Unknown element '{http://www.s60.com/xml/confml/2}foo'
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/validate/expected/report_only_schema.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,17 @@
+Validation problems
+-------------------
+File: assets/invalid/confml/invalid_element.confml
+Line: 8
+Type: schema.confml
+Msg:  Element '{http://www.s60.com/xml/confml/2}foo': This element is not expected. Expected is one of ( {http://www.s60.com/xml/confml/2}desc, {http://www.s60.com/xml/confml/2}icon, {http://www.s60.com/xml/confml/2}link, {http://www.s60.com/xml/confml/2}option, {http://www.s60.com/xml/confml/2}property, {http://www.s60.com/xml/confml/2}setting, {http://www.s60.com/xml/confml/2}localPath, {http://www.s60.com/xml/confml/2}targetPath, {http://www.w3.org/2001/XMLSchema}minInclusive, {http://www.w3.org/2001/XMLSchema}maxInclusive ).
+
+File: assets/invalid/confml/invalid_type.confml
+Line: 4
+Type: schema.confml
+Msg:  Element '{http://www.s60.com/xml/confml/2}setting', attribute 'type': 'invalid_type' is not a valid value of the atomic type '{http://www.s60.com/xml/confml/2}typeType'.
+
+File: assets/invalid/implml/invalid_attribute.implml
+Line: 4
+Type: schema.implml.implml
+Msg:  Element '{http://www.symbianfoundation.org/xml/implml/1}container', attribute 'foo': The attribute 'foo' is not allowed.
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/validate/expected/valid_config_report.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,2 @@
+Validation problems
+-------------------
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/validate/project/assets/invalid/confml/invalid_element.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+                      xmlns:confml="http://www.s60.com/xml/confml/2"
+                      xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2"
+                      name="Invalid element test">
+  <confml:feature ref="InvalidElementTest" name="Invalid element test">
+    <confml:setting ref="TestSetting" name="Test setting" type="string">
+        <confml:foo value="bar"/>
+    </confml:setting>
+  </confml:feature>
+  <confml:data>
+    <confml:InvalidElementTest>
+      <confml:TestSetting>test</confml:TestSetting>
+    </confml:InvalidElementTest>
+  </confml:data>
+</confml:configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/validate/project/assets/invalid/confml/invalid_type.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/2" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2" name="Invalid type test">
+  <confml:feature ref="InvalidTypeTest" name="Invalid type test">
+    <confml:setting ref="TestSetting" name="Test setting" type="invalid_type"/>
+  </confml:feature>
+  <confml:data>
+    <confml:InvalidTypeTest>
+      <confml:TestSetting>test</confml:TestSetting>
+    </confml:InvalidTypeTest>
+  </confml:data>
+</confml:configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/validate/project/assets/invalid/confml/model_level_validation_test.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns="http://www.s60.com/xml/confml/1" name="ValidationTest"  xmlns:xs="http://www.w3.org/2001/XMLSchema">
+    <feature ref="ValidationTest" name="Settings for ConfML model-level validation test">
+        <setting ref="Foo" name="Foo" type="string">
+            <xs:maxLength value="3"/>
+        </setting>
+    </feature>
+    <data>
+        <ValidationTest>
+            <Foo>foobar</Foo>
+            <Bar>baz</Bar>
+        </ValidationTest>
+    </data>
+</configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/validate/project/assets/invalid/implml/duplicate_tempvar_ref.implml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<container xmlns="http://www.symbianfoundation.org/xml/implml/1">
+    <!-- Duplicate tempVariable refs cannot be caught by schema validation, but
+         will be caught by model-level validation -->
+    <container>
+        <tempVariable ref="Temp.Foo"/>
+    </container>
+    
+    <container>
+        <tempVariable ref="Temp.Foo"/>
+    </container>
+</container>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/validate/project/assets/invalid/implml/invalid_attribute.implml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<container xmlns="http://www.symbianfoundation.org/xml/implml/1">
+    <!-- This is caught by schema validation -->
+    <container foo="bar"/>
+</container>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/validate/project/assets/invalid/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="ASCII"?>
+<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/1" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="http://www.w3.org/2001/XInclude http://www.s60.com/xml/confml/1#//include" name="asset1">
+  <xi:include href="confml/invalid_type.confml"/>
+  <xi:include href="confml/invalid_element.confml"/>
+  <xi:include href="confml/model_level_validation_test.confml"/>
+  <xi:include href="confml/broken.confml"/>
+</confml:configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/validate/project/assets/valid/confml/basic_setting_types_test.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/2" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2" name="Basic setting types test">
+  <confml:feature ref="BasicSettingTypesTest" name="Basic setting types test">
+    <confml:desc>Feature with basic setting types (ConfML v2.0)</confml:desc>
+    
+    <confml:setting ref="RealSetting" name="Real setting" type="real">
+      <confml:desc>A real setting</confml:desc>
+    </confml:setting>
+    
+    <confml:setting ref="IntSetting" name="Int setting" type="int">
+      <confml:desc>An int setting</confml:desc>
+    </confml:setting>
+    
+    <confml:setting ref="StringSetting" name="String setting" type="string">
+      <confml:desc>A string setting</confml:desc>
+    </confml:setting>
+    
+    <confml:setting ref="BooleanSetting" name="Boolean setting" type="boolean">
+      <confml:desc>A boolean setting</confml:desc>
+    </confml:setting>
+    
+    <confml:setting ref="SelectionSetting" name="Selection setting" type="selection">
+      <confml:desc>A selection setting</confml:desc>
+      <confml:option name="Option0" value="0"/>
+      <confml:option name="Option1" value="1"/>
+      <confml:option name="Option2" value="2"/>
+      <confml:option name="Option3" value="3"/>
+      <confml:option name="Option4" value="4"/>
+    </confml:setting>
+    
+    <confml:setting ref="MultiSelectionSetting" name="Multi-selection setting" type="multiSelection">
+      <confml:desc>A multi-selection setting</confml:desc>
+      <confml:option name="Option 0" value="opt 0"/>
+      <confml:option name="Option 1" value="opt 1"/>
+      <confml:option name="Option 2" value="opt 2"/>
+      <confml:option name="Option 3" value="opt 3"/>
+      <confml:option name="Option 4" value="opt 4"/>
+    </confml:setting>
+  </confml:feature>
+  
+  <confml:data>
+    <confml:BasicSettingTypesTest>
+      <confml:RealSetting>3.14</confml:RealSetting>
+      <confml:IntSetting>10</confml:IntSetting>
+      <confml:StringSetting>default string</confml:StringSetting>
+      <confml:BooleanSetting>true</confml:BooleanSetting>
+      <confml:SelectionSetting>1</confml:SelectionSetting>
+      <confml:MultiSelectionSetting>"opt 0" "opt 2" "opt 4"</confml:MultiSelectionSetting>
+    </confml:BasicSettingTypesTest>
+  </confml:data>
+  
+  <confml:rfs>
+    <confml:BasicSettingTypesTest>
+      <confml:RealSetting>true</confml:RealSetting>
+      <confml:IntSetting>false</confml:IntSetting>
+      <confml:StringSetting>false</confml:StringSetting>
+      <confml:BooleanSetting>true</confml:BooleanSetting>
+      <confml:SelectionSetting>true</confml:SelectionSetting>
+      <confml:MultiSelectionSetting>true</confml:MultiSelectionSetting>
+    </confml:BasicSettingTypesTest>
+  </confml:rfs>
+</confml:configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/validate/project/assets/valid/root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="ASCII"?>
+<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/1" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="http://www.w3.org/2001/XInclude http://www.s60.com/xml/confml/1#//include" name="asset1">
+  <xi:include href="confml/basic_setting_types_test.confml"/>
+</confml:configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/validate/project/errors_root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="ASCII"?>
+<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2 http://www.w3.org/2001/XInclude http://www.s60.com/xml/confml/1#//include">
+  <xi:include href="assets/invalid/root.confml"/>
+</confml:configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/validate/project/no_errors_root.confml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="ASCII"?>
+<confml:configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:confml="http://www.s60.com/xml/confml/2" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="http://www.s60.com/xml/confml/2 http://www.s60.com/xml/confml/1#//confml2 http://www.w3.org/2001/XInclude http://www.s60.com/xml/confml/1#//include">
+  <xi:include href="assets/valid/root.confml"/>
+</confml:configuration>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/testdata/validate/template.txt	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,9 @@
+Validation problems
+-------------------
+{% for problem in problems -%}
+File: {{problem.file}}
+Line: {{problem.line}}
+Type: {{problem.type}}
+Msg:  {{problem.msg}}
+
+{% endfor %}
\ No newline at end of file
--- a/configurationengine/source/scripts/tests/unittest_compare.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/tests/unittest_compare.py	Tue Aug 10 14:29:28 2010 +0300
@@ -24,7 +24,7 @@
 import shutil
 import subprocess
 import difflib
-import __init__
+
 from testautomation.base_testcase import BaseTestCase
 from scripttest_common import get_cmd
 
--- a/configurationengine/source/scripts/tests/unittest_cone.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/tests/unittest_cone.py	Tue Aug 10 14:29:28 2010 +0300
@@ -18,17 +18,22 @@
 Test the configuration
 """
 import unittest
-import string
-import sys
 import os
-import subprocess
-import __init__
+import re
+
 from testautomation.base_testcase import BaseTestCase
 from scripttest_common import get_cmd
 
 ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
 
 class TestConeHelp(BaseTestCase):    
+    
+    def test_get_version(self):
+        cmd = '%s --version' % get_cmd('')
+        out = self.run_command(cmd)
+        print "output from version %s" % out
+        lines = out.split(os.linesep)
+        self.assertTrue(re.match(r'^ConE\s+\d+\.\d+\.\d+.*$', lines[0]))
 
     def test_get_help(self):
         cmd = '%s -h' % get_cmd('')
@@ -40,7 +45,7 @@
         cmd = '%s info --print-runtime-info --verbose=5' % get_cmd('')
         out = self.run_command(cmd)
         # Check that there are debug messages in the output
-        self.assertTrue('DEBUG   : cone' in out)
+        self.assertTrue('DEBUG: cone' in out)
         self.assertTrue('sys.path contents:' in out)
     
     def test_empty_verbose_level(self):
@@ -97,6 +102,14 @@
         out = self.run_command(cmd)
         self.assertTrue("Level:DEBUG, Logger:cone, Message:sys.path contents:" in out, out)
 
+    def test_custom_log_config_with_escaping(self):
+        CONF_FILE = os.path.join(ROOT_PATH, 'testdata', 'log_config.ini')
+        LOG_FILE = os.path.join(ROOT_PATH, 'testdata', "log\\x\\cone.log")
+        cmd = '%s --log-config "%s" --log-file "%s"' % (get_cmd('info'), CONF_FILE, LOG_FILE)
+        out = self.run_command(cmd)
+        self.assertTrue("Level:DEBUG, Logger:cone, Message:sys.path contents:" in out, out)
+
+
 if __name__ == '__main__':
-      unittest.main()
-      
+    unittest.main()
+    
--- a/configurationengine/source/scripts/tests/unittest_export.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/tests/unittest_export.py	Tue Aug 10 14:29:28 2010 +0300
@@ -24,7 +24,7 @@
 import subprocess
 import zipfile
 import shutil
-import __init__
+
 from testautomation.base_testcase import BaseTestCase
 from testautomation.unzip_file import unzip_file
 from cone.storage.filestorage import FileStorage
@@ -52,7 +52,7 @@
     def test_get_help(self):
         cmd = '%s -h' % get_cmd('export')
         out = self.run_command(cmd)
-        lines = out.split('\r\n')
+        lines = out.split(os.linesep)
         self.assertTrue('Options:' in lines)
         self.assertTrue('  Export options:' in lines)
 
@@ -61,10 +61,10 @@
         self.remove_if_exists(remote)
         
         self.set_modification_reference_time(TEST_PROJECT_CPF)
-        cmd = '%s -p "%s" -c "root4.confml" -r "%s' % (get_cmd('export'), TEST_PROJECT_CPF, remote)
+        cmd = '%s -p "%s" -c "root4.confml" -r "%s"' % (get_cmd('export'), TEST_PROJECT_CPF, remote)
         out = self.run_command(cmd)
         #print out
-        lines = out.split('\r\n')
+        lines = out.split(os.linesep)
         self.assertTrue('Export root4.confml to %s done!' % remote in lines)
         
         self.assertEquals(set(os.listdir(remote)),
@@ -87,7 +87,7 @@
         cmd = '%s -p "%s" -c "root2.confml" -c "root3.confml" -c "root5.confml" -r "%s"' % (get_cmd('export'), TEST_PROJECT_CPF, remote)
         out = self.run_command(cmd)
         #print out
-        lines = out.split('\r\n')
+        lines = out.split(os.linesep)
         self.assertTrue('Export root2.confml to %s done!' % remote in lines)
         self.assertTrue('Export root3.confml to %s done!' % remote in lines)
         self.assertTrue('Export root5.confml to %s done!' % remote in lines)
@@ -116,7 +116,7 @@
         cmd = '%s -p "%s" -c "root2.confml" -c "root3.confml" -c "root5.confml" -r "%s"' % (get_cmd('export'), TEST_PROJECT_CPF, remote)
         out = self.run_command(cmd)
         #print out
-        lines = out.split('\r\n')
+        lines = out.split(os.linesep)
         self.assertTrue('Export root2.confml to %s done!' % remote in lines)
         self.assertTrue('Export root3.confml to %s done!' % remote in lines)
         self.assertTrue('Export root5.confml to %s done!' % remote in lines)
@@ -275,9 +275,28 @@
             target_storage_type = 'file',
             empty_folders       = True)
     
+    def test_export_to_target_with_nonexistent_path(self):
+        # Remove the target root directory to make sure that it
+        # does not exist before the export
+        self.remove_if_exists(os.path.join(TEMP_DIR, 'nep'))
+        
+        self._run_test_export_project_to_project(
+            source_project      = 'f2z/source',
+            source_storage_type = 'file',
+            target_project      = 'nep/f2z/x/y/z/target.zip',
+            target_storage_type = 'zip',
+            empty_folders       = False)
+    
+        self._run_test_export_project_to_project(
+            source_project      = 'f2z/source',
+            source_storage_type = 'file',
+            target_project      = 'nep/f2f/x/y/z/target',
+            target_storage_type = 'file',
+            empty_folders       = False)
+    
     def _run_test_multi_export(self, export_dir, export_format, config_args,
                                expected_cpfs=None, expected_dirs=None):
-        self.assertFalse(expected_cpfs is None and expected_dirs is None,
+        self.assertFalse(expected_cpfs is not None and expected_dirs is not None,
                          "Only one of expected_cpfs or expected_dirs can be specified!")
         self.assertFalse(expected_cpfs is None and expected_dirs is None,
                          "Either expected_cpfs or expected_dirs must be specified!")
@@ -413,4 +432,4 @@
     
 
 if __name__ == '__main__':
-      unittest.main()
+    unittest.main()
--- a/configurationengine/source/scripts/tests/unittest_generate.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/tests/unittest_generate.py	Tue Aug 10 14:29:28 2010 +0300
@@ -17,8 +17,9 @@
 ## 
 # @author Teemu Rytkonen
 
-import sys, os, shutil, unittest
-import __init__
+import os, unittest
+import tempfile
+
 from testautomation.base_testcase import BaseTestCase
 from testautomation import zip_dir
 from scripttest_common import get_cmd
@@ -29,11 +30,10 @@
 rootconf = 'root3.confml'
 
 class TestGenerate(BaseTestCase):
-
     def test_get_help(self):
         cmd = '%s -h' % get_cmd('generate')
         out = self.run_command(cmd)
-        lines = out.split('\r\n')
+        lines = out.split(os.linesep)
         self.assertTrue('Options:' in lines)
         self.assertTrue('  Generate options:' in lines)
 
@@ -46,7 +46,39 @@
         self.assert_exists_and_contains_something(OUTPUT_DIR)
         
         self.assert_not_modified(testproject)
-    
+            
+    def test_generate_output_file_from_script(self):
+        testproject = os.path.join(ROOT_PATH, 'testdata/generate/impl_container/project')
+        self.set_modification_reference_time(testproject)
+        OUTPUT_DIR = os.path.join(ROOT_PATH, 'temp/output')
+        self.remove_if_exists(OUTPUT_DIR)
+        LOGFILE = os.path.join(OUTPUT_DIR, 'cone_temp.log')
+        cmd = '%s -p "%s" -c "%s" -o "%s" --log-file "%s"' % (get_cmd('generate'),
+                                                                          testproject,
+                                                                          'base_root.confml',
+                                                                          OUTPUT_DIR,
+                                                                          LOGFILE)
+        out = self.run_command(cmd)
+
+        self.assertEquals(True, os.path.isfile(os.path.join(OUTPUT_DIR, 'output_test.txt')))
+        self.assert_not_modified(testproject)
+
+    def test_generate_with_absolute_path(self):
+        self.set_modification_reference_time(testproject)
+        tempdir = os.path.join(tempfile.gettempdir(), 'cone_output')
+        (drive,OUTPUT_DIR) = os.path.splitdrive(os.path.abspath(tempdir))
+        LOGFILE = os.path.join(OUTPUT_DIR, 'cone_temp.log')
+        self.remove_if_exists(OUTPUT_DIR)
+        cmd = '%s -p "%s" -c "%s" -o "%s" --log-file "%s"' % (get_cmd('generate'),
+                                                            testproject,
+                                                            rootconf,
+                                                            OUTPUT_DIR,
+                                                            LOGFILE)
+        out = self.run_command(cmd)
+        self.assert_exists_and_contains_something(OUTPUT_DIR)
+        self.assertTrue(os.path.exists(LOGFILE))
+        self.assert_not_modified(testproject)
+
     def test_generate_with_report(self):
         self.set_modification_reference_time(testproject)
         OUTPUT_DIR  = os.path.join(ROOT_PATH, 'temp/gen2/output')
@@ -108,8 +140,43 @@
             report_file   = 'temp/gen7/report.csv',
             template_path = os.path.join(ROOT_PATH,'test_template/template2.csv'))
 
+    def test_generate_with_errors_in_project(self):
+        project = os.path.join(ROOT_PATH, 'testdata/generate/error_test_project')
+        
+        OUTPUT_DIR  = os.path.join(ROOT_PATH, 'temp/gen_err/output')
+        REPORT_FILE = os.path.join(ROOT_PATH, 'temp/gen_err/report.html')
+        LOG_FILE = os.path.join(ROOT_PATH, 'temp/gen_err/cone.log')
+        self.remove_if_exists([OUTPUT_DIR, REPORT_FILE, LOG_FILE])
+        cmd = '%s -p "%s" -c root.confml -o "%s" -r "%s" --log-file "%s"' % (get_cmd('generate'),project, OUTPUT_DIR, REPORT_FILE, LOG_FILE)
+        out = self.run_command(cmd)
+        
+        # Check that output and report are generated even though
+        # there are errors in the project
+        self.assert_exists_and_contains_something(OUTPUT_DIR)
+        self.assert_exists_and_contains_something(REPORT_FILE)
+        self.assert_exists_and_contains_something(LOG_FILE)
+        
+        # Check that the errors are shown in the log correctly
+        self.assert_file_contains(LOG_FILE,
+            ['''ERROR   : cone.rules Exception in get_refs() of relation ConfigureRelation(ref='layer1/implml/rules_with_errors.implml', lineno=11): Expression is None''',
+             '''ERROR   : cone Error executing rule ConfigureRelation(ref='layer1/implml/rules_with_errors.implml', lineno=11): ParseException: Syntax error: " configures ${TempFeature.Int} = 6000"''',
+             '''ERROR   : cone Error executing rule ConfigureRelation(ref='layer1/implml/rules_with_errors.implml', lineno=12): ParseException: Syntax error: "True configures "'''])
+        
+        # Check that the errors are shown in the report correctly
+        self.assert_file_contains(REPORT_FILE, data=[],
+            regexes=[r'Exception:\s*layer1/implml/rules_with_errors.implml:11',
+                     r'Exception:\s*layer1/implml/rules_with_errors.implml:12'])
+        
+        # Check from the output that the other rules were successfully
+        # executed
+        self.assert_file_contains(
+            os.path.join(OUTPUT_DIR, 'content/rules_with_errors_test.txt'),
+            ['TempFeature.String:  testing and more testing',
+            'TempFeature.Int:     501',
+            'TempFeature.Real:    1.75',
+            'TempFeature.Boolean: True'])
+
 class TestGenerateAllImplsOnLastLayer(BaseTestCase):
-    
     def _prepare_workdir(self, workdir):
         workdir = os.path.join(ROOT_PATH, workdir)
         self.recreate_dir(workdir)
@@ -176,13 +243,12 @@
             self.assert_dir_contents_equal('output', EXPECTED_DIR, ['.svn'])
             
             # Check that output has also been generated to the overridden output root directory
-            self.assert_exists_and_contains_something('overridden_output/output_rootdir_test.txt')
-            self.assert_exists_and_contains_something('overridden_output/test_subdir/output_rootdir_test.txt')
+            #self.assert_exists_and_contains_something('overridden_output/output_rootdir_test.txt')
+            #self.assert_exists_and_contains_something('overridden_output/test_subdir/output_rootdir_test.txt')
         finally:
             os.chdir(orig_workdir)
 
 class TestGenerationImplFilteringByTags(BaseTestCase):
-    
     def test_no_tag_filtering(self):
         self._run_tag_filtering_test(
             name     = 'no_filter',
@@ -264,6 +330,7 @@
         self.remove_if_exists(OUTPUT)
         
         cmd = '%s -p "%s" --output "%s" --log-file="%s" %s' % (get_cmd('generate'), PROJECT, OUTPUT, LOG, filter)
+        #print cmd
         self.run_command(cmd)
         
         self.assert_exists_and_contains_something(OUTPUT)
@@ -273,5 +340,198 @@
         
         self.assertEquals(expected_files, actual_files)
 
+class TestGenerationImplFilteringByLayers(BaseTestCase):
+    def test_filter_by_last_layer(self):
+        self._run_layer_filtering_test(
+            name     = 'll1',
+            filter   = '--layer -1',
+            expected = ['layer3'])
+    
+    def test_filter_by_two_last_layers(self):
+        self._run_layer_filtering_test(
+            name     = 'll2',
+            filter   = '--layer -1 --layer 2',
+            expected = ['layer2', 'layer3'])
+    
+    def test_filter_by_regex_1(self):
+        self._run_layer_filtering_test(
+            name     = 'r1',
+            filter   = '--layer-regex layer[13]',
+            expected = ['layer1', 'layer3'])
+    
+    def test_filter_by_regex_2(self):
+        self._run_layer_filtering_test(
+            name     = 'r2',
+            filter   = '--layer-regex [12]/root.confml',
+            expected = ['layer1', 'layer2'])
+    
+    def test_filter_by_regex_3(self):
+        self._run_layer_filtering_test(
+            name     = 'r3',
+            filter   = '--layer-regex layer1 --layer-regex layer3',
+            expected = ['layer1', 'layer3'])
+    
+    def test_filter_by_wildcard(self):
+        self._run_layer_filtering_test(
+            name     = 'w',
+            filter   = '--layer-wildcard *layer*',
+            expected = ['layer1', 'layer2', 'layer3'])
+    
+    def _run_layer_filtering_test(self, name, filter, expected):
+        PROJECT = os.path.join(ROOT_PATH, 'testdata/generate/layer_filtering_project')
+        
+        OUTPUT_ROOT = os.path.join(ROOT_PATH, 'temp/gen_lf/', name)
+        OUTPUT      = os.path.join(OUTPUT_ROOT, 'out')
+        LOG         = os.path.join(OUTPUT_ROOT, 'cone.log')
+        self.remove_if_exists(OUTPUT)
+        
+        cmd = '%s -p "%s" --output "%s" --log-file="%s" %s' % (get_cmd('generate'), PROJECT, OUTPUT, LOG, filter)
+        #print cmd
+        self.run_command(cmd)
+        
+        self.assert_exists_and_contains_something(OUTPUT)
+        
+        expected_files = sorted([x + '.txt' for x in expected])
+        actual_files = sorted(os.listdir(OUTPUT))
+        
+        # Ignore the rule output txt files
+        for f in ('rule_test_v2.txt', 'rule_test_v3.txt'):
+            if f in actual_files: del actual_files[actual_files.index(f)]
+        self.assertEquals(expected_files, actual_files)
+        
+        # Check that the correct rules have been executed
+        expected_str = ' ' + ' '.join(sorted(expected)) + ' x'
+        self.assert_file_content_equals(os.path.join(OUTPUT, 'rule_test_v2.txt'), expected_str)
+        self.assert_file_content_equals(os.path.join(OUTPUT, 'rule_test_v3.txt'), expected_str)
+
+class TestGenerateInvalidParameters(BaseTestCase):
+    PROJECT = os.path.join(ROOT_PATH, 'testdata/generate/layer_filtering_project')
+    
+    def _run_test(self, args, expected_msg):
+        if not isinstance(args, basestring):
+            args = ' '.join(args)
+        
+        cmd = get_cmd('generate') + ' ' + args
+        # Note: The following run_command() should really expect the
+        #       return code 2, but for some reason when running from the
+        #       standalone test set, the return value is 0 for some cases
+        #       (specifically, the ones that don't use parser.error() to
+        #       exit the program)
+        out = self.run_command(cmd, expected_return_code = None)
+        
+        self.assertTrue(expected_msg in out,
+                        "Expected message '%s' not in output ('%s')" % (expected_msg, out))
+    
+    def test_invalid_layer_index_1(self):
+        self._run_test(
+            '-p "%s" --layer -1 --layer foobar' % self.PROJECT,
+            "option --layer: invalid integer value: 'foobar'")
+    
+    def test_invalid_layer_index_2(self):
+        self._run_test(
+            '-p "%s" --layer -1 --layer 7' % self.PROJECT,
+            'Invalid layer index: 7')
+    
+    def test_no_matching_layer_for_regex(self):
+        self._run_test(
+            '-p "%s" --layer-regex foo' % self.PROJECT,
+            'No layers matched by layer patterns')
+    
+    def test_no_matching_layer_for_wildcard(self):
+        self._run_test(
+            '-p "%s" --layer-wildcard foo' % self.PROJECT,
+            'No layers matched by layer patterns')
+
+class TestGenerateImplContainer(BaseTestCase):
+    def _run_test(self, root, args):
+        PROJECT = os.path.join(ROOT_PATH, 'testdata/generate/impl_container/project')
+        EXPECTED = os.path.join(ROOT_PATH, 'testdata/generate/impl_container/expected', root)
+        
+        OUTPUT_ROOT = os.path.join(ROOT_PATH, 'temp/gen_ic/', root)
+        OUTPUT      = os.path.join(OUTPUT_ROOT, 'out')
+        LOG         = os.path.join(OUTPUT_ROOT, 'cone.log')
+        self.remove_if_exists(OUTPUT)
+        
+        cmd = '%s -p "%s" -c %s --output "%s" --log-file="%s" %s' % (get_cmd('generate'), PROJECT, root, OUTPUT, LOG, args)
+        #print cmd
+        self.run_command(cmd)
+        
+        self.assert_dir_contents_equal(EXPECTED, OUTPUT, ['.svn'])
+    
+    def test_implcontainer_with_triggering_rule_and_templateml(self):
+        self._run_test(
+            root = 'data_root.confml',
+            args = '--layer -1')
+
+class TestGenerateSetTempvarValue(BaseTestCase):
+    def test_set_tempvar_value_from_cmdline(self):
+        PROJECT = os.path.join(ROOT_PATH, 'generation_test_project')
+        
+        OUTPUT_ROOT = os.path.join(ROOT_PATH, 'temp/gen_tvs/')
+        OUTPUT      = os.path.join(OUTPUT_ROOT, 'out')
+        LOG         = os.path.join(OUTPUT_ROOT, 'cone.log')
+        self.remove_if_exists(OUTPUT)
+        
+        cmd = ['%(cone_cmd)s',
+               '-p "%(project)s"',
+               '-c root.confml',
+               '--output "%(output)s"',
+               '--log-file="%(log_file)s"',
+               '--impl simple_tempvar',
+               '--set "TempFeature.String=testing from cmdline"',
+               '--set "TempFeature.Int=8090"',
+               '--set "TempFeature.Real=-5.75"',]
+        cmd = ' '.join(cmd) % {'cone_cmd':  get_cmd('generate'),
+                               'project':   PROJECT,
+                               'output':    OUTPUT,
+                               'log_file':  LOG}
+        #print cmd
+        self.run_command(cmd)
+        
+        self.assert_file_contains(
+            os.path.join(OUTPUT, 'content', 'simple_tempvars_test.txt'),
+            ['TempFeature.String:  testing from cmdline and more testing',
+             'TempFeature.Int:     8091',
+             'TempFeature.Real:    -5.5'])
+
+class TestGenerateWhatOutput(BaseTestCase):
+    PROJECT = os.path.join(ROOT_PATH, 'generation_test_project')
+    OUTPUT_ROOT = os.path.join(ROOT_PATH, 'temp/gen_wop')
+    OUTPUT      = os.path.join(OUTPUT_ROOT, 'out')
+    LOG         = os.path.join(OUTPUT_ROOT, 'cone.log')
+    WHAT_FILE   = os.path.join(OUTPUT_ROOT, 'what_output.txt')
+    CMP_FILE    = os.path.join(PROJECT, 'what_output.txt')
+    
+    def test_write_what_out(self):        
+        self.remove_if_exists(self.OUTPUT)
+        
+        cmd = ['%(cone_cmd)s',
+               '-p "%(project)s"',
+               '-c root.confml',
+               '--what="%(what_file)s"',
+               '--output "%(output)s"',
+               '--log-file="%(log_file)s"',
+               '--all-layers',]
+        cmd = ' '.join(cmd) % {'cone_cmd':      get_cmd('generate'),
+                               'project':       self.PROJECT,
+                               'what_file':     self.WHAT_FILE,
+                               'output':        self.OUTPUT,
+                               'log_file':      self.LOG}
+        self.run_command(cmd)
+        
+        cmp_what_out_fh = open(self.CMP_FILE, 'r')
+        cmp_files = []
+        try: cmp_files = cmp_what_out_fh.readlines()
+        finally: cmp_what_out_fh.close()
+            
+        self.assert_exists_and_contains_something(self.WHAT_FILE)
+        self.assert_file_contains(self.WHAT_FILE, [self._flip(c.strip()) for c in cmp_files])
+        
+    def _flip(self, path):
+        newpath= path.replace('\\', os.sep)
+        newpath = newpath.replace('/', os.sep)
+        return newpath
+        
+
 if __name__ == '__main__':
-      unittest.main()
+    unittest.main()
--- a/configurationengine/source/scripts/tests/unittest_info.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/tests/unittest_info.py	Tue Aug 10 14:29:28 2010 +0300
@@ -22,7 +22,7 @@
 import sys
 import os
 import subprocess
-import __init__
+
 from testautomation.base_testcase import BaseTestCase
 from scripttest_common import get_cmd
 
@@ -36,7 +36,7 @@
     def test_get_help(self):
         cmd = '%s -h' % get_cmd('info')
         out = self.run_command(cmd)
-        lines = out.split('\r\n')
+        lines = out.split(os.linesep)
         self.assertTrue('Options:' in lines)
         self.assertTrue('  Info options:' in lines)
     
@@ -46,7 +46,7 @@
         cmd = '%s -p "%s"' % (get_cmd('info'), testproject)
         out = self.run_command(cmd)
         
-        lines = out.split('\r\n')
+        lines = out.split(os.linesep)
         self.assertTrue('Configurations in the project.' in lines)
         self.assertTrue('root1.confml' in lines)
         self.assertTrue('root2.confml' in lines)
@@ -56,6 +56,22 @@
         
         self.assert_not_modified(testproject)
     
+    def test_print_active_root(self):
+        cmd = '%s -p "%s" --print-active-root' % (get_cmd('info'), testproject)
+        out = self.run_command(cmd)
+        self.assertTrue('Active root: root5.confml' in out)
+        
+        project = os.path.join(ROOT_PATH,'test_variant.cpf')
+        cmd = '%s -p "%s" --print-active-root' % (get_cmd('info'), project)
+        out = self.run_command(cmd)
+        self.assertTrue('Active root: root.confml' in out)
+        
+        project = os.path.join(ROOT_PATH, 'testdata/info/no_active_root.cpf')
+        cmd = '%s -p "%s" --print-active-root' % (get_cmd('info'), project)
+        out = self.run_command(cmd)
+        self.assertTrue('No active root.' in out)
+        
+    
     def test_api_report(self):
         EXPECTED_FILE = os.path.join(ROOT_PATH, 'testdata/info/expected/api_report.html')
         REPORT_FILE = os.path.join(temp_dir, 'api_report.html')
@@ -163,7 +179,7 @@
         self._run_test_value_report(
             output   = 'value_report_langpacks_regex.html',
             expected = 'value_report_langpacks.html',
-            args     = '--config-regex product_langpack_\\d{2}_root.confml')
+            args     = '--config-regex product_langpack_[0-9]{2}_root.confml')
     
     def test_value_report_multi_config(self):
         self._run_test_value_report(
@@ -218,8 +234,11 @@
         EXPECTED_FILE = os.path.join(ROOT_PATH, 'testdata/info/expected/value_report_custom.html')
         REPORT_FILE = os.path.join(temp_dir, 'value_report_custom.html')
         self.remove_if_exists(REPORT_FILE)
-        cmd = '%s -p "%s" --template "%s" --report "%s" -c product_root.confml' \
-            % (get_cmd('info'), VALUE_REPORT_PROJECT, TEMPLATE_FILE, REPORT_FILE)
+        cmd = '%s -p "%s" --template "%s" --log-file="%s" --report "%s" -c product_root.confml' \
+            % (get_cmd('info'), VALUE_REPORT_PROJECT, 
+                                TEMPLATE_FILE, 
+                                os.path.join(temp_dir, 'value_report_custom_cone.log'),
+                                REPORT_FILE)
         out = self.run_command(cmd)
         
         self.assert_file_contents_equal(EXPECTED_FILE, REPORT_FILE)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/unittest_initvariant.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,99 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+"""
+Test the configuration
+"""
+import unittest
+import os
+
+from testautomation.base_testcase import BaseTestCase
+from testautomation import unzip_file
+from scripttest_common import get_cmd
+from cone.public import api
+
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+TESTDATA_DIR = os.path.join(ROOT_PATH, 'testdata/initvariant')
+TEMP_DIR = os.path.join(ROOT_PATH, 'temp/initvariant')
+TEST_VARIANT_CPF = os.path.join(TESTDATA_DIR, 'variant.cpf')
+
+
+class TestInitVariant(BaseTestCase):
+    
+    def _prepare_workdir(self, subdir, expected_zip):
+        WORKDIR = os.path.join(TEMP_DIR, subdir)
+        PROJECT_DIR = os.path.join(WORKDIR, 'project')
+        EXPECTED_DIR = os.path.join(WORKDIR, 'expected')
+        
+        self.remove_if_exists(WORKDIR)
+        
+        unzip_file.unzip_file(
+            os.path.join(TESTDATA_DIR, 'test_project.zip'),
+            PROJECT_DIR)
+        unzip_file.unzip_file(
+           os.path.join(TESTDATA_DIR, expected_zip),
+           EXPECTED_DIR)
+        
+        return PROJECT_DIR, EXPECTED_DIR
+        
+    
+    def _get_active_configuration(self, project):
+        p = api.Project(api.Storage.open(project, 'r'))
+        active_root = p.get_storage().get_active_configuration()
+        p.close()
+        return active_root
+    
+    def test_initvariant(self):
+        PROJECT_DIR, EXPECTED_DIR = self._prepare_workdir('var1', 'expected.zip')
+        
+        self.assertEquals(self._get_active_configuration(PROJECT_DIR), None)
+        
+        cmd = '%s -p "%s" -r "%s" --variant-id 123 --variant-name foo --set-active-root' % (get_cmd('initvariant'), PROJECT_DIR, TEST_VARIANT_CPF)
+        self.run_command(cmd)
+        
+        self.assert_dir_contents_equal(PROJECT_DIR, EXPECTED_DIR, ['.svn', '.metadata'])
+        self.assertEquals(self._get_active_configuration(PROJECT_DIR),
+                          'testprod_custvariant_123_foo_root.confml')
+    
+    
+    def test_initvariant_2(self):
+        PROJECT_DIR, EXPECTED_DIR = self._prepare_workdir('var2', 'expected2.zip')
+        
+        self.assertEquals(self._get_active_configuration(PROJECT_DIR), None)
+        
+        cmd = '%s -p "%s" -r "%s" -c foovariant.confml --variant-id 321' % (get_cmd('initvariant'), PROJECT_DIR, TEST_VARIANT_CPF)
+        self.run_command(cmd)
+        
+        self.assert_dir_contents_equal(PROJECT_DIR, EXPECTED_DIR, ['.svn', '.metadata'])
+        self.assertEquals(self._get_active_configuration(PROJECT_DIR), None)
+
+
+    def test_initvariant_based_on_configuration(self):
+        PROJECT_DIR, EXPECTED_DIR = self._prepare_workdir('var3', 'expected3.zip')
+        
+        self.assertEquals(self._get_active_configuration(PROJECT_DIR), None)
+        
+        cmd = '%s -p "%s" -c foovariant.confml --variant-id=123 -b testprod_custvariant_root.confml' % (get_cmd('initvariant'), PROJECT_DIR)
+
+        self.run_command(cmd)
+        
+        self.assert_dir_contents_equal(PROJECT_DIR, EXPECTED_DIR, ['.svn', '.metadata'])
+        self.assertEquals(self._get_active_configuration(PROJECT_DIR), None)
+
+
+if __name__ == '__main__':
+    unittest.main()
--- a/configurationengine/source/scripts/tests/unittest_merge.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/tests/unittest_merge.py	Tue Aug 10 14:29:28 2010 +0300
@@ -21,7 +21,7 @@
 import os
 import shutil
 import zipfile
-import __init__
+
 from testautomation.base_testcase import BaseTestCase
 from testautomation import unzip_file
 from scripttest_common import get_cmd
@@ -86,7 +86,7 @@
     def test_get_help(self):
         cmd = '%s -h' % get_cmd('merge')
         out = self.run_command(cmd)
-        lines = out.split('\r\n')
+        lines = out.split(os.linesep)
         self.assertTrue('Options:' in lines)
         self.assertTrue('  Merge options:' in lines)
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/unittest_packvariant.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,115 @@
+# *-* coding: utf-8 *-*
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+## 
+# @author Teemu Rytkonen
+
+import os, unittest
+
+from testautomation import unzip_file
+from testautomation.base_testcase import BaseTestCase
+from scripttest_common import get_cmd
+
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+rootconf = 'testprod_custvariant_root.confml'
+
+TESTDATA_DIR = os.path.join(ROOT_PATH, 'testdata/packvariant')
+TEMP_DIR = os.path.join(ROOT_PATH, 'temp/packvariant')
+
+class TestPackvariant(BaseTestCase):
+    def test_get_help(self):
+        cmd = '%s -h' % get_cmd('packvariant')
+        out = self.run_command(cmd)
+        lines = out.split(os.linesep)
+        self.assertTrue('Options:' in lines)
+        self.assertTrue('  Packvariant options:' in lines)
+
+    def test_packvariant(self):
+        PROJECT_DIR = os.path.join(ROOT_PATH, TESTDATA_DIR, 'project')
+        REMOTE_ZIP = os.path.join(ROOT_PATH, TEMP_DIR, 'output/packvariant.zip')
+        EXPECTED_ZIP = os.path.join(ROOT_PATH, TESTDATA_DIR, 'expected/packvariant.zip')
+
+        self.remove_if_exists(REMOTE_ZIP)
+        cmd = '%s -p "%s" -c "%s" -r "%s"' % (get_cmd('packvariant'),PROJECT_DIR,rootconf,REMOTE_ZIP)
+        out = self.run_command(cmd)
+        self.assert_exists_and_contains_something(REMOTE_ZIP)
+        
+        REMOTE_TEMP_DIR = os.path.join(TEMP_DIR, 'output/remote')
+        EXPECTED_TEMP_DIR = os.path.join(TEMP_DIR, 'output/expected')
+
+        self.remove_if_exists(REMOTE_TEMP_DIR)    
+        self.remove_if_exists(EXPECTED_TEMP_DIR)    
+
+        unzip_file.unzip_file(
+            REMOTE_ZIP,
+            REMOTE_TEMP_DIR)
+        unzip_file.unzip_file(
+            EXPECTED_ZIP,
+            EXPECTED_TEMP_DIR)
+        
+        self.assert_dir_contents_equal(REMOTE_TEMP_DIR, EXPECTED_TEMP_DIR, ignore=['.svn'])
+
+    def test_packvariant_project_does_not_exist(self):
+        PROJECT_DIR = os.path.join(ROOT_PATH, TESTDATA_DIR, 'project_does_not_exist')
+        REMOTE_ZIP = os.path.join(ROOT_PATH, TEMP_DIR, 'output/packvariant.zip')
+
+        self.remove_if_exists(REMOTE_ZIP)
+        cmd = '%s -p "%s" -c "%s" -r "%s"' % (get_cmd('packvariant'),PROJECT_DIR,rootconf,REMOTE_ZIP)
+        
+        self._run_test(
+           cmd, 2,
+           "Could not create Zip archive: The given data folder for storage does not exist!")
+
+
+    def test_packvariant_configuration_does_not_exist(self):
+        PROJECT_DIR = os.path.join(ROOT_PATH, TESTDATA_DIR, 'project')
+        REMOTE_ZIP = os.path.join(ROOT_PATH, TEMP_DIR, 'output', 'packvariant.zip')
+        rootconf = 'root_does_not_exist.confml'
+        expected_msg = "Could not create Zip archive: Child root_does_not_exist_confml not found from Project"
+        
+        self.remove_if_exists(REMOTE_ZIP)
+        cmd = '%s -p "%s" -c "%s" -r "%s"' % (get_cmd('packvariant'),PROJECT_DIR,rootconf,REMOTE_ZIP)
+        out = self.run_command(cmd, None)
+        
+        self.assertTrue(expected_msg in out,
+                "Expected message '%s' not in output ('%s')" % (expected_msg, out))
+        
+
+    def test_packvariant_project_is_not_a_folder(self):
+        PROJECT_DIR = os.path.join(ROOT_PATH, TESTDATA_DIR, 'packvariant/project/testprod_custvariant_root.confml')
+        REMOTE_ZIP = os.path.join(ROOT_PATH, TEMP_DIR, 'output/packvariant.zip')
+
+        self.remove_if_exists(REMOTE_ZIP)
+        cmd = '%s -p "%s" -c "%s" -r "%s"' % (get_cmd('packvariant'),PROJECT_DIR,rootconf,REMOTE_ZIP)
+        
+        self._run_test(
+           cmd, 1,
+           "ERROR: --Project must be a directory. Terminating the program.")
+
+
+    def _run_test(self, args, expected_return_code, expected_msg):
+        if not isinstance(args, basestring):
+            args = ' '.join(args)
+        
+        cmd = get_cmd('packvariant') + ' ' + args
+        out = self.run_command(cmd, expected_return_code = None)
+        
+        self.assertTrue(expected_msg in out,
+                        "Expected message '%s' not in output ('%s')" % (expected_msg, out))
+
+if __name__ == '__main__':
+    unittest.main()
--- a/configurationengine/source/scripts/tests/unittest_report.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/tests/unittest_report.py	Tue Aug 10 14:29:28 2010 +0300
@@ -15,7 +15,7 @@
 #
 
 import sys, os, shutil, unittest
-import __init__
+
 from testautomation.base_testcase import BaseTestCase
 from testautomation import zip_dir
 from scripttest_common import get_cmd
@@ -31,7 +31,7 @@
     def _test_get_help(self):
         cmd = '%s -h' % get_cmd('report')
         out = self.run_command(cmd)
-        lines = out.split('\r\n')
+        lines = out.split(os.linesep)
         self.assertTrue('Options:' in lines)
         self.assertTrue('  Report options:' in lines)
     
@@ -65,8 +65,8 @@
         REPORT_DATA_FILE = os.path.join(TEMP_DIR, report_data_file)
         self.remove_if_exists(OUTPUT_DIR)
         
-        cmd = '%s -p "%s" -o "%s" --report-data-output "%s" --impl-tag target:%s' \
-            % (get_cmd('generate'), TEST_PROJECT, OUTPUT_DIR, REPORT_DATA_FILE, target_tag)
+        cmd = '%s -p "%s" -o "%s" --log-file="%s" --report-data-output "%s" --impl-tag target:%s' \
+            % (get_cmd('generate'), TEST_PROJECT, OUTPUT_DIR, os.path.join(OUTPUT_DIR,'cone.log'), REPORT_DATA_FILE, target_tag)
         self.run_command(cmd)
         self.assert_exists_and_contains_something(OUTPUT_DIR)
         self.assert_exists_and_contains_something(REPORT_DATA_FILE)
@@ -82,7 +82,10 @@
         REPORT_FILE = os.path.join(TEMP_DIR, report_file)
         self.remove_if_exists(REPORT_FILE)
         
-        cmd = '%s --report "%s" --template "%s" ' % (get_cmd('report'), REPORT_FILE, TEMPLATE_FILE)
+        cmd = '%s --report "%s" --log-file="%s" --template "%s" ' % (get_cmd('report'),
+                                                                     REPORT_FILE,
+                                                                     os.path.join(TEMP_DIR,'cone_report.log'),
+                                                                     TEMPLATE_FILE)
         cmd += ' '.join(['--input-data "%s"' % f for f in report_data_files])
         self.run_command(cmd)
         self.assert_exists_and_contains_something(REPORT_FILE)
@@ -97,11 +100,15 @@
         REPORT_FILE = os.path.join(TEMP_DIR, report_file)
         self.remove_if_exists(REPORT_FILE)
         
-        cmd = '%s --report "%s" --template "%s" --input-data-dir "%s"' \
-            % (get_cmd('report'), REPORT_FILE, TEMPLATE_FILE, report_data_dir)
+        cmd = '%s --report "%s" --log-file="%s" --template "%s" --input-data-dir "%s"' \
+            % (get_cmd('report'), REPORT_FILE, 
+                                  os.path.join(TEMP_DIR,'cone_report_from_dir.log'),
+                                  TEMPLATE_FILE, 
+                                  report_data_dir)
         self.run_command(cmd)
         self.assert_exists_and_contains_something(REPORT_FILE)
         return REPORT_FILE
 
+
 if __name__ == '__main__':
-      unittest.main()
+    unittest.main()
--- a/configurationengine/source/scripts/tests/unittest_update.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/scripts/tests/unittest_update.py	Tue Aug 10 14:29:28 2010 +0300
@@ -23,7 +23,7 @@
 import os
 import subprocess
 import shutil
-import __init__
+
 from testautomation.base_testcase import BaseTestCase
 from testautomation import unzip_file
 from scripttest_common import get_cmd
@@ -49,7 +49,7 @@
     def test_get_help(self):
         cmd = '%s -h' % get_cmd('update')
         out = self.run_command(cmd)
-        lines = out.split('\r\n')
+        lines = out.split(os.linesep)
         self.assertTrue('Options:' in lines)
         self.assertTrue('  Update options:' in lines)
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/tests/unittest_validate.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,187 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+"""
+Test the configuration
+"""
+import string
+import unittest
+import os
+
+from scripttest_common import get_cmd
+from testautomation.base_testcase import BaseTestCase
+
+ROOT_PATH    = os.path.dirname(os.path.abspath(__file__))
+TEMP_DIR     = os.path.join(ROOT_PATH, 'temp/validate')
+TESTDATA_DIR = os.path.join(ROOT_PATH, 'testdata/validate')
+TEST_TEMPLATE = os.path.join(TESTDATA_DIR, 'template.txt')
+
+class TestValidate(BaseTestCase):
+    
+    def test_get_help(self):
+        cmd = '%s -h' % get_cmd('validate')
+        out = self.run_command(cmd)
+        lines = out.split(os.linesep)
+        self.assertTrue('Options:' in lines)
+        self.assertTrue('  Validate options:' in lines)
+    
+    def _run_test_validate(self, args, report_file, template=None, report_type=None, assert_file=True):
+        REPORT_FILE = os.path.join(TEMP_DIR, report_file)
+        self.remove_if_exists(REPORT_FILE)
+        
+        cmd = '%(cmd)s %(args)s --report "%(report)s"' \
+            % {'cmd'        : get_cmd('validate'),
+               'args'       : args,
+               'report'     : REPORT_FILE}
+        if template:
+            cmd = cmd + ' --template "%s"' % template
+        if report_type:
+            cmd = cmd + ' --report-type %s' % report_type
+        out = self.run_command(cmd)
+        
+        EXPECTED_FILE = os.path.join(TESTDATA_DIR, 'expected', report_file)
+        if assert_file:
+            self.assert_file_contents_equal(EXPECTED_FILE, REPORT_FILE)
+        return out
+
+    def test_validate_templates(self):
+        PROJECT = os.path.join(TESTDATA_DIR, 'project')
+        CONFIG = 'errors_root.confml'
+        self._run_test_validate(
+            args        = '-p "%s" -c %s' % (PROJECT, CONFIG),
+            report_type = 'xml',
+            report_file = 'report.xml')
+    
+    def test_validate_invalid_configuration(self):
+        PROJECT = os.path.join(TESTDATA_DIR, 'project')
+        CONFIG = 'errors_root.confml'
+        self._run_test_validate(
+            args        = '-p "%s" -c %s' % (PROJECT, CONFIG),
+            report_file = 'invalid_config_report.txt',
+            template = TEST_TEMPLATE)
+    
+    def test_validate_valid_configuration(self):
+        PROJECT = os.path.join(TESTDATA_DIR, 'project')
+        CONFIG = 'no_errors_root.confml'
+        self._run_test_validate(
+            args        = '-p "%s" -c %s' % (PROJECT, CONFIG),
+            report_file = 'valid_config_report.txt',
+            template = TEST_TEMPLATE)
+    
+    def test_validate_invalid_file(self):
+        orig_workdir = os.getcwd()
+        os.chdir(ROOT_PATH)
+        try:
+            FILE = 'testdata/validate/project/assets/invalid/confml/invalid_type.confml'
+            self._run_test_validate(
+                args        = '--confml-file %s' % FILE,
+                report_file = 'invalid_file_report.txt',
+                template = TEST_TEMPLATE)
+        finally:
+            os.chdir(orig_workdir)
+    
+    def test_dump_schema_files(self):
+        OUTPUT_DIR = os.path.join(TEMP_DIR, 'schema_file_dump')
+        self.remove_if_exists(OUTPUT_DIR)
+        
+        cmd = '%(cmd)s --dump-schema-files "%(output)s"' \
+            % {'cmd'    : get_cmd('validate'),
+               'output' : OUTPUT_DIR}
+        self.run_command(cmd)
+        
+        def check(path):
+            path = os.path.normpath(os.path.join(OUTPUT_DIR, path))
+            self.assert_exists_and_contains_something(path)
+        check('confml/confml.xsd')
+        check('confml/confml2.xsd')
+        check('implml/implml.xsd')
+    
+    def _run_filtering_test(self, args, report_file):
+        PROJECT = os.path.join(TESTDATA_DIR, 'project')
+        CONFIG = 'errors_root.confml'
+        return self._run_test_validate(
+            args        = '-p "%s" -c %s %s' % (PROJECT, CONFIG, args),
+            report_file = report_file,
+            template = TEST_TEMPLATE)
+    
+    def test_validate_only_confml(self):
+        out = self._run_filtering_test(
+            args        = '--include-filter *.confml',
+            report_file = 'report_only_confml.txt')
+        self.assertTrue('Performing XML schema validation on ConfML files...' in out)
+        self.assertTrue('Validating ConfML model...' in out)
+        self.assertFalse('Performing XML schema validation on ImplML files...' in out)
+        self.assertFalse('Validating implementations...' in out)
+    
+    def test_validate_multiple_confml(self):
+        out = self._run_test_validate(
+            args        = '--confml-file "%s" --confml-file "%s"' % (os.path.join(TESTDATA_DIR, 'project/assets/invalid/confml/broken.confml'),
+                                                                 os.path.join(TESTDATA_DIR, 'project/assets/invalid/confml/invalid_element.confml')),
+            report_type = 'xml',
+            report_file = 'report.xml',
+            assert_file = False)
+        out = "".join(out)
+        self.assertTrue(string.find(out,"broken.confml")!=-1)
+        self.assertTrue(string.find(out,"invalid_element.confml")!=-1)
+    
+    def test_validate_only_implml(self):
+        out = self._run_filtering_test(
+            args        = '--include-filter *.implml',
+            report_file = 'report_only_implml.txt')
+        self.assertFalse('Performing XML schema validation on ConfML files...' in out)
+        self.assertFalse('Validating ConfML model...' in out)
+        self.assertTrue('Performing XML schema validation on ImplML files...' in out)
+        self.assertTrue('Validating implementations...' in out)
+    
+    def test_validate_multiple_implml(self):
+        out = self._run_test_validate(
+            args        = '--implml-file "%s" --implml-file "%s"' % (os.path.join(TESTDATA_DIR, 'project/assets/invalid/implml/broken.implml'),
+                                                                 os.path.join(TESTDATA_DIR, 'project/assets/invalid/implml/invalid_attribute.implml')),
+            report_type = 'xml',
+            report_file = 'report.xml',
+            assert_file = False)
+        out = "".join(out)
+        self.assertTrue(string.find(out,"broken.implml")!=-1)
+        self.assertTrue(string.find(out,"invalid_attribute.implml")!=-1)
+    
+    def test_validate_only_model(self):
+        out = self._run_filtering_test(
+            args        = '--include-filter model',
+            report_file = 'report_only_model.txt')
+        self.assertFalse('Performing XML schema validation on ConfML files...' in out)
+        self.assertTrue('Validating ConfML model...' in out)
+        self.assertFalse('Performing XML schema validation on ImplML files...' in out)
+        self.assertTrue('Validating implementations...' in out)
+    
+    def test_validate_only_schema(self):
+        out = self._run_filtering_test(
+            args        = '--include-filter schema',
+            report_file = 'report_only_schema.txt')
+        self.assertTrue('Performing XML schema validation on ConfML files...' in out)
+        self.assertFalse('Validating ConfML model...' in out)
+        self.assertTrue('Performing XML schema validation on ImplML files...' in out)
+        self.assertFalse('Parsing implementations...' in out)
+        self.assertFalse('Validating implementations...' in out)
+    
+    def test_validate_multiple_filters(self):
+        self._run_filtering_test(
+            args        = '--include-filter schema --include-filter model.confml '
+                          '--exclude-filter schema.confml '
+                          '--exclude-filter model.confml.missing_feature_for_data',
+            report_file = 'report_multiple_filters.txt')
+    
+if __name__ == '__main__':
+    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/validation_report_template.html	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,30 @@
+{% extends "cone_base.html" %}
+{% block title %}Validation report{% endblock %}
+{% block content %}
+    <h1>Validation problems:</h1><br>
+
+    <table class="report" id="report_data">
+    <tr>
+        <th class="featureName">File</th>
+		<th class="featureName">Line</th>
+        <th class="featureName">Type</th>
+        <th class="featureName">Severity</th>
+		<th class="featureName">Message</th>
+    </tr>
+    {% for problem in problems %}
+    <tr>
+        <td><a href="./{{ problem.file }}">{{ problem.file }}</td>
+        <td>{{ problem.line }}</td>
+        <td>{{ problem.type }}</td>
+        <td>{{ problem.severity }}</td>
+        <td>{{ problem.msg }}</td>
+    </tr>
+    {% endfor %}
+    
+    </table>
+<script language="javascript" type="text/javascript">
+//<![CDATA[
+    setFilterGrid("report_data");
+//]]>
+</script>
+{% endblock %}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/scripts/validation_report_template.xml	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<diamonds-build>
+	<quality aspect="SW Configurability">
+		<summary message="Total Problems" value="{{ problems | length }}"/>
+		<summary message="Total Errors" value="{{ problems | filter_by_severity('error') | length }}"/>
+		<summary message="Total Warnings" value="{{ problems | filter_by_severity('warning') | length  }}"/>
+    {% for problem in problems %}
+		<message severity="{{ problem.severity }}" type="{{ problem.type }}" message="{{ problem.msg | escape}}" />
+    {% endfor %}
+	</quality> 
+</diamonds-build>
\ No newline at end of file
--- a/configurationengine/source/setup.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/setup.py	Tue Aug 10 14:29:28 2010 +0300
@@ -23,7 +23,7 @@
 setup(
     name = "cone",
     version = __version__,
-    packages = find_packages(exclude=["*.tests", "*.tests.*", "tests.*", "tests"]),
+    packages = find_packages(exclude=["*.tests", "*.tests.*", "tests.*", "tests", "scripts"]),
     package_data = {'cone.validation': ['confml_xsd/*.xsd', 'implml_xsd/*.xsd']},
     install_requires = ['Jinja2>=2.1.1', 'simplejson>=2.0.9', 'lxml>=2.2.2'], #FIX THIS: not to try load cone from web
 
--- a/configurationengine/source/testautomation/testautomation/base_testcase.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/testautomation/testautomation/base_testcase.py	Tue Aug 10 14:29:28 2010 +0300
@@ -38,7 +38,10 @@
         Assert that a given file or directory has been modified since the last
         call to set_modification_reference_time() with the same path.
         """
-        self._assert_modification(path, assert_not_modified=False)
+        # This fails on linux for some reason, probably because the modification
+        # timestamps are not accurate enough
+        if sys.platform == "win32":
+            self._assert_modification(path, assert_not_modified=False)
     
     def assert_not_modified(self, path):
         """
@@ -157,12 +160,14 @@
                 os.path.join(dir1, d), os.path.join(dir2, d),
                 ignore, custom_comparison_functions, cr)
     
-    def assert_file_contents_equal(self, file1, file2, ignore_patterns=[]):
+    def assert_file_contents_equal(self, file1, file2, ignore_patterns=[], ignore_endline_style=False):
         """
         Assert the the given two files exist and their contents are equal.
         @param ignore_patterns: List of regular expressions for portions of the
             file content to ignore in the comparison. The ignored parts are
             deleted from the files before actual comparison.
+        @param ignore_endline_style: If True, the endline style (CRLF or LF) is
+            ignored during the comparison.
         """
         self.assertTrue(os.path.exists(file1), "File '%s' does not exist!" % file1)
         self.assertTrue(os.path.exists(file2), "File '%s' does not exist!" % file2)
@@ -177,17 +182,28 @@
         data1 = remove_ignored(data1, ignore_patterns)
         data2 = remove_ignored(data2, ignore_patterns)
         
+        if ignore_endline_style:
+            data1 = data1.replace('\r\n', '\n')
+            data2 = data2.replace('\r\n', '\n')
+        
+        import difflib
+        difseq = difflib.ndiff(data1, data2)
+        # take only the first ten rows of the difference
+        difference = ''.join(list(difseq)[:10])
         if data1 != data2:
             if len(ignore_patterns) > 0:
+                self.write_data_to_file(file1 + '.diff', ''.join(difseq))
                 self.write_data_to_file(file1 + '.comparetemp', data1)
                 self.write_data_to_file(file2 + '.comparetemp', data2)
-                self.fail("Data of the files '%s' and '%s' are not equal\nSee *.comparetemp files for the actual data that was compared." % (file1, file2))
+                self.fail("Data of the files '%s' and '%s' are not equal\nSee *.comparetemp files for the actual data that was compared.\nDifference %s" % (file1, file2, difference))
             else:
-                self.fail("Data of the files '%s' and '%s' are not equal" % (file1, file2))
+                self.fail("Data of the files '%s' and '%s' are not equal\nDifference %s" % (file1, file2, difference))
     
-    def assert_file_content_equals(self, filepath, expected_data):
+    def assert_file_content_equals(self, filepath, expected_data, ignore_endline_style=False):
         """
         Assert that the content of the given file is equals to the given expected data.
+        @param ignore_endline_style: If True, the endline style (CRLF or LF) is
+            ignored during the comparison.
         """
         self.assertTrue(os.path.exists(filepath), "'%s' does not exist!" % filepath)
         self.assertTrue(os.path.isfile(filepath), "'%s' is not a file!" % filepath)
@@ -196,18 +212,25 @@
         try:        filedata = f.read()
         finally:    f.close()
         
+        if ignore_endline_style:
+            filedata = filedata.replace('\r\n', '\n')
+            expected_data = expected_data.replace('\r\n', '\n')
+        
         if filedata != expected_data:
             msg = ("The content of the file '%s' is not what was expected!\n" % filepath) +\
                   ("Expected: %r\nActual: %r" % (expected_data, filedata))
             self.fail(msg)
     
-    def assert_file_contains(self, filepath, data, encoding=None):
+    def assert_file_contains(self, filepath, data, encoding=None, regexes=[]):
         """
         Assert that the given file contains the given text somewhere in its contents.
         @param filepath: Path to the file to check.
         @param data: The data the file is expected to contain.
         @param encoding: Encoding used to decode the contents of the file.
             If None, noe decoding is done.
+        @param regexes: A list of regular expressions that are used to search for
+            a match in the file data. If any of them doesn't find a match,
+            the assertion fails.
         """
         self.assertTrue(os.path.exists(filepath), "'%s' does not exist!" % filepath)
         self.assertTrue(os.path.isfile(filepath), "'%s' is not a file!" % filepath)
@@ -225,6 +248,10 @@
         for entry in data:
             if not filedata.find(entry) != -1:
                 self.fail("The file '%s' does not contain the data '%s'" % (filepath, entry))
+        
+        for regex in regexes:
+            if re.search(regex, filedata, re.MULTILINE) is None:
+                self.fail("The regex %r does not match anything in file '%s'" % (regex, filepath))
 
     def assert_file_does_not_contain(self, filepath, data, encoding=None):
         """
@@ -297,6 +324,55 @@
                             "Output: \n%s" % (command, expected_return_code, p.returncode, out))
         return out
     
+    def assert_problem_lists_equal(self, actual, expected, outdir):
+        """
+        Assert that two lists of api.Problem objects are equal.
+        @param actual: The list of actual problems.
+        @param expected: The list of expected problems.
+        @param outdir: The directory where output is written if the assertion
+            fails.
+        """
+        act = sorted([repr(p) for p in actual])
+        exp = sorted([repr(p) for p in expected])
+        if act != exp:
+            if not os.path.exists(outdir):
+                os.makedirs(outdir)
+            self.write_data_to_file(os.path.join(outdir, 'actual.txt'), os.linesep.join(act))
+            self.write_data_to_file(os.path.join(outdir, 'expected.txt'), os.linesep.join(exp))
+            self.fail("Problem lists not equal, see the files in '%s'" % outdir)
+    
+    def assert_problem_list_equals_expected(self, actual, expected_file, outdir):
+        """
+        Assert that the given list of api.Problem objects is equal to the
+        list specified in the given file.
+        @param actual: The list of actual problems.
+        @param expected_file: Path to the file containing the list of
+            expected problems. The file should contain the repr() output
+            for an api.Problem object on each line.
+        @param outdir: The directory where output is written if the assertion
+            fails.
+        """
+        act = sorted([repr(p) for p in actual])
+        
+        if not os.path.isfile(expected_file):
+            raise RuntimeError("Expected problem file '%s' does not exist or is not a file!" % expected_file)
+        f = open(expected_file, 'r')
+        try:        exp = sorted([line.rstrip('\r\n') for line in f])
+        finally:    f.close()
+        
+        # Delete lines starting with #
+        for i in reversed(range(len(exp))):
+            if exp[i].startswith('#'):
+                del exp[i]
+        
+        if act != exp:
+            if not os.path.exists(outdir):
+                os.makedirs(outdir)
+            self.write_data_to_file(os.path.join(outdir, 'actual.txt'), os.linesep.join(act))
+            self.write_data_to_file(os.path.join(outdir, 'expected.txt'), os.linesep.join(exp))
+            self.fail("Problem list is not what was expected, see the files in '%s'" % outdir)
+    
+    
     # =====================================================
     # Private helper methods
     # =====================================================
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/testautomation/testautomation/build_egg_info.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,65 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+# Script for generating the egg-info directories for all needed plug-ins.
+#
+# This is needed, because running some of the tests from Eclipse or
+# command line requires the egg-info dirs to be present for the plug-ins
+# to be found.
+
+import sys, os, subprocess, shutil
+
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+DEBUG = False
+
+def generate_egg_info(path):
+    """Generate egg-info for the given plug-in path if possible and necessary."""
+    if not os.path.isdir(path) or "setup.py" not in os.listdir(path):
+        return
+    
+    # Check if egg-info has already been generated
+    for name in os.listdir(path):
+        egg_info_path = os.path.join(path, name)
+        if os.path.isdir(egg_info_path) and name.endswith('.egg-info'):
+            # xxx.egg-info is present in the directory, check if it is old
+            setup_py_path = os.path.join(path, 'setup.py')
+            if os.stat(setup_py_path).st_mtime < os.stat(egg_info_path).st_mtime:
+                if DEBUG: print "No need to generate egg-info for '%s'" % path
+                return
+            else:
+                if DEBUG: print "egg-info for '%s' is out of date, removing old and generating new" % path
+                shutil.rmtree(egg_info_path)
+    
+    # Run the egg-info generation command
+    orig_workdir = os.getcwd()
+    try:
+        if DEBUG: print "Generating egg-info for '%s'..." % path
+        os.chdir(path)
+        p = subprocess.Popen("python setup.py egg_info", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+        out, err = p.communicate()
+        if p.returncode != 0:
+            print >>sys.stderr, "Could not generate egg-info for '%s'!" % path
+            print >>sys.stderr, "Command stdout output:"
+            print >>sys.stderr, out
+            print >>sys.stderr, "Command stderr output:"
+            print >>sys.stderr, err
+        else:
+            if DEBUG:
+                print "Done"
+                print "Command output:"
+                print out
+    finally:
+        os.chdir(orig_workdir)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/testautomation/testautomation/plugin_utils.py	Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,225 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+import sys, os, unittest, re
+import build_egg_info
+
+# Path to the directory where this file is located
+ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
+
+
+
+def plugin_test_init(root_path, plugin_source_relative_path='../..'):
+    """
+    Initialize things so that plug-in unit tests can be run.
+    
+    @param root_path: Path of the __init__.py file calling this function. 
+    @param plugin_source_relative_path: Path to the plug-in's source root relative
+        to root_path. Usually this should be '../..', since this function is intended
+        to be called from a plug-in's tests/__init__.py file.
+    
+    """
+
+    # Generate egg-info for the plug-in.
+    # The egg-info needs to be up-to-date, or the plug-in framework will not be able
+    # to find the plug-in's ImplML reader classes
+    plugin_path = os.path.normpath(os.path.join(root_path, plugin_source_relative_path))
+    assert 'setup.py' in os.listdir(plugin_path), "Path '%s' does not contain 'setup.py" % plugin_path
+    build_egg_info.generate_egg_info(plugin_path)
+
+#def integration_test_init(root_path):
+#    """
+#    Initialize things so that integration tests can be run.
+#    
+#    This function is intended to be called from a sub-package's integration-test/__init__.py file.
+#    @param root_path: Path of the __init__.py file calling this function.
+#    """
+#    
+#    
+#    # Generate egg-info for the plug-ins.
+#    # The egg-info needs to be up-to-date, or the plug-in framework will not be able
+#    # to find the plug-in's ImplML reader classes
+#    for p in plugin_paths:
+#        assert 'setup.py' in os.listdir(p), "Path '%s' does not contain 'setup.py" % p
+#        build_egg_info.generate_egg_info(p)
+
+#def init_all():
+#    """
+#    Add all plug-ins to sys.path and PYTHONPATH so that running all
+#    plug-in unit tests and integration tests work.
+#    """
+#    # Find all plug-in source directories
+#    plugin_paths = []
+#    temp = find_all_plugin_sources(os.path.join(PLUGIN_SOURCE_ROOT))
+#    for package_name, sources in temp.iteritems():
+#        for path, modname in sources:
+#            plugin_paths.append(path)
+#    
+#    # Add paths so that the unit tests work
+#    # -------------------------------------
+#    extra_paths = [
+#        # For module 'cone' (may be needed in some tests for e.g. asserts)
+#        SOURCE_ROOT,
+#        
+#        # For module 'testautomation'
+#        os.path.join(SOURCE_ROOT, 'testautomation'),
+#    ] + plugin_paths
+#    for p in extra_paths:
+#        p = os.path.normpath(p)
+#        if p not in sys.path: sys.path.append(p)
+#    
+#    # Add things to PYTHONPATH so that running cone_tool.py works
+#    paths = []
+#    paths.append(SOURCE_ROOT) # For module 'cone'
+#    paths.extend(plugin_paths)
+#    os.environ['PYTHONPATH'] = os.environ.get('PYTHONPATH', '') + ';' + ';'.join(paths)
+#    
+#    # Generate egg-info for the plug-ins.
+#    # The egg-info needs to be up-to-date, or the plug-in framework will not be able
+#    # to find the plug-in's ImplML reader classes
+#    for p in plugin_paths:
+#        assert 'setup.py' in os.listdir(p), "Path '%s' does not contain 'setup.py" % p
+#        build_egg_info.generate_egg_info(p)
+
+
+def get_plugin_module_name(plugin_src_path):
+    """
+    Return the name of the plug-in's module under given plug-in source path.
+    
+    >>> get_tests_module('source/plugins/common/ConeContentPlugin')
+    'contentplugin'
+    >>> get_tests_module('foo')
+    None
+    """
+    if not os.path.isdir(plugin_src_path):
+        return None
+    
+    for name in os.listdir(plugin_src_path):
+        path = os.path.join(plugin_src_path, name)
+        if os.path.isdir(path) and '__init__.py' in os.listdir(path):
+            return name
+    return None
+
+def find_plugin_sources(subpackage_root_path):
+    """
+    Return ConE plug-in source directories from the given path.
+    
+    All sub-directories in subpackage_root_path of the form Cone*Plugin/ containing
+    a sub-directory that is a python module are returned.
+    
+    @param path: The directory from where to find the entries.
+    @return: A list of tuples, each containing (<source_dir>, <module_name>).
+    """
+    pattern = re.compile(r'^Cone.*Plugin$')
+    
+    # Collect a list of plug-in source paths and plug-in module names
+    result = []
+    for name in os.listdir(subpackage_root_path):
+        path = os.path.join(subpackage_root_path, name)
+        if pattern.match(name) is not None:
+            modname = get_plugin_module_name(path)
+            if modname is not None:
+                result.append((path, modname))
+    return result
+
+def find_all_plugin_sources(plugins_root_path):
+    """
+    Return all ConE plug-in source directories from the plugins/ root
+    directory.
+    @return: A dictionary containing the output of find_plugin_sources() by
+        plug-in sub-packages.
+    >>> find_all_plugin_sources('C:/work/cone-trunk/source/plugins')
+    {'common': [('C:/work/cone-trunk/source/plugins/common/ConeContentPlugin', 'contentplugin'),
+                ('C:/work/cone-trunk/source/plugins/common/ConeTemplatePlugin', 'templatemlplugin')],
+     'example': [('C:/work/cone-trunk/source/plugins/example/ConeExamplePlugin', 'examplemlplugin')]}
+    """
+    result = {}
+    for name in os.listdir(plugins_root_path):
+        path = os.path.join(plugins_root_path, name)
+        if os.path.isdir(path):
+            sources = find_plugin_sources(path)
+            if sources: result[name] = sources
+    return result
+
+def find_plugin_package_subpaths(plugin_source_root, subpath, package_name=None):
+    """
+    Return a list of plug-in package sub-paths based on the given plug-in package name.
+    
+    The returned list always contains the sub-path for common plug-ins, and
+    additionally for an extra plug-in package based on the given package name.
+    
+    This function can be used to find specifically named files or directories
+    under the plug-in paths. E.g. find all 'integration-test' directories:
+    
+    >>> find_plugin_package_subpaths('integration-test', 'symbian')
+    [('common',  'C:\\cone\\trunk\\sources\\plugins\\common\\integration-test'),
+     ('symbian', 'C:\\cone\\trunk\\sources\\plugins\\symbian\\integration-test')]
+    
+    @param package_name: Name of the extra plug-in package. Can be None, '',
+        'common' or an existing plug-in package.
+    @return: List of tuples (package_name, subpath).
+    
+    @raise ValueError: The given package_name was invalid.
+    """
+    result = []
+    
+    def add(package_name):
+        package_dir = os.path.join(plugin_source_root, package_name)
+        
+        if not os.path.exists(package_dir):
+            raise ValueError("Invalid plug-in package name: '%s'" % package_name)
+        
+        path = os.path.normpath(os.path.join(package_dir, subpath))
+        if os.path.exists(path):
+            result.append((package_name, path))
+    
+    add('common')
+    if package_name not in (None, '', 'common'):
+        add(package_name)
+    
+    return result
+    
+
+def find_plugin_sources_by_package(plugin_source_root, package_name=None):
+    """
+    Return a list of plug-in source paths based on the given plug-in package name.
+    
+    The returned list always contains sources of common plug-ins, and
+    additionally extra plug-in sources based on the given package name.
+    
+    @param package_name: Name of the extra plug-in package. Can be None, '',
+        'common' or an existing plug-in package.
+    @raise ValueError: The given package_name was invalid.
+    """
+    result = []
+    
+    # Find all plug-in sources
+    sources = find_all_plugin_sources(plugin_source_root)
+    
+    # Always return common plug-ins
+    if 'common' in sources:
+        for path, modname in sources['common']:
+            result.append(path)
+    
+    # Return extra plug-ins if necessary
+    if package_name not in (None, '', 'common'):
+        if package_name not in sources:
+            raise ValueError("Invalid plug-in package name: '%s'" % package_name)
+        else:
+            for path, modname in sources[package_name]:
+                result.append(path)
+    
+    return result
--- a/configurationengine/source/testautomation/testautomation/setup.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/testautomation/testautomation/setup.py	Tue Aug 10 14:29:28 2010 +0300
@@ -35,7 +35,7 @@
     author = "Teemu Rytkonen",
     author_email = "teemu.rytkonen@nokia.com",
     description = "Configuration Engine test module",
-    license = "Symbian Foundation License v1.0",
+    license = "Eclipse Public License v1.0",
     keywords = "cone test",
     url = "http://developer.symbian.org/wiki/index.php/Software_Configuration_Middleware",
 
--- a/configurationengine/source/testautomation/testautomation/tests/__init__.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/testautomation/testautomation/tests/__init__.py	Tue Aug 10 14:29:28 2010 +0300
@@ -14,27 +14,3 @@
 # Description: 
 #
 
-import unittest, os, sys
-
-ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
-sys.path.append(os.path.join(ROOT_PATH,'../..'))
-
-# Find all unittest_*.py files in this folder
-import re
-__all__ = filter(lambda name: re.match(r'^unittest_.*\.py$', name) != None, os.listdir(ROOT_PATH))
-# Strip .py endings
-__all__ = map(lambda name: name[:-3], __all__)
-
-def collect_suite():  
-    suite = unittest.TestSuite()
-    for test_module in __all__:
-        # Load the test module dynamically and add it to the test suite
-        module = __import__(test_module)
-        suite.addTests(unittest.TestLoader().loadTestsFromModule(module))
-    return suite      
-
-def runtests():
-    unittest.TextTestRunner(verbosity=2).run(collect_suite())
-
-if __name__ == '__main__':
-    runtests()
--- a/configurationengine/source/testautomation/testautomation/tests/runtests.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/testautomation/testautomation/tests/runtests.py	Tue Aug 10 14:29:28 2010 +0300
@@ -14,5 +14,6 @@
 # Description:
 #
 
-import __init__
-__init__.runtests()
\ No newline at end of file
+if __name__ == '__main__':
+    import nose
+    nose.core.run(argv=['collector','--include=unittest', '--verbosity=3'])
--- a/configurationengine/source/testautomation/testautomation/utils.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/source/testautomation/testautomation/utils.py	Tue Aug 10 14:29:28 2010 +0300
@@ -13,6 +13,8 @@
 #
 # Description:
 #
+import os
+import shutil
 
 def hex_to_bindata(hexdata):
     hexdata = hexdata.replace(' ', '').replace('\r', '').replace('\n', '').replace('\t', '')
@@ -27,4 +29,18 @@
         start = i * 2
         end   = start + 2 
         temp.append(chr(int(hexdata[start:end], 16)))
-    return ''.join(temp)
\ No newline at end of file
+    return ''.join(temp)
+
+def remove_if_exists(path_or_paths):
+    """Remove files or directories if they exist.
+    @param path_or_paths: The path to remove. Can also be a list of paths."""
+    if isinstance(path_or_paths, list):
+        paths = path_or_paths
+    else:
+        paths = [path_or_paths]
+    
+    for path in paths:
+        if os.path.isdir(path):
+            shutil.rmtree(path)
+        elif os.path.isfile(path):
+            os.remove(path)
\ No newline at end of file
--- a/configurationengine/update_svn_revision.py	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/update_svn_revision.py	Tue Aug 10 14:29:28 2010 +0300
@@ -1,3 +1,4 @@
+#
 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
 # All rights reserved.
 # This component and the accompanying materials are made available
@@ -11,6 +12,7 @@
 # Contributors:
 #
 # Description: 
+#
 
 import sys, re
 
--- a/configurationengine/windows.properties	Fri Mar 12 08:30:17 2010 +0200
+++ b/configurationengine/windows.properties	Tue Aug 10 14:29:28 2010 +0300
@@ -1,1 +1,4 @@
-os.windows.pythonlocationbase = E:/
\ No newline at end of file
+os.windows.name = Windows 2003, Windows XP, Windows vista
+os.windows.pythonlocationbase = E:/
+os.windows.cmdname = cmd
+os.windows.cmdswitch = /c