← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 9439: Changed from using database identifiers to UIDs in indicator expressions, validation rules and da...

 

Merge authors:
  Lars Helge Øverland (larshelge)
------------------------------------------------------------
revno: 9439 [merge]
committer: Lars Helge Øverland <larshelge@xxxxxxxxx>
branch nick: dhis2
timestamp: Sat 2013-01-05 16:23:46 +0100
message:
  Changed from using database identifiers to UIDs in indicator expressions, validation rules and data entry forms
added:
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/startup/ExpressionUpgrader.java
renamed:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/datamart/CrossTabDataValue.java => dhis-2/dhis-services/dhis-service-datamart-default/src/main/java/org/hisp/dhis/datamart/CrossTabDataValue.java
modified:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/chart/Chart.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/constant/ConstantService.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementCategoryService.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementOperand.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementService.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementStore.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataentryform/DataEntryFormService.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/expression/Expression.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/expression/ExpressionService.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/interpretation/Interpretation.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/mapping/Map.java
  dhis-2/dhis-api/src/test/java/org/hisp/dhis/dataelement/OperandTest.java
  dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/dataintegrity/DefaultDataIntegrityService.java
  dhis-2/dhis-services/dhis-service-aggregationengine-default/src/main/java/org/hisp/dhis/aggregation/impl/indicator/IndicatorAggregation.java
  dhis-2/dhis-services/dhis-service-aggregationengine-default/src/test/java/org/hisp/dhis/aggregation/AggregationServiceTest.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/constant/DefaultConstantService.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataelement/DefaultDataElementCategoryService.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataelement/DefaultDataElementService.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataelement/hibernate/HibernateDataElementStore.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataentryform/DefaultDataEntryFormService.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/datavalue/hibernate/HibernateDataValueStore.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/expression/DefaultExpressionService.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/validation/DefaultValidationRuleService.java
  dhis-2/dhis-services/dhis-service-core/src/main/resources/META-INF/dhis/beans.xml
  dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/dataentryform/DataEntryFormServiceTest.java
  dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/expression/ExpressionServiceTest.java
  dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/validation/ValidationRuleServiceTest.java
  dhis-2/dhis-services/dhis-service-datamart-default/src/main/java/org/hisp/dhis/datamart/DataMartManager.java
  dhis-2/dhis-services/dhis-service-datamart-default/src/main/java/org/hisp/dhis/datamart/JdbcDataMartManager.java
  dhis-2/dhis-services/dhis-service-datamart-default/src/main/java/org/hisp/dhis/datamart/dataelement/DataElementDataMart.java
  dhis-2/dhis-services/dhis-service-datamart-default/src/main/java/org/hisp/dhis/datamart/dataelement/DefaultDataElementDataMart.java
  dhis-2/dhis-services/dhis-service-datamart-default/src/main/java/org/hisp/dhis/datamart/engine/DefaultDataMartEngine.java
  dhis-2/dhis-services/dhis-service-datamart-default/src/main/java/org/hisp/dhis/datamart/indicator/DefaultIndicatorDataMart.java
  dhis-2/dhis-services/dhis-service-datamart-default/src/test/java/org/hisp/dhis/datamart/DataMartServiceOrgUnitTest.java
  dhis-2/dhis-services/dhis-service-datamart-default/src/test/java/org/hisp/dhis/datamart/DataMartServiceTest.java
  dhis-2/dhis-services/dhis-service-datamart-default/src/test/java/org/hisp/dhis/datamart/crosstab/CrossTabStoreTest.java
  dhis-2/dhis-services/dhis-service-importexport/src/main/java/org/hisp/dhis/importexport/DefaultImportService.java
  dhis-2/dhis-services/dhis-service-importexport/src/main/java/org/hisp/dhis/importexport/analysis/IndicatorFormulaIdentifier.java
  dhis-2/dhis-services/dhis-service-importexport/src/main/java/org/hisp/dhis/importexport/dxf/converter/DXFConverter.java
  dhis-2/dhis-services/dhis-service-importexport/src/main/java/org/hisp/dhis/importexport/dxf/converter/IndicatorConverter.java
  dhis-2/dhis-services/dhis-service-importexport/src/main/java/org/hisp/dhis/importexport/dxf/converter/ValidationRuleConverter.java
  dhis-2/dhis-services/dhis-service-importexport/src/main/java/org/hisp/dhis/importexport/service/DefaultImportObjectManager.java
  dhis-2/dhis-services/dhis-service-importexport/src/test/java/org/hisp/dhis/importexport/analysis/ImportAnalyserTest.java
  dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/datasetreport/impl/DefaultDataSetReportService.java
  dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/datasetreport/jdbc/JdbcDataSetReportStore.java
  dhis-2/dhis-support/dhis-support-hibernate/src/main/java/org/hisp/dhis/cache/DefaultHibernateCacheManager.java
  dhis-2/dhis-support/dhis-support-hibernate/src/main/java/org/hisp/dhis/cache/HibernateCacheManager.java
  dhis-2/dhis-support/dhis-support-test/src/main/java/org/hisp/dhis/DhisConvenienceTest.java
  dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/ajax/jsonCategoryOptionCombos.vm
  dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/ajax/jsonDataElementOperands.vm
  dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/ajax/jsonDataElements.vm
  dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/ajax/jsonIndicators.vm
  dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/commons.ajax.js
  dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/commons/action/GetCategoryOptionCombosAction.java
  dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/commons/action/GetOrganisationUnitTreeAction.java
  dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/security/AbstractAutomaticAccessProvider.java
  dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/security/filter/BasicAuthenticationRequiredFilter.java
  dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/LoadFormAction.java
  dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/SaveValueAction.java
  dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/customForm.vm
  dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/defaultForm.vm
  dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/javascript/entry.js
  dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/javascript/form.js
  dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/multiOrgSectionForm.vm
  dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/responseDataValues.vm
  dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/responseMetaData.vm
  dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/sectionForm.vm
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/java/org/hisp/dhis/dd/action/dataelement/GetDataElementGroupMembersAction.java
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataset/src/main/webapp/dhis-web-maintenance-dataset/javascript/viewDataEntryForm.js
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataset/src/main/webapp/dhis-web-maintenance-dataset/viewDataEntryForm.vm
  resources/sql/copydata.sql


--
lp:dhis2
https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk

Your team DHIS 2 developers is subscribed to branch lp:dhis2.
To unsubscribe from this branch go to https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk/+edit-subscription
=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/chart/Chart.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/chart/Chart.java	2012-12-27 14:07:54 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/chart/Chart.java	2013-01-04 18:10:25 +0000
@@ -27,14 +27,11 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.annotation.JsonView;
-import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
-import com.fasterxml.jackson.databind.annotation.JsonSerialize;
-import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
-import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
-import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
 import org.hisp.dhis.common.BaseIdentifiableObject;
 import org.hisp.dhis.common.BaseNameableObject;
 import org.hisp.dhis.common.Dxf2Namespace;
@@ -54,12 +51,15 @@
 import org.hisp.dhis.period.Period;
 import org.hisp.dhis.period.RelativePeriods;
 import org.hisp.dhis.period.comparator.AscendingPeriodEndDateComparator;
-import org.hisp.dhis.user.User;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonView;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
 
 /**
  * @author Lars Helge Overland

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/constant/ConstantService.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/constant/ConstantService.java	2011-12-11 00:00:06 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/constant/ConstantService.java	2013-01-04 18:10:25 +0000
@@ -56,7 +56,7 @@
 
     Collection<Constant> getAllConstants();
 
-    Map<Integer, Double> getConstantMap();
+    Map<String, Double> getConstantMap();
 
     Map<String, Double> getConstantParameterMap();
 

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementCategoryService.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementCategoryService.java	2012-07-25 13:18:48 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementCategoryService.java	2013-01-05 15:22:55 +0000
@@ -28,6 +28,7 @@
  */
 
 import java.util.Collection;
+import java.util.Map;
 
 import org.hisp.dhis.concept.Concept;
 import org.hisp.dhis.hierarchy.HierarchyViolationException;
@@ -184,7 +185,6 @@
      */
     Collection<DataElementCategoryOption> getDataElementCategorOptionsByConcept( Concept concept );
 
-
     // -------------------------------------------------------------------------
     // CategoryCombo
     // -------------------------------------------------------------------------
@@ -420,6 +420,8 @@
      */
     Collection<DataElementCategory> getDataElementCategorysByConcept( Concept concept );
     
+    Map<String, Integer> getDataElementCategoryOptionComboUidIdMap();
+    
     int getDataElementCategoryCount();
 
     int getDataElementCategoryCountByName( String name );

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementOperand.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementOperand.java	2012-08-29 14:39:44 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementOperand.java	2013-01-05 15:22:55 +0000
@@ -31,15 +31,19 @@
 import com.fasterxml.jackson.annotation.JsonView;
 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+
+import org.apache.commons.lang.StringUtils;
 import org.hisp.dhis.common.BaseIdentifiableObject;
 import org.hisp.dhis.common.Dxf2Namespace;
 import org.hisp.dhis.common.view.DetailedView;
 import org.hisp.dhis.common.view.ExportView;
+import org.hisp.dhis.expression.ExpressionService;
 
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.regex.Matcher;
 
 /**
  * This object can act both as a hydrated persisted object and as a wrapper
@@ -80,9 +84,9 @@
     // Transient properties
     // -------------------------------------------------------------------------
 
-    private int dataElementId;
+    private String dataElementId;
 
-    private int optionComboId;
+    private String optionComboId;
 
     private String operandId;
 
@@ -114,14 +118,14 @@
         this.categoryOptionCombo = categoryOptionCombo;
     }
 
-    public DataElementOperand( int dataElementId, int optionComboId )
+    public DataElementOperand( String dataElementId, String optionComboId )
     {
         this.dataElementId = dataElementId;
         this.optionComboId = optionComboId;
         this.operandId = dataElementId + SEPARATOR + optionComboId;
     }
 
-    public DataElementOperand( int dataElementId, int optionComboId, String operandName )
+    public DataElementOperand( String dataElementId, String optionComboId, String operandName )
     {
         this.dataElementId = dataElementId;
         this.optionComboId = optionComboId;
@@ -129,7 +133,7 @@
         this.operandName = operandName;
     }
 
-    public DataElementOperand( int dataElementId, int optionComboId, String operandName, String valueType,
+    public DataElementOperand( String dataElementId, String optionComboId, String operandName, String valueType,
         String aggregationOperator, List<Integer> aggregationLevels, int frequencyOrder )
     {
         this.dataElementId = dataElementId;
@@ -272,9 +276,9 @@
      */
     public void updateProperties( DataElement dataElement, DataElementCategoryOptionCombo categoryOptionCombo )
     {
-        this.dataElementId = dataElement.getId();
-        this.optionComboId = categoryOptionCombo.getId();
-        this.operandId = dataElement.getId() + SEPARATOR + categoryOptionCombo.getId();
+        this.dataElementId = dataElement.getUid();
+        this.optionComboId = categoryOptionCombo.getUid();
+        this.operandId = dataElementId + SEPARATOR + optionComboId;
         this.operandName = getPrettyName( dataElement, categoryOptionCombo );
         this.aggregationOperator = dataElement.getAggregationOperator();
         this.frequencyOrder = dataElement.getFrequencyOrder();
@@ -289,8 +293,8 @@
      */
     public void updateProperties( DataElement dataElement )
     {
-        this.dataElementId = dataElement.getId();
-        this.operandId = String.valueOf( dataElement.getId() );
+        this.dataElementId = dataElement.getUid();
+        this.operandId = String.valueOf( dataElementId );
         this.operandName = dataElement.getDisplayName() + SPACE + NAME_TOTAL;
         this.aggregationOperator = dataElement.getAggregationOperator();
         this.frequencyOrder = dataElement.getFrequencyOrder();
@@ -302,37 +306,20 @@
      * Generates a DataElementOperand based on the given formula. The formula
      * needs to be on the form "[<dataelementid>.<categoryoptioncomboid>]".
      *
-     * @param formula the formula.
+     * @param expression the formula.
      * @return a DataElementOperand.
      */
-    public static DataElementOperand getOperand( String formula )
+    public static DataElementOperand getOperand( String expression )
         throws NumberFormatException
     {
-        formula = formula.replaceAll( "[\\[\\]]", "" );
-
-        int dataElementId = 0;
-        int categoryOptionComboId = 0;
-        String operandType = null;
-
-        if ( formula.contains( SEPARATOR ) ) // Value
-        {
-            dataElementId = Integer.parseInt( formula.substring( 0, formula.indexOf( SEPARATOR ) ) );
-            categoryOptionComboId = Integer.parseInt( formula.substring( formula.indexOf( SEPARATOR ) + 1, formula.length() ) );
-
-            operandType = TYPE_VALUE;
-        }
-        else // Total
-        {
-            dataElementId = Integer.parseInt( formula );
-
-            operandType = TYPE_TOTAL;
-        }
-
-        final DataElementOperand operand = new DataElementOperand();
-        operand.setDataElementId( dataElementId );
-        operand.setOptionComboId( categoryOptionComboId );
+        Matcher matcher = ExpressionService.OPERAND_PATTERN.matcher( expression );
+        matcher.find();
+        String dataElement = StringUtils.trimToNull( matcher.group( 1 ) );
+        String categoryOptionCombo = StringUtils.trimToNull( matcher.group( 2 ) );
+        String operandType = categoryOptionCombo != null ? TYPE_VALUE : TYPE_TOTAL;        
+        
+        final DataElementOperand operand = new DataElementOperand( dataElement, categoryOptionCombo );
         operand.setOperandType( operandType );
-
         return operand;
     }
 
@@ -376,22 +363,22 @@
         this.categoryOptionCombo = categoryOptionCombo;
     }
 
-    public int getDataElementId()
+    public String getDataElementId()
     {
         return dataElementId;
     }
 
-    public void setDataElementId( int dataElementId )
+    public void setDataElementId( String dataElementId )
     {
         this.dataElementId = dataElementId;
     }
 
-    public int getOptionComboId()
+    public String getOptionComboId()
     {
         return optionComboId;
     }
 
-    public void setOptionComboId( int optionComboId )
+    public void setOptionComboId( String optionComboId )
     {
         this.optionComboId = optionComboId;
     }
@@ -480,76 +467,6 @@
     // hashCode, equals, toString, compareTo
     // -------------------------------------------------------------------------
 
-    @Override
-    public int hashCode()
-    {
-        final int prime = 31;
-        int result = 1;
-
-        result = prime * result + ( ( categoryOptionCombo == null) ? 0 : categoryOptionCombo.hashCode() );
-        result = prime * result + ( ( dataElement == null) ? 0 : dataElement.hashCode() );
-        result = prime * result + dataElementId;
-        result = prime * result + optionComboId;
-
-        return result;
-    }
-
-    @Override
-    public boolean equals( Object object )
-    {
-        if ( this == object )
-        {
-            return true;
-        }
-
-        if ( object == null )
-        {
-            return false;
-        }
-
-        if ( getClass() != object.getClass() )
-        {
-            return false;
-        }
-
-        final DataElementOperand other = (DataElementOperand) object;
-
-        if ( dataElement == null )
-        {
-            if ( other.dataElement != null )
-            {
-                return false;
-            }
-        }
-        else if ( !dataElement.equals( other.dataElement ) )
-        {
-            return false;
-        }
-
-        if ( categoryOptionCombo == null )
-        {
-            if ( other.categoryOptionCombo != null )
-            {
-                return false;
-            }
-        }
-        else if ( !categoryOptionCombo.equals( other.categoryOptionCombo ) )
-        {
-            return false;
-        }
-
-        if ( dataElementId != other.dataElementId )
-        {
-            return false;
-        }
-
-        if ( optionComboId != other.optionComboId )
-        {
-            return false;
-        }
-
-        return true;
-    }
 
     @Override
     public String toString()
@@ -570,13 +487,98 @@
             '}';
     }
 
+    @Override
+    public int hashCode()
+    {
+        final int prime = 31;
+        int result = 1;
+        
+        result = prime * result + ( ( dataElement == null ) ? 0 : dataElement.hashCode() );
+        result = prime * result + ( ( categoryOptionCombo == null ) ? 0 : categoryOptionCombo.hashCode() );
+        result = prime * result + ( ( dataElementId == null ) ? 0 : dataElementId.hashCode() );
+        result = prime * result + ( ( optionComboId == null ) ? 0 : optionComboId.hashCode() );
+        
+        return result;
+    }
+
+    @Override
+    public boolean equals( Object object )
+    {
+        if ( this == object )
+        {
+            return true;
+        }
+        
+        if ( object == null )
+        {
+            return false;
+        }
+        
+        if ( getClass() != object.getClass() )
+        {
+            return false;
+        }
+        
+        DataElementOperand other = (DataElementOperand) object;
+        
+        if ( categoryOptionCombo == null )
+        {
+            if ( other.categoryOptionCombo != null )
+            {
+                return false;
+            }
+        }
+        else if ( !categoryOptionCombo.equals( other.categoryOptionCombo ) )
+        {
+            return false;
+        }
+        
+        if ( dataElement == null )
+        {
+            if ( other.dataElement != null )
+            {
+                return false;
+            }
+        }
+        else if ( !dataElement.equals( other.dataElement ) )
+        {
+            return false;
+        }
+        
+        if ( dataElementId == null )
+        {
+            if ( other.dataElementId != null )
+            {
+                return false;
+            }
+        }
+        else if ( !dataElementId.equals( other.dataElementId ) )
+        {
+            return false;
+        }
+        
+        if ( optionComboId == null )
+        {
+            if ( other.optionComboId != null )
+            {
+                return false;
+            }
+        }
+        else if ( !optionComboId.equals( other.optionComboId ) )
+        {
+            return false;
+        }
+        
+        return true;
+    }
+
     public int compareTo( DataElementOperand other )
     {
-        if ( this.getDataElementId() != other.getDataElementId() )
+        if ( this.dataElementId.compareTo( other.dataElementId ) != 0 )
         {
-            return this.getDataElementId() - other.getDataElementId();
+            return this.dataElementId.compareTo( other.dataElementId );
         }
-
-        return this.getOptionComboId() - other.getOptionComboId();
+        
+        return this.optionComboId.compareTo( other.optionComboId );
     }
 }

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementService.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementService.java	2012-12-22 12:26:34 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementService.java	2013-01-05 15:22:55 +0000
@@ -286,7 +286,9 @@
 
     int getDataElementCountByName( String name );
 
-    Map<Integer, Set<Integer>> getDataElementCategoryOptionCombos();
+    Map<String, Set<String>> getDataElementCategoryOptionCombos();
+    
+    Map<String, Integer> getDataElementUidIdMap();
 
     // -------------------------------------------------------------------------
     // DataElementGroup

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementStore.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementStore.java	2012-12-22 12:26:34 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElementStore.java	2013-01-04 18:10:25 +0000
@@ -168,7 +168,7 @@
      */
     Collection<DataElement> getDataElementsByAggregationLevel( int aggregationLevel );
 
-    Map<Integer, Set<Integer>> getDataElementCategoryOptionCombos();
+    Map<String, Set<String>> getDataElementCategoryOptionCombos();
     
     Collection<DataElement> get( DataSet dataSet, String key, Integer max );
 }

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataentryform/DataEntryFormService.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataentryform/DataEntryFormService.java	2013-01-02 20:50:36 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataentryform/DataEntryFormService.java	2013-01-04 18:10:25 +0000
@@ -45,11 +45,11 @@
     String ID = DataEntryFormService.class.getName();
 
     final Pattern INPUT_PATTERN = Pattern.compile( "(<input.*?/>)", Pattern.DOTALL );
-    final Pattern IDENTIFIER_PATTERN = Pattern.compile( "(\\d+)-(\\d+)-val" );
-    final Pattern DATAELEMENT_TOTAL_PATTERN = Pattern.compile( "dataelementid=\"(.*?)\"" );
-    final Pattern INDICATOR_PATTERN = Pattern.compile( "indicatorid=\"(.*?)\"" );
-    final Pattern DYNAMIC_INPUT_PATTERN = Pattern.compile( "(.*?)-(.*?)-dyninput" ); // Random code - category option combo id
-    final Pattern DYNAMIC_SELECT_PATTERN = Pattern.compile( "dynselect=\"(.*?)\"" ); // Category combo id
+    final Pattern IDENTIFIER_PATTERN = Pattern.compile( "id=\"(\\w+)-(\\w+)-val\"" );
+    final Pattern DATAELEMENT_TOTAL_PATTERN = Pattern.compile( "dataelementid=\"(\\w+?)\"" );
+    final Pattern INDICATOR_PATTERN = Pattern.compile( "indicatorid=\"(\\w+)\"" );
+    final Pattern DYNAMIC_INPUT_PATTERN = Pattern.compile( "(\\w+)-(\\w+)-dyninput" ); // Random code - category option combo id
+    final Pattern DYNAMIC_SELECT_PATTERN = Pattern.compile( "dynselect=\"(\\w+)\"" ); // Category combo id
     final Pattern VALUE_TAG_PATTERN = Pattern.compile( "value=\"(.*?)\"", Pattern.DOTALL );
     final Pattern TITLE_TAG_PATTERN = Pattern.compile( "title=\"(.*?)\"", Pattern.DOTALL );
     

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/expression/Expression.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/expression/Expression.java	2012-10-10 12:49:27 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/expression/Expression.java	2013-01-04 18:10:25 +0000
@@ -74,8 +74,8 @@
     private static final long serialVersionUID = -4868682510629094282L;
 
     public static final String SEPARATOR = ".";
-    public static final String EXP_OPEN = "[";
-    public static final String EXP_CLOSE = "]";
+    public static final String EXP_OPEN = "#{";
+    public static final String EXP_CLOSE = "}";
     public static final String PAR_OPEN = "(";
     public static final String PAR_CLOSE = ")";
 

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/expression/ExpressionService.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/expression/ExpressionService.java	2012-09-23 07:25:57 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/expression/ExpressionService.java	2013-01-04 18:10:25 +0000
@@ -30,6 +30,7 @@
 import java.util.Collection;
 import java.util.Map;
 import java.util.Set;
+import java.util.regex.Pattern;
 
 import org.hisp.dhis.dataelement.DataElement;
 import org.hisp.dhis.dataelement.DataElementCategoryOptionCombo;
@@ -37,10 +38,16 @@
 import org.hisp.dhis.indicator.Indicator;
 
 /**
- * Interface for ExpressionService. Defines service functionality for
- * Expressions.
+ * Expressions are mathematical formulas and can contain references to various
+ * elements.
+ * 
+ * - Data element operands on the form #{dataelementuid.categoryoptioncombouid}
+ * - Data element totals on the form #{dataelementuid}
+ * - Constants on the form C{constantuid}
+ * - Days in aggregation period as the symbol D{}
  *
  * @author Margrethe Store
+ * @author Lars Helge Overland
  * @version $Id: ExpressionService.java 6461 2008-11-24 11:32:37Z larshelg $
  */
 public interface ExpressionService
@@ -49,20 +56,24 @@
     
     final String VALID = "valid";
     final String EXPRESSION_IS_EMPTY = "expression_is_empty";
-    final String ID_NOT_NUMERIC = "id_not_numeric";
     final String DATAELEMENT_DOES_NOT_EXIST = "data_element_does_not_exist";
     final String CATEGORYOPTIONCOMBO_DOES_NOT_EXIST = "category_option_combo_does_not_exist";
+    final String CONSTANT_DOES_NOT_EXIST = "constant_does_not_exist";
     final String EXPRESSION_NOT_WELL_FORMED = "expression_not_well_formed";
-    final String CONSTANT_DOES_NOT_EXIST = "constant_does_not_exist";
 
     final String DAYS_DESCRIPTION = "[Number of days]";
     final String NULL_REPLACEMENT = "0";
     final String SPACE = " ";
 
-    final String FORMULA_EXPRESSION = "\\[.+?\\]";
-    final String OPERAND_EXPRESSION = "\\[\\d+?.*?\\]";
-    final String DAYS_EXPRESSION = "[days]";
-    final String CONSTANT_EXPRESSION = "\\[C(\\d+?)\\]";
+    final String OPERAND_EXPRESSION = "#\\{(\\w+)\\.?(\\w*)\\}";
+    final String CONSTANT_EXPRESSION = "C\\{(\\w+)\\}";
+    final String DAYS_EXPRESSION = "\\[days\\]";
+
+    final Pattern OPERAND_PATTERN = Pattern.compile( OPERAND_EXPRESSION );
+    final Pattern CONSTANT_PATTERN = Pattern.compile( CONSTANT_EXPRESSION );
+    final Pattern DAYS_PATTERN = Pattern.compile( DAYS_EXPRESSION );
+
+    final String DAYS_SYMBOL = "[days]";
     
     /**
      * Adds a new Expression to the database.
@@ -102,7 +113,7 @@
     Collection<Expression> getAllExpressions();
 
     Double getExpressionValue( Expression expression, Map<DataElementOperand, Double> valueMap, 
-        Map<Integer, Double> constantMap, Integer days );
+        Map<String, Double> constantMap, Integer days );
     
     /**
      * Returns all DataElements included in the given expression string.
@@ -124,20 +135,6 @@
     Set<DataElementOperand> getOperandsInExpression( String expression );
     
     /**
-     * Converts the given expression based on the maps of corresponding data element
-     * identifiers and category option combo identifiers.
-     * 
-     * @param expression the expression formula.
-     * @param dataElementMapping the data element mapping.
-     * @param categoryOptionComboMapping the category option combo mapping.
-     * 
-     * @return an expression which has converted its data element and category
-     *         option combo identifiers with the corresponding entries in the
-     *         mappings.
-     */
-    String convertExpression( String expression, Map<Object, Integer> dataElementMapping, Map<Object, Integer> categoryOptionComboMapping );
-    
-    /**
      * Filters indicators from the given collection where the numerator and /
      * or the denominator are invalid.
      *  
@@ -151,10 +148,11 @@
      * 
      * @param formula the expression formula.
      * @return VALID if the expression is valid.
-     * 	       DATAELEMENT_ID_NOT_NUMERIC if the data element is not a number.
-     * 	       CATEGORYOPTIONCOMBO_ID_NOT_NUMERIC if the category option combo id is not a number.
+     * 	       EXPRESSION_IS_EMPTY if the expression is empty.
      * 	       DATAELEMENT_DOES_NOT_EXIST if the data element does not exist.
      *         CATEGORYOPTIONCOMBO_DOES_NOT_EXIST if the category option combo does not exist.
+     *         CONSTANT_DOES_NOT_EXIST if the constant does not exist.
+     *         EXPRESSION_NOT_WELL_FORMED if the expression is not well-formed.
      */
     String expressionIsValid( String formula );
 
@@ -164,12 +162,13 @@
      * 
      * @param formula the expression formula.
      * @return VALID if the expression is valid.
-     *         DATAELEMENT_ID_NOT_NUMERIC if the data element is not a number.
-     *         CATEGORYOPTIONCOMBO_ID_NOT_NUMERIC if the category option combo id is not a number.
+     *         EXPRESSION_IS_EMPTY if the expression is empty.
      *         DATAELEMENT_DOES_NOT_EXIST if the data element does not exist.
      *         CATEGORYOPTIONCOMBO_DOES_NOT_EXIST if the category option combo does not exist.
+     *         CONSTANT_DOES_NOT_EXIST if the constant does not exist.
+     *         EXPRESSION_NOT_WELL_FORMED if the expression is not well-formed.
      */
-    String expressionIsValid( String formula, Set<Integer> dataElements, Set<Integer> categoryOptionCombos, Set<Integer> constants );
+    String expressionIsValid( String formula, Set<String> dataElements, Set<String> categoryOptionCombos, Set<String> constants );
     
     /**
      * Creates an expression string containing DataElement names and the names of
@@ -229,7 +228,7 @@
      * @param valueMap The map containing data element identifiers and aggregated value.
      * @param days The number to be substituted with the days expression in the formula.
      */
-    String generateExpression( String expression, Map<DataElementOperand, Double> valueMap, Map<Integer, Double> constantMap, Integer days, boolean nullIfNoValues );
+    String generateExpression( String expression, Map<DataElementOperand, Double> valueMap, Map<String, Double> constantMap, Integer days, boolean nullIfNoValues );
     
     /**
      * Returns all Operands included in the formulas for the given collection of

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/interpretation/Interpretation.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/interpretation/Interpretation.java	2012-12-27 14:07:54 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/interpretation/Interpretation.java	2013-01-04 18:10:25 +0000
@@ -43,7 +43,6 @@
 import org.hisp.dhis.period.Period;
 import org.hisp.dhis.period.PeriodType;
 import org.hisp.dhis.reporttable.ReportTable;
-import org.hisp.dhis.user.User;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.annotation.JsonView;

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/mapping/Map.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/mapping/Map.java	2012-12-27 14:07:54 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/mapping/Map.java	2013-01-04 18:10:25 +0000
@@ -40,7 +40,6 @@
 
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.annotation.JsonView;
-import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
 import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
 import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;

=== modified file 'dhis-2/dhis-api/src/test/java/org/hisp/dhis/dataelement/OperandTest.java'
--- dhis-2/dhis-api/src/test/java/org/hisp/dhis/dataelement/OperandTest.java	2011-12-26 10:07:59 +0000
+++ dhis-2/dhis-api/src/test/java/org/hisp/dhis/dataelement/OperandTest.java	2013-01-04 18:10:25 +0000
@@ -27,10 +27,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertNull;
-import static junit.framework.Assert.assertTrue;
+import static org.junit.Assert.*;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -46,11 +43,11 @@
     @Test
     public void getRelevantAggregationLevel()
     {
-        DataElementOperand operand = new DataElementOperand( 1, 1, "Operand", null, null, new ArrayList<Integer>(), 0 );
+        DataElementOperand operand = new DataElementOperand( "a", "a", "Operand", null, null, new ArrayList<Integer>(), 0 );
         
         assertNull( operand.getRelevantAggregationLevel( 1 ) );
         
-        operand = new DataElementOperand( 1, 1, "Operand", null, null, Arrays.asList( 3, 5 ), 0 );
+        operand = new DataElementOperand( "a", "a", "Operand", null, null, Arrays.asList( 3, 5 ), 0 );
         
         assertEquals( new Integer( 3 ), operand.getRelevantAggregationLevel( 1 ) );
         assertEquals( new Integer( 3 ), operand.getRelevantAggregationLevel( 2 ) );
@@ -63,12 +60,12 @@
     @Test
     public void aggregationLevelIsValid()
     {
-        DataElementOperand operand = new DataElementOperand( 1, 1, "Operand", null, null, new ArrayList<Integer>(), 0 );
+        DataElementOperand operand = new DataElementOperand( "a", "a", "Operand", null, null, new ArrayList<Integer>(), 0 );
         
         assertTrue( operand.aggregationLevelIsValid( 1, 3 ) );
         assertTrue( operand.aggregationLevelIsValid( 4, 3 ) );
         
-        operand = new DataElementOperand( 1, 1, "Operand", null, null, Arrays.asList( 3, 5 ), 0 );
+        operand = new DataElementOperand( "a", "a", "Operand", null, null, Arrays.asList( 3, 5 ), 0 );
 
         assertTrue( operand.aggregationLevelIsValid( 2, 2 ) );
         assertTrue( operand.aggregationLevelIsValid( 2, 3 ) );

=== modified file 'dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/dataintegrity/DefaultDataIntegrityService.java'
--- dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/dataintegrity/DefaultDataIntegrityService.java	2012-09-15 14:27:07 +0000
+++ dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/dataintegrity/DefaultDataIntegrityService.java	2013-01-04 18:10:25 +0000
@@ -27,8 +27,8 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+import static org.hisp.dhis.common.IdentifiableObjectUtils.getUids;
 import static org.hisp.dhis.system.util.ListUtils.getDuplicates;
-import static org.hisp.dhis.system.util.ConversionUtils.*;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -40,10 +40,8 @@
 import java.util.TreeMap;
 
 import org.hisp.dhis.common.comparator.IdentifiableObjectNameComparator;
-import org.hisp.dhis.constant.Constant;
 import org.hisp.dhis.constant.ConstantService;
 import org.hisp.dhis.dataelement.DataElement;
-import org.hisp.dhis.dataelement.DataElementCategoryOptionCombo;
 import org.hisp.dhis.dataelement.DataElementCategoryService;
 import org.hisp.dhis.dataelement.DataElementGroup;
 import org.hisp.dhis.dataelement.DataElementGroupSet;
@@ -358,9 +356,9 @@
     {
         SortedMap<Indicator, String> invalids = new TreeMap<Indicator, String>( IdentifiableObjectNameComparator.INSTANCE );
 
-        Set<Integer> dataElements = new HashSet<Integer>( getIdentifiers( DataElement.class, dataElementService.getAllDataElements() ) );
-        Set<Integer> categoryOptionCombos = new HashSet<Integer>( getIdentifiers( DataElementCategoryOptionCombo.class, categoryService.getAllDataElementCategoryOptionCombos() ) );
-        Set<Integer> constants = new HashSet<Integer>( getIdentifiers( Constant.class, constantService.getAllConstants() ) );
+        Set<String> dataElements = new HashSet<String>( getUids( dataElementService.getAllDataElements() ) );
+        Set<String> categoryOptionCombos = new HashSet<String>( getUids( categoryService.getAllDataElementCategoryOptionCombos() ) );
+        Set<String> constants = new HashSet<String>( getUids( constantService.getAllConstants() ) );
         
         for ( Indicator indicator : indicatorService.getAllIndicators() )
         {
@@ -379,9 +377,9 @@
     {
         SortedMap<Indicator, String> invalids = new TreeMap<Indicator, String>( IdentifiableObjectNameComparator.INSTANCE );
 
-        Set<Integer> dataElements = new HashSet<Integer>( getIdentifiers( DataElement.class, dataElementService.getAllDataElements() ) );
-        Set<Integer> categoryOptionCombos = new HashSet<Integer>( getIdentifiers( DataElementCategoryOptionCombo.class, categoryService.getAllDataElementCategoryOptionCombos() ) );
-        Set<Integer> constants = new HashSet<Integer>( getIdentifiers( Constant.class, constantService.getAllConstants() ) );
+        Set<String> dataElements = new HashSet<String>( getUids( dataElementService.getAllDataElements() ) );
+        Set<String> categoryOptionCombos = new HashSet<String>( getUids( categoryService.getAllDataElementCategoryOptionCombos() ) );
+        Set<String> constants = new HashSet<String>( getUids( constantService.getAllConstants() ) );
         
         for ( Indicator indicator : indicatorService.getAllIndicators() )
         {
@@ -539,9 +537,9 @@
         SortedMap<ValidationRule, String> invalids = new TreeMap<ValidationRule, String>(
             IdentifiableObjectNameComparator.INSTANCE );
 
-        Set<Integer> dataElements = new HashSet<Integer>( getIdentifiers( DataElement.class, dataElementService.getAllDataElements() ) );
-        Set<Integer> categoryOptionCombos = new HashSet<Integer>( getIdentifiers( DataElementCategoryOptionCombo.class, categoryService.getAllDataElementCategoryOptionCombos() ) );
-        Set<Integer> constants = new HashSet<Integer>( getIdentifiers( Constant.class, constantService.getAllConstants() ) );
+        Set<String> dataElements = new HashSet<String>( getUids( dataElementService.getAllDataElements() ) );
+        Set<String> categoryOptionCombos = new HashSet<String>( getUids( categoryService.getAllDataElementCategoryOptionCombos() ) );
+        Set<String> constants = new HashSet<String>( getUids( constantService.getAllConstants() ) );
         
         for ( ValidationRule rule : validationRuleService.getAllValidationRules() )
         {
@@ -561,9 +559,9 @@
         SortedMap<ValidationRule, String> invalids = new TreeMap<ValidationRule, String>(
             IdentifiableObjectNameComparator.INSTANCE );
 
-        Set<Integer> dataElements = new HashSet<Integer>( getIdentifiers( DataElement.class, dataElementService.getAllDataElements() ) );
-        Set<Integer> categoryOptionCombos = new HashSet<Integer>( getIdentifiers( DataElementCategoryOptionCombo.class, categoryService.getAllDataElementCategoryOptionCombos() ) );
-        Set<Integer> constants = new HashSet<Integer>( getIdentifiers( Constant.class, constantService.getAllConstants() ) );
+        Set<String> dataElements = new HashSet<String>( getUids( dataElementService.getAllDataElements() ) );
+        Set<String> categoryOptionCombos = new HashSet<String>( getUids( categoryService.getAllDataElementCategoryOptionCombos() ) );
+        Set<String> constants = new HashSet<String>( getUids( constantService.getAllConstants() ) );
         
         for ( ValidationRule rule : validationRuleService.getAllValidationRules() )
         {

=== modified file 'dhis-2/dhis-services/dhis-service-aggregationengine-default/src/main/java/org/hisp/dhis/aggregation/impl/indicator/IndicatorAggregation.java'
--- dhis-2/dhis-services/dhis-service-aggregationengine-default/src/main/java/org/hisp/dhis/aggregation/impl/indicator/IndicatorAggregation.java	2012-07-20 11:41:57 +0000
+++ dhis-2/dhis-services/dhis-service-aggregationengine-default/src/main/java/org/hisp/dhis/aggregation/impl/indicator/IndicatorAggregation.java	2013-01-04 18:10:25 +0000
@@ -147,7 +147,7 @@
     
     private String generateExpression( String expression, Date startDate, Date endDate, OrganisationUnit organisationUnit, int days )
     {
-        Map<Integer, Double> constantMap = constantService.getConstantMap();
+        Map<String, Double> constantMap = constantService.getConstantMap();
         
         Set<DataElementOperand> operands = expressionService.getOperandsInExpression( expression );
         

=== modified file 'dhis-2/dhis-services/dhis-service-aggregationengine-default/src/test/java/org/hisp/dhis/aggregation/AggregationServiceTest.java'
--- dhis-2/dhis-services/dhis-service-aggregationengine-default/src/test/java/org/hisp/dhis/aggregation/AggregationServiceTest.java	2012-11-20 17:04:08 +0000
+++ dhis-2/dhis-services/dhis-service-aggregationengine-default/src/test/java/org/hisp/dhis/aggregation/AggregationServiceTest.java	2013-01-05 15:22:55 +0000
@@ -27,8 +27,8 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+import static org.hisp.dhis.expression.Expression.SEPARATOR;
 import static org.junit.Assert.assertEquals;
-import static org.hisp.dhis.expression.Expression.SEPARATOR;
 
 import java.util.Date;
 
@@ -77,16 +77,10 @@
     private DataElementCategoryOptionCombo categoryOptionComboA;
     private DataElementCategoryOptionCombo categoryOptionComboB;    
     
-    private int categoryOptionComboIdA;
-    
     private DataElement dataElementA;
     private DataElement dataElementB;
     private DataElement dataElementC;
-    
-    private int dataElementIdA;
-    private int dataElementIdB;
-    private int dataElementIdC;
-    
+        
     private IndicatorType indicatorType;
     
     private Indicator indicatorA;
@@ -160,7 +154,7 @@
         categoryOptionComboA = createCategoryOptionCombo( categoryCombo, categoryOptionA );
         categoryOptionComboB = createCategoryOptionCombo( categoryCombo, categoryOptionB );
         
-        categoryOptionComboIdA = categoryService.addDataElementCategoryOptionCombo( categoryOptionComboA );
+        categoryService.addDataElementCategoryOptionCombo( categoryOptionComboA );
         categoryService.addDataElementCategoryOptionCombo( categoryOptionComboB );
 
         // ---------------------------------------------------------------------
@@ -171,9 +165,9 @@
         dataElementB = createDataElement( 'B', DataElement.VALUE_TYPE_BOOL, DataElement.AGGREGATION_OPERATOR_SUM, categoryCombo );
         dataElementC = createDataElement( 'C', DataElement.VALUE_TYPE_INT, DataElement.AGGREGATION_OPERATOR_SUM, categoryCombo );
 
-        dataElementIdA = dataElementService.addDataElement( dataElementA );
-        dataElementIdB = dataElementService.addDataElement( dataElementB );
-        dataElementIdC = dataElementService.addDataElement( dataElementC );
+        dataElementService.addDataElement( dataElementA );
+        dataElementService.addDataElement( dataElementB );
+        dataElementService.addDataElement( dataElementC );
 
         // ---------------------------------------------------------------------
         // Setup Indicators
@@ -185,11 +179,11 @@
         indicatorService.addIndicatorType( indicatorType );
         
         indicatorA = createIndicator( 'A', indicatorType );
-        indicatorA.setNumerator( "[" + dataElementIdA + SEPARATOR + categoryOptionComboIdA + "]+150" );
-        indicatorA.setDenominator( "[" + dataElementIdB + SEPARATOR + categoryOptionComboIdA + "]" );
+        indicatorA.setNumerator( "#{" + dataElementA.getUid() + SEPARATOR + categoryOptionComboA.getUid() + "}+150" );
+        indicatorA.setDenominator( "#{" + dataElementB.getUid() + SEPARATOR + categoryOptionComboA.getUid() + "}" );
         
         indicatorB = createIndicator( 'B', indicatorType );
-        indicatorB.setNumerator( "[" + dataElementIdC + "]" );
+        indicatorB.setNumerator( "#{" + dataElementC.getUid() + "}" );
         indicatorB.setDenominator( "1" );
         
         indicatorService.addIndicator( indicatorA );

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/constant/DefaultConstantService.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/constant/DefaultConstantService.java	2011-12-11 00:00:06 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/constant/DefaultConstantService.java	2013-01-04 18:10:25 +0000
@@ -91,13 +91,13 @@
         return constantStore.getAll();
     }
     
-    public Map<Integer, Double> getConstantMap()
+    public Map<String, Double> getConstantMap()
     {
-        Map<Integer, Double> map = new HashMap<Integer, Double>();
+        Map<String, Double> map = new HashMap<String, Double>();
         
         for ( Constant constant : getAllConstants() )
         {
-            map.put( constant.getId(), constant.getValue() );
+            map.put( constant.getUid(), constant.getValue() );
         }
         
         return map;

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataelement/DefaultDataElementCategoryService.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataelement/DefaultDataElementCategoryService.java	2012-10-04 16:52:13 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataelement/DefaultDataElementCategoryService.java	2013-01-05 15:22:55 +0000
@@ -502,6 +502,18 @@
         updateDataElementCategoryCombo( categoryCombo );
     }
     
+    public Map<String, Integer> getDataElementCategoryOptionComboUidIdMap()
+    {
+        Map<String, Integer> map = new HashMap<String, Integer>();
+        
+        for ( DataElementCategoryOptionCombo coc : getAllDataElementCategoryOptionCombos() )
+        {
+            map.put( coc.getUid(), coc.getId() );
+        }
+        
+        return map;
+    }
+    
     public int getDataElementCategoryCount()
     {
         return dataElementCategoryStore.getCount();

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataelement/DefaultDataElementService.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataelement/DefaultDataElementService.java	2012-12-22 12:26:34 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataelement/DefaultDataElementService.java	2013-01-05 15:22:55 +0000
@@ -329,11 +329,23 @@
         return i18n( i18nService, dataElementStore.getDataElementsByAggregationLevel( aggregationLevel ) );
     }
     
-    public Map<Integer, Set<Integer>> getDataElementCategoryOptionCombos()
+    public Map<String, Set<String>> getDataElementCategoryOptionCombos()
     {
         return dataElementStore.getDataElementCategoryOptionCombos();
     }
     
+    public Map<String, Integer> getDataElementUidIdMap()
+    {
+        Map<String, Integer> map = new HashMap<String, Integer>();
+        
+        for ( DataElement dataElement : getAllDataElements() )
+        {
+            map.put( dataElement.getUid(), dataElement.getId() );
+        }
+        
+        return map;
+    }
+    
     public Collection<DataElement> getDataElements( DataSet dataSet, String key, Integer max )
     {
         return dataElementStore.get( dataSet, key, max );

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataelement/hibernate/HibernateDataElementStore.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataelement/hibernate/HibernateDataElementStore.java	2012-12-22 12:26:34 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataelement/hibernate/HibernateDataElementStore.java	2013-01-05 15:22:55 +0000
@@ -224,12 +224,15 @@
         return getQuery( hql ).setInteger( "aggregationLevel", aggregationLevel ).list();
     }
 
-    public Map<Integer, Set<Integer>> getDataElementCategoryOptionCombos()
+    public Map<String, Set<String>> getDataElementCategoryOptionCombos()
     {
-        final String sql = "select de.dataelementid, coc.categoryoptioncomboid from dataelement de " +
-            "join categorycombos_optioncombos coc on de.categorycomboid=coc.categorycomboid";
+        final String sql = 
+            "select de.uid, coc.uid " +
+            "from dataelement de " +
+            "join categorycombos_optioncombos cc on de.categorycomboid = cc.categorycomboid " +
+            "join categoryoptioncombo coc on cc.categoryoptioncomboid = coc.categoryoptioncomboid";
         
-        final Map<Integer, Set<Integer>> sets = new HashMap<Integer, Set<Integer>>();
+        final Map<String, Set<String>> sets = new HashMap<String, Set<String>>();
         
         jdbcTemplate.query( sql, new RowCallbackHandler()
         {
@@ -237,13 +240,13 @@
             public void processRow( ResultSet rs )
                 throws SQLException
             {
-                int dataElementId = rs.getInt( 1 );
-                int categoryOptionComboId = rs.getInt( 2 );
-                
-                Set<Integer> set = sets.get( dataElementId ) != null ? sets.get( dataElementId ) : new HashSet<Integer>();
-                
-                set.add( categoryOptionComboId );                
-                sets.put( dataElementId, set );
+                String dataElement = rs.getString( 1 );
+                String categoryOptionCombo = rs.getString( 2 );
+                
+                Set<String> set = sets.get( dataElement ) != null ? sets.get( dataElement ) : new HashSet<String>();
+                
+                set.add( categoryOptionCombo );                
+                sets.put( dataElement, set );
             }
         } );
         

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataentryform/DefaultDataEntryFormService.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataentryform/DefaultDataEntryFormService.java	2012-10-10 18:17:25 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataentryform/DefaultDataEntryFormService.java	2013-01-04 18:10:25 +0000
@@ -190,15 +190,15 @@
 
             if ( identifierMatcher.find() && identifierMatcher.groupCount() > 0 )
             {
-                int dataElementId = Integer.parseInt( identifierMatcher.group( 1 ) );
+                String dataElementId = identifierMatcher.group( 1 );
                 DataElement dataElement = dataElementService.getDataElement( dataElementId );
 
-                int optionComboId = Integer.parseInt( identifierMatcher.group( 2 ) );
+                String optionComboId = identifierMatcher.group( 2 );
                 DataElementCategoryOptionCombo categegoryOptionCombo = categoryService.getDataElementCategoryOptionCombo( optionComboId );
                 String optionComboName = categegoryOptionCombo != null ? categegoryOptionCombo.getName() : "[ " + i18n.getString( "cat_option_combo_not_exist" ) + " ]";
 
                 StringBuilder title = dataElement != null ? 
-                    new StringBuilder( "title=\"" ).append( dataElement.getId() ).append( " - " ).
+                    new StringBuilder( "title=\"" ).append( dataElementId ).append( " - " ).
                     append( dataElement.getDisplayName() ).append( " - " ).append( optionComboId ).append( " - " ).
                     append( optionComboName ).append( " - " ).append( dataElement.getType() ).append( "\"" ) : new StringBuilder();
 
@@ -207,7 +207,7 @@
             }
             else if ( dataElementTotalMatcher.find() && dataElementTotalMatcher.groupCount() > 0 )
             {
-                int dataElementId = Integer.parseInt( dataElementTotalMatcher.group( 1 ) );
+                String dataElementId = dataElementTotalMatcher.group( 1 );
                 DataElement dataElement = dataElementService.getDataElement( dataElementId );
 
                 displayValue = dataElement != null ? "value=\"[ " + dataElement.getDisplayName() + " ]\"" : "[ " + i18n.getString( "data_element_not_exist" ) + " ]";
@@ -215,7 +215,7 @@
             }
             else if ( indicatorMatcher.find() && indicatorMatcher.groupCount() > 0 )
             {
-                int indicatorId = Integer.parseInt( indicatorMatcher.group( 1 ) );
+                String indicatorId = indicatorMatcher.group( 1 );
                 Indicator indicator = indicatorService.getIndicator( indicatorId );
 
                 displayValue = indicator != null ? "value=\"[ " + indicator.getDisplayName() + " ]\"" : "[ " + i18n.getString( "indicator_not_exist" ) + " ]";
@@ -223,7 +223,7 @@
             }
             else if ( dynamicInputMatcher.find() && dynamicInputMatcher.groupCount() > 0 )
             {
-                int categoryOptionComboId = Integer.parseInt( dynamicInputMatcher.group( 2 ) );
+                String categoryOptionComboId = dynamicInputMatcher.group( 2 );
                 DataElementCategoryOptionCombo categoryOptionCombo = categoryService.getDataElementCategoryOptionCombo( categoryOptionComboId );
                 
                 displayValue = categoryOptionCombo != null ? "value=\"[ " + categoryOptionCombo.getDisplayName() + " ]\"" : "[ " + i18n.getString( "cat_option_combo_not_exist" ) + " ]";
@@ -231,7 +231,7 @@
             }
             else if ( dynamicSelectMatcher.find() && dynamicSelectMatcher.groupCount() > 0 )
             {
-                int categoryComboId = Integer.parseInt( dynamicSelectMatcher.group( 1 ) );
+                String categoryComboId = dynamicSelectMatcher.group( 1 );
                 DataElementCategoryCombo categoryCombo = categoryService.getDataElementCategoryCombo( categoryComboId );
                 
                 displayValue = categoryCombo != null ? "value=\"[ " + categoryCombo.getDisplayName() + " ]\"" : "[ " + i18n.getString( "cat_combo_not_exist" );
@@ -273,7 +273,7 @@
 
         Matcher inputMatcher = INPUT_PATTERN.matcher( htmlCode );
 
-        Map<Integer, DataElement> dataElementMap = getDataElementMap( dataSet );
+        Map<String, DataElement> dataElementMap = getDataElementMap( dataSet );
 
         while ( inputMatcher.find() )
         {
@@ -289,8 +289,8 @@
 
             if ( identifierMatcher.find() && identifierMatcher.groupCount() > 0 )
             {
-                int dataElementId = Integer.parseInt( identifierMatcher.group( 1 ) );
-                int optionComboId = Integer.parseInt( identifierMatcher.group( 2 ) );
+                String dataElementId = identifierMatcher.group( 1 );
+                String optionComboId = identifierMatcher.group( 2 );
 
                 DataElement dataElement = dataElementMap.get( dataElementId );
 
@@ -327,13 +327,12 @@
                 }
 
                 inputHtml = inputHtml.replace( TAG_CLOSE, appendCode );
-                inputHtml += "<span id=\"" + dataElement.getId() + "-dataelement\" style=\"display:none\">" + dataElement.getFormNameFallback() + "</span>";
-                inputHtml += "<span id=\"" + categoryOptionCombo.getId() + "-optioncombo\" style=\"display:none\">" + categoryOptionCombo.getName() + "</span>";
+                inputHtml += "<span id=\"" + dataElement.getUid() + "-dataelement\" style=\"display:none\">" + dataElement.getFormNameFallback() + "</span>";
+                inputHtml += "<span id=\"" + categoryOptionCombo.getUid() + "-optioncombo\" style=\"display:none\">" + categoryOptionCombo.getName() + "</span>";
             }
             else if ( dynamicInputMather.find() && dynamicInputMather.groupCount() > 0 )
             {
-                int optionComboId = Integer.parseInt( dynamicInputMather.group( 2 ) );
-
+                String optionComboId = dynamicInputMather.group( 2 );
                 DataElementCategoryOptionCombo categoryOptionCombo = categoryService.getDataElementCategoryOptionCombo( optionComboId );
 
                 if ( categoryOptionCombo == null )
@@ -364,7 +363,7 @@
             return null;
         }
         
-        Map<Integer, DataElement> dataElementMap = getDataElementMap( dataSet );
+        Map<String, DataElement> dataElementMap = getDataElementMap( dataSet );
         
         Set<DataElement> dataElements = new HashSet<DataElement>();
         
@@ -381,12 +380,12 @@
             
             if ( identifierMatcher.find() && identifierMatcher.groupCount() > 0 )
             {
-                int dataElementId = Integer.parseInt( identifierMatcher.group( 1 ) );
+                String dataElementId = identifierMatcher.group( 1 );
                 dataElement = dataElementMap.get( dataElementId );
             }
             else if ( dataElementTotalMatcher.find() && dataElementTotalMatcher.groupCount() > 0 )
             {
-                int dataElementId = Integer.parseInt( dataElementTotalMatcher.group( 1 ) );
+                String dataElementId = dataElementTotalMatcher.group( 1 );
                 dataElement = dataElementMap.get( dataElementId );
             }
             
@@ -418,8 +417,8 @@
             
             if ( identifierMatcher.find() && identifierMatcher.groupCount() > 0 )
             {
-                int dataElementId = Integer.parseInt( identifierMatcher.group( 1 ) );
-                int categoryOptionComboId = Integer.parseInt( identifierMatcher.group( 2 ) );                
+                String dataElementId = identifierMatcher.group( 1 );
+                String categoryOptionComboId = identifierMatcher.group( 2 );                
 
                 DataElementOperand operand = new DataElementOperand( dataElementId, categoryOptionComboId );
                 
@@ -471,13 +470,13 @@
      * Returns a Map of all DataElements in the given DataSet where the key is
      * the DataElement identifier and the value is the DataElement.
      */
-    private Map<Integer, DataElement> getDataElementMap( DataSet dataSet )
+    private Map<String, DataElement> getDataElementMap( DataSet dataSet )
     {
-        Map<Integer, DataElement> map = new HashMap<Integer, DataElement>();
+        Map<String, DataElement> map = new HashMap<String, DataElement>();
 
         for ( DataElement element : dataSet.getDataElements() )
         {
-            map.put( element.getId(), element );
+            map.put( element.getUid(), element );
         }
 
         return map;

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/datavalue/hibernate/HibernateDataValueStore.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/datavalue/hibernate/HibernateDataValueStore.java	2012-07-25 14:44:02 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/datavalue/hibernate/HibernateDataValueStore.java	2013-01-05 15:22:55 +0000
@@ -409,27 +409,34 @@
     {
         Map<DataElementOperand, Double> map = new HashMap<DataElementOperand, Double>();
         
+        if ( dataElements.isEmpty() )
+        {
+            return map;
+        }
+        
         final String sql = 
-            "select dataelementid, categoryoptioncomboid, value " +
-            "from datavalue " +
-            "where dataelementid in (" + TextUtils.getCommaDelimitedString( ConversionUtils.getIdentifiers( DataElement.class, dataElements ) ) + ") " +
-            "and periodid = " + period.getId() + " " +
-            "and sourceid = " + unit.getId();
+            "select de.uid, coc.uid, value " +
+            "from datavalue dv " +
+            "join dataelement de on dv.dataelementid = de.dataelementid " +
+            "join categoryoptioncombo coc on dv.categoryoptioncomboid = coc.categoryoptioncomboid " +
+            "where dv.dataelementid in (" + TextUtils.getCommaDelimitedString( ConversionUtils.getIdentifiers( DataElement.class, dataElements ) ) + ") " +
+            "and dv.periodid = " + period.getId() + " " +
+            "and dv.sourceid = " + unit.getId();
         
         SqlRowSet rowSet = jdbcTemplate.queryForRowSet( sql );
         
         while ( rowSet.next() )
         {
-            int dataElementId = rowSet.getInt( "dataelementid" );
-            int optionComboId = rowSet.getInt( "categoryoptioncomboid" );
-            Double value = MathUtils.parseDouble( rowSet.getString( "value" ) );
+            String dataElement = rowSet.getString( 1 );
+            String optionCombo = rowSet.getString( 2 );
+            Double value = MathUtils.parseDouble( rowSet.getString( 3 ) );
             
             if ( value != null )
             {
-                map.put( new DataElementOperand( dataElementId, optionComboId ), value );
+                map.put( new DataElementOperand( dataElement, optionCombo ), value );
             }
         }
         
-        return map;        
+        return map; 
     }
 }

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/expression/DefaultExpressionService.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/expression/DefaultExpressionService.java	2013-01-01 19:53:04 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/expression/DefaultExpressionService.java	2013-01-05 15:22:55 +0000
@@ -40,8 +40,8 @@
 import java.util.Map;
 import java.util.Set;
 import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
+import org.apache.commons.lang.StringUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.hisp.dhis.common.GenericStore;
@@ -73,9 +73,6 @@
 {
     private static final Log log = LogFactory.getLog( DefaultExpressionService.class );
 
-    private final Pattern FORMULA_PATTERN = Pattern.compile( FORMULA_EXPRESSION );
-    private final Pattern OPERAND_PATTERN = Pattern.compile( OPERAND_EXPRESSION );
-
     // -------------------------------------------------------------------------
     // Dependencies
     // -------------------------------------------------------------------------
@@ -142,7 +139,7 @@
     // -------------------------------------------------------------------------
     
     public Double getExpressionValue( Expression expression, Map<DataElementOperand, Double> valueMap, 
-        Map<Integer, Double> constantMap, Integer days )
+        Map<String, Double> constantMap, Integer days )
     {
         final String expressionString = generateExpression( expression.getExpression(), valueMap, constantMap, days, expression.isNullIfBlank() );
 
@@ -161,8 +158,7 @@
 
             while ( matcher.find() )
             {
-                final DataElement dataElement = dataElementService.getDataElement( DataElementOperand.getOperand(
-                    matcher.group() ).getDataElementId() );
+                final DataElement dataElement = dataElementService.getDataElement( matcher.group( 1 ) );
 
                 if ( dataElement != null )
                 {
@@ -186,8 +182,8 @@
 
             while ( matcher.find() )
             {
-                DataElementCategoryOptionCombo categoryOptionCombo = categoryService.getDataElementCategoryOptionCombo( 
-                    DataElementOperand.getOperand( matcher.group() ).getOptionComboId() );
+                DataElementCategoryOptionCombo categoryOptionCombo = categoryService.
+                    getDataElementCategoryOptionCombo( matcher.group( 2 ) );
 
                 if ( categoryOptionCombo != null )
                 {
@@ -199,55 +195,10 @@
         return optionCombosInExpression;
     }
     
-    public String convertExpression( String expression, Map<Object, Integer> dataElementMapping,
-        Map<Object, Integer> categoryOptionComboMapping )
-    {
-        //TODO constants
-        
-        final StringBuffer convertedFormula = new StringBuffer();
-
-        if ( expression != null )
-        {
-            final Matcher matcher = OPERAND_PATTERN.matcher( expression );
-
-            while ( matcher.find() )
-            {
-                String match = matcher.group();
-
-                final DataElementOperand operand = DataElementOperand.getOperand( match );
-
-                final Integer mappedDataElementId = dataElementMapping.get( operand.getDataElementId() );
-                final Integer mappedCategoryOptionComboId = categoryOptionComboMapping.get( operand.getOptionComboId() );
-
-                if ( mappedDataElementId == null )
-                {
-                    log.warn( "Data element identifier refers to non-existing object: " + operand.getDataElementId() );
-
-                    match = NULL_REPLACEMENT;
-                }
-                else if ( !operand.isTotal() && mappedCategoryOptionComboId == null )
-                {
-                    log.warn( "Category option combo identifier refers to non-existing object: "
-                        + operand.getOptionComboId() );
-
-                    match = NULL_REPLACEMENT;
-                }
-                else
-                {
-                    match = EXP_OPEN + mappedDataElementId + SEPARATOR + mappedCategoryOptionComboId + EXP_CLOSE;
-                }
-
-                matcher.appendReplacement( convertedFormula, match );
-            }
-
-            matcher.appendTail( convertedFormula );
-        }
-
-        return convertedFormula.toString();
-    }
-
     public Set<DataElementOperand> getOperandsInExpression( String expression )
     {
+        //TODO reimplement using uids
+        
         Set<DataElementOperand> operandsInExpression = null;
 
         if ( expression != null )
@@ -279,7 +230,7 @@
                     !expressionIsValid( indicator.getDenominator() ).equals( VALID ) )
                 {
                     iterator.remove();
-                    log.warn( "Indicator is invalid: " + indicator );
+                    log.warn( "Indicator is invalid: " + indicator + ", " + indicator.getNumerator() + ", " + indicator.getDenominator() );
                 }
             }
         }
@@ -290,79 +241,69 @@
         return expressionIsValid( formula, null, null, null );
     }
     
-    public String expressionIsValid( String formula, Set<Integer> dataElements, Set<Integer> categoryOptionCombos, Set<Integer> constants )
+    public String expressionIsValid( String expression, Set<String> dataElements, Set<String> categoryOptionCombos, Set<String> constants )
     {
-        if ( formula == null )
+        if ( expression == null || expression.isEmpty() )
         {
             return EXPRESSION_IS_EMPTY;
         }
 
-        final StringBuffer buffer = new StringBuffer();
-
-        final Matcher matcher = FORMULA_PATTERN.matcher( formula );
-
-        while ( matcher.find() )
-        {
-            DataElementOperand operand = null;
-
-            final String match = matcher.group();
-
-            if ( DAYS_EXPRESSION.equals( match ) )
-            {
-                // Ignore
-            }
-            else if ( match.matches( CONSTANT_EXPRESSION ) )
-            {
-                Integer id = null;
-                
-                try
-                {
-                    id = Integer.parseInt( stripConstantExpression( match ) );
-                }
-                catch ( NumberFormatException ex )
-                {
-                    return ID_NOT_NUMERIC;
-                }
-                
-                if ( constants != null ? !constants.contains( id ) : constantService.getConstant( id ) == null )
-                {
-                    return CONSTANT_DOES_NOT_EXIST;
-                }                    
-            }
-            else
-            {
-                try
-                {
-                    operand = DataElementOperand.getOperand( match );
-                }
-                catch ( NumberFormatException ex )
-                {
-                    return ID_NOT_NUMERIC;
-                }
-
-                if ( dataElements != null ? !dataElements.contains( operand.getDataElementId() ) : dataElementService.getDataElement( operand.getDataElementId() ) == null )
-                {
-                    return DATAELEMENT_DOES_NOT_EXIST;
-                }
-
-                if ( !operand.isTotal() && ( categoryOptionCombos != null ? !categoryOptionCombos.contains( operand.getOptionComboId() ) :
-                    categoryService.getDataElementCategoryOptionCombo( operand.getOptionComboId() ) == null ) )
-                {
-                    return CATEGORYOPTIONCOMBO_DOES_NOT_EXIST;
-                }
-            }
-
-            // -----------------------------------------------------------------
-            // Replacing the operand with 1.1 in order to later be able to
-            // verify that the formula is mathematically valid
-            // -----------------------------------------------------------------
-
-            matcher.appendReplacement( buffer, "1.1" );
-        }
-
-        matcher.appendTail( buffer );
-
-        if ( MathUtils.expressionHasErrors( buffer.toString() ) )
+        // ---------------------------------------------------------------------
+        // Operands
+        // ---------------------------------------------------------------------
+        
+        StringBuffer sb = new StringBuffer();
+        Matcher matcher = OPERAND_PATTERN.matcher( expression );
+
+        while ( matcher.find() )
+        {
+            String de = matcher.group( 1 );
+            String coc = matcher.group( 2 );
+            
+            if ( dataElements != null ? !dataElements.contains( de ) : dataElementService.getDataElement( de ) == null )
+            {
+                return DATAELEMENT_DOES_NOT_EXIST;
+            }
+
+            if ( !operandIsTotal( matcher ) && ( 
+                categoryOptionCombos != null ? !categoryOptionCombos.contains( coc ) : categoryService.getDataElementCategoryOptionCombo( coc ) == null ) )
+            {
+                return CATEGORYOPTIONCOMBO_DOES_NOT_EXIST;
+            }
+                    
+            matcher.appendReplacement( sb, "1.1" );
+        }
+        
+        expression = appendTail( matcher, sb );
+
+        // ---------------------------------------------------------------------
+        // Constants
+        // ---------------------------------------------------------------------
+        
+        matcher = CONSTANT_PATTERN.matcher( expression );
+        sb = new StringBuffer();
+        
+        while ( matcher.find() )
+        {
+            String constant = matcher.group( 1 );
+            
+            if ( constants != null ? !constants.contains( constant ) : constantService.getConstant( constant ) == null )
+            {
+                return CONSTANT_DOES_NOT_EXIST;
+            }
+            
+            matcher.appendReplacement( sb, "1.1" );
+        }
+
+        expression = appendTail( matcher, sb );
+
+        expression = expression.replaceAll( DAYS_EXPRESSION, "1.1" );
+        
+        // ---------------------------------------------------------------------
+        // Well-formed expression
+        // ---------------------------------------------------------------------
+
+        if ( MathUtils.expressionHasErrors( expression ) )
         {
             return EXPRESSION_NOT_WELL_FORMED;
         }
@@ -370,67 +311,81 @@
         return VALID;
     }
 
-    public String getExpressionDescription( String formula )
+    public String getExpressionDescription( String expression )
     {
-        StringBuffer buffer = null;
-
-        if ( formula != null )
-        {
-            buffer = new StringBuffer();
-
-            final Matcher matcher = FORMULA_PATTERN.matcher( formula );
-
-            while ( matcher.find() )
-            {
-                String match = matcher.group();
-
-                if ( DAYS_EXPRESSION.equals( match ) )
-                {
-                    match = DAYS_DESCRIPTION;
-                }
-                else if ( match.matches( CONSTANT_EXPRESSION ) )
-                {
-                    final Integer id = Integer.parseInt( stripConstantExpression( match ) );
-                    
-                    final Constant constant = constantService.getConstant( id );
-                    
-                    if ( constant == null )
-                    {
-                        throw new IllegalArgumentException( "Identifier does not reference a constant: " + id );
-                    }
-                    
-                    match = constant.getDisplayName();
-                }
-                else
-                {
-                    final DataElementOperand operand = DataElementOperand.getOperand( match );
-
-                    final DataElement dataElement = dataElementService.getDataElement( operand.getDataElementId() );
-                    final DataElementCategoryOptionCombo categoryOptionCombo = categoryService
-                        .getDataElementCategoryOptionCombo( operand.getOptionComboId() );
-
-                    if ( dataElement == null )
-                    {
-                        throw new IllegalArgumentException( "Identifier does not reference a data element: "
-                            + operand.getDataElementId() );
-                    }
-
-                    if ( !operand.isTotal() && categoryOptionCombo == null )
-                    {
-                        throw new IllegalArgumentException( "Identifier does not reference a category option combo: "
-                            + operand.getOptionComboId() );
-                    }
-
-                    match = DataElementOperand.getPrettyName( dataElement, categoryOptionCombo );
-                }
-
-                matcher.appendReplacement( buffer, match );
-            }
-
-            matcher.appendTail( buffer );
-        }
-
-        return buffer != null ? buffer.toString() : null;
+        if ( expression == null || expression.isEmpty() )
+        {
+            return null;
+        }
+
+        // ---------------------------------------------------------------------
+        // Operands
+        // ---------------------------------------------------------------------
+        
+        StringBuffer sb = new StringBuffer();
+        Matcher matcher = OPERAND_PATTERN.matcher( expression );
+        
+        while ( matcher.find() )
+        {
+            String de = matcher.group( 1 );
+            String coc = matcher.group( 2 );
+            
+            DataElement dataElement = dataElementService.getDataElement( de );
+            DataElementCategoryOptionCombo categoryOptionCombo = categoryService.getDataElementCategoryOptionCombo( coc );
+            
+            if ( dataElement == null )
+            {
+                throw new IllegalArgumentException( "Identifier does not reference a data element: " + de );
+            }
+
+            if ( !operandIsTotal( matcher ) && categoryOptionCombo == null )
+            {
+                throw new IllegalArgumentException( "Identifier does not reference a category option combo: " + coc );
+            }
+            
+            matcher.appendReplacement( sb, DataElementOperand.getPrettyName( dataElement, categoryOptionCombo ) );
+        }
+        
+        expression = appendTail( matcher, sb );
+        
+        // ---------------------------------------------------------------------
+        // Constants
+        // ---------------------------------------------------------------------
+
+        sb = new StringBuffer();
+        matcher = CONSTANT_PATTERN.matcher( expression );
+        
+        while ( matcher.find() )
+        {
+            String co = matcher.group( 1 );
+            
+            Constant constant = constantService.getConstant( co );
+            
+            if ( constant == null )
+            {
+                throw new IllegalArgumentException( "Identifier does not reference a constant: " + co );
+            }
+            
+            matcher.appendReplacement( sb, constant.getDisplayName() );
+        }
+
+        expression = appendTail( matcher, sb );
+
+        // ---------------------------------------------------------------------
+        // Days
+        // ---------------------------------------------------------------------
+
+        sb = new StringBuffer();
+        matcher = DAYS_PATTERN.matcher( expression );
+        
+        while ( matcher.find() )
+        {
+            matcher.appendReplacement( sb, DAYS_DESCRIPTION );
+        }
+
+        expression = appendTail( matcher, sb );
+
+        return expression;
     }
 
     public void explodeAndSubstituteExpressions( Collection<Indicator> indicators, Integer days )
@@ -443,7 +398,7 @@
                 indicator.setExplodedDenominator( substituteExpression( indicator.getDenominator(), days ) );
             }
 
-            final Map<Integer, Set<Integer>> dataElementMap = dataElementService.getDataElementCategoryOptionCombos();
+            final Map<String, Set<String>> dataElementMap = dataElementService.getDataElementCategoryOptionCombos();
             
             for ( Indicator indicator : indicators )
             {
@@ -452,161 +407,180 @@
             }     
         }
     }
-        
-    private String explodeExpression( String expression, Map<Integer, Set<Integer>> dataElementMap )
+    
+    private String explodeExpression( String expression, Map<String, Set<String>> dataElementMap )
     {
-        StringBuffer buffer = null;
-
-        if ( expression != null )
-        {
-            final Matcher matcher = OPERAND_PATTERN.matcher( expression );
-
-            buffer = new StringBuffer();
-
-            while ( matcher.find() )
+        if ( expression == null || expression.isEmpty() )
+        {
+            return null;
+        }
+
+        StringBuffer sb = new StringBuffer();
+        Matcher matcher = OPERAND_PATTERN.matcher( expression );
+
+        while ( matcher.find() )
+        {
+            if ( operandIsTotal( matcher ) )
             {
-                final DataElementOperand operand = DataElementOperand.getOperand( matcher.group() );
-                
-                if ( operand.isTotal() )
+                final StringBuilder replace = new StringBuilder( PAR_OPEN );
+
+                for ( String coc : dataElementMap.get( matcher.group( 1 ) ) )
                 {
-                    final StringBuilder replace = new StringBuilder( PAR_OPEN );
-
-                    for ( Integer categoryOptionCombo : dataElementMap.get( operand.getDataElementId() ) )
-                    {
-                        replace.append( EXP_OPEN ).append( operand.getDataElementId() ).append( SEPARATOR ).append(
-                            categoryOptionCombo ).append( EXP_CLOSE ).append( "+" );
-                    }
-
-                    replace.deleteCharAt( replace.length() - 1 ).append( PAR_CLOSE );
-
-                    matcher.appendReplacement( buffer, replace.toString() );
+                    replace.append( EXP_OPEN ).append( matcher.group( 1 ) ).append( SEPARATOR ).append(
+                        coc ).append( EXP_CLOSE ).append( "+" );
                 }
+
+                replace.deleteCharAt( replace.length() - 1 ).append( PAR_CLOSE );
+                matcher.appendReplacement( sb, replace.toString() );
             }
-
-            matcher.appendTail( buffer );
         }
 
-        return buffer != null ? buffer.toString() : null;
+        return appendTail( matcher, sb );
     }
     
     public String explodeExpression( String expression )
     {
-        StringBuffer buffer = null;
-
-        if ( expression != null )
-        {
-            final Matcher matcher = OPERAND_PATTERN.matcher( expression );
-
-            buffer = new StringBuffer();
-
-            while ( matcher.find() )
+        if ( expression == null || expression.isEmpty() )
+        {
+            return null;
+        }
+
+        StringBuffer sb = new StringBuffer();
+        Matcher matcher = OPERAND_PATTERN.matcher( expression );
+
+        while ( matcher.find() )
+        {
+            if ( operandIsTotal( matcher ) )
             {
-                final DataElementOperand operand = DataElementOperand.getOperand( matcher.group() );
-                
-                if ( operand.isTotal() )
+                final StringBuilder replace = new StringBuilder( PAR_OPEN );
+
+                final DataElement dataElement = dataElementService.getDataElement( matcher.group( 1 ) );
+
+                final DataElementCategoryCombo categoryCombo = dataElement.getCategoryCombo();
+
+                for ( DataElementCategoryOptionCombo categoryOptionCombo : categoryCombo.getOptionCombos() )
                 {
-                    final StringBuilder replace = new StringBuilder( PAR_OPEN );
-
-                    final DataElement dataElement = dataElementService.getDataElement( operand.getDataElementId() );
-
-                    final DataElementCategoryCombo categoryCombo = dataElement.getCategoryCombo();
-
-                    for ( DataElementCategoryOptionCombo categoryOptionCombo : categoryCombo.getOptionCombos() )
-                    {
-                        replace.append( EXP_OPEN ).append( dataElement.getId() ).append( SEPARATOR ).append(
-                            categoryOptionCombo.getId() ).append( EXP_CLOSE ).append( "+" );
-                    }
-
-                    replace.deleteCharAt( replace.length() - 1 ).append( PAR_CLOSE );
-
-                    matcher.appendReplacement( buffer, replace.toString() );
+                    replace.append( EXP_OPEN ).append( dataElement.getUid() ).append( SEPARATOR ).append(
+                        categoryOptionCombo.getUid() ).append( EXP_CLOSE ).append( "+" );
                 }
+
+                replace.deleteCharAt( replace.length() - 1 ).append( PAR_CLOSE );
+                matcher.appendReplacement( sb, replace.toString() );
             }
-
-            matcher.appendTail( buffer );
         }
 
-        return buffer != null ? buffer.toString() : null;
+        return appendTail( matcher, sb );
     }
     
     public String substituteExpression( String expression, Integer days )
     {
-        StringBuffer buffer = null;
-        
-        if ( expression != null )
-        {
-            buffer = new StringBuffer();
-
-            final Matcher matcher = FORMULA_PATTERN.matcher( expression );
-            while ( matcher.find() )
-            {
-                String match = matcher.group();
-
-                if ( DAYS_EXPRESSION.equals( match ) ) // Days
-                {
-                    match = days != null ? String.valueOf( days ) : NULL_REPLACEMENT;
-                }
-                else if ( match.matches( CONSTANT_EXPRESSION ) ) // Constant
-                {
-                    final Constant constant = constantService.getConstant( Integer.parseInt( stripConstantExpression( match ) ) );
-                    
-                    match = constant != null ? String.valueOf( constant.getValue() ) : NULL_REPLACEMENT; 
-                }
-                
-                matcher.appendReplacement( buffer, match );
-            }
-
-            matcher.appendTail( buffer );
-        }
-
-        return buffer != null ? buffer.toString() : null;
+        if ( expression == null || expression.isEmpty() )
+        {
+            return null;
+        }
+
+        // ---------------------------------------------------------------------
+        // Constants
+        // ---------------------------------------------------------------------
+
+        StringBuffer sb = new StringBuffer();        
+        Matcher matcher = CONSTANT_PATTERN.matcher( expression );
+        
+        while ( matcher.find() )
+        {
+            String co = matcher.group( 1 );
+            
+            Constant constant = constantService.getConstant( co );
+            
+            String replacement = constant != null ? String.valueOf( constant.getValue() ) : NULL_REPLACEMENT; 
+            
+            matcher.appendReplacement( sb, replacement );
+        }
+
+        expression = appendTail( matcher, sb );
+        
+        // ---------------------------------------------------------------------
+        // Days
+        // ---------------------------------------------------------------------
+
+        sb = new StringBuffer();
+        matcher = DAYS_PATTERN.matcher( expression );
+        
+        while ( matcher.find() )
+        {            
+            String replacement = days != null ? String.valueOf( days ) : NULL_REPLACEMENT;
+            
+            matcher.appendReplacement( sb, replacement );
+        }
+        
+        return appendTail( matcher, sb );
     }
     
-    public String generateExpression( String expression, Map<DataElementOperand, Double> valueMap, Map<Integer, Double> constantMap, Integer days, boolean nullIfNoValues )
+    public String generateExpression( String expression, Map<DataElementOperand, Double> valueMap, Map<String, Double> constantMap, Integer days, boolean nullIfNoValues )
     {
-        StringBuffer buffer = null;
-
-        if ( expression != null )
-        {
-            final Matcher matcher = FORMULA_PATTERN.matcher( expression );
-
-            buffer = new StringBuffer();
-
-            while ( matcher.find() )
+        if ( expression == null || expression.isEmpty() )
+        {
+            return null;
+        }
+
+        // ---------------------------------------------------------------------
+        // Operands
+        // ---------------------------------------------------------------------
+        
+        StringBuffer sb = new StringBuffer();
+        Matcher matcher = OPERAND_PATTERN.matcher( expression );
+        
+        while ( matcher.find() )
+        {
+            DataElementOperand operand = DataElementOperand.getOperand( matcher.group() );
+
+            final Double value = valueMap.get( operand );
+            
+            if ( value == null && nullIfNoValues )
             {
-                String match = matcher.group();
-
-                if ( DAYS_EXPRESSION.equals( match ) ) // Days
-                {
-                    match = days != null ? String.valueOf( days ) : NULL_REPLACEMENT;
-                }
-                else if ( match.matches( CONSTANT_EXPRESSION ) ) // Constant
-                {
-                    final Double constant = constantMap.get( Integer.parseInt( stripConstantExpression( match ) ) );
-                    
-                    match = constant != null ? String.valueOf( constant ) : NULL_REPLACEMENT;
-                }
-                else // Operand
-                {
-                    final DataElementOperand operand = DataElementOperand.getOperand( match );
-
-                    final Double value = valueMap.get( operand );
-
-                    if ( value == null && nullIfNoValues )
-                    {
-                        return null;
-                    }
-
-                    match = value != null ? String.valueOf( value ) : NULL_REPLACEMENT;
-                }
-
-                matcher.appendReplacement( buffer, match );
+                return null;
             }
 
-            matcher.appendTail( buffer );
-        }
-
-        return buffer != null ? buffer.toString() : null;
+            String replacement = value != null ? String.valueOf( value ) : NULL_REPLACEMENT;
+            
+            matcher.appendReplacement( sb, replacement );
+        }
+        
+        expression = appendTail( matcher, sb );
+        
+        // ---------------------------------------------------------------------
+        // Constants
+        // ---------------------------------------------------------------------
+        
+        sb = new StringBuffer();
+        matcher = CONSTANT_PATTERN.matcher( expression );
+        
+        while ( matcher.find() )
+        {
+            final Double constant = constantMap.get( matcher.group( 1 ) );
+            
+            String replacement = constant != null ? String.valueOf( constant ) : NULL_REPLACEMENT;
+            
+            matcher.appendReplacement( sb, replacement );
+        }
+        
+        expression = appendTail( matcher, sb );
+        
+        // ---------------------------------------------------------------------
+        // Days
+        // ---------------------------------------------------------------------
+        
+        sb = new StringBuffer();
+        matcher = DAYS_PATTERN.matcher( expression );
+        
+        while ( matcher.find() )
+        {            
+            String replacement = days != null ? String.valueOf( days ) : NULL_REPLACEMENT;
+            
+            matcher.appendReplacement( sb, replacement );
+        }
+        
+        return appendTail( matcher, sb );
     }
 
     public Set<DataElementOperand> getOperandsInIndicators( Collection<Indicator> indicators )
@@ -624,9 +598,19 @@
         
         return operands;
     }
-    
-    private static final String stripConstantExpression( String match )
-    {
-        return match != null ? match.replaceAll( "[\\[C\\]]", "" ) : null;
+
+    // -------------------------------------------------------------------------
+    // Supportive methods
+    // -------------------------------------------------------------------------
+    
+    private String appendTail( Matcher matcher, StringBuffer sb )
+    {
+        matcher.appendTail( sb );
+        return sb.toString();
+    }
+    
+    private boolean operandIsTotal( Matcher matcher )
+    {
+        return matcher != null && StringUtils.trimToEmpty( matcher.group( 2 ) ).isEmpty();
     }
 }

=== added file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/startup/ExpressionUpgrader.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/startup/ExpressionUpgrader.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/startup/ExpressionUpgrader.java	2013-01-05 15:22:55 +0000
@@ -0,0 +1,288 @@
+package org.hisp.dhis.startup;
+
+import static org.hisp.dhis.dataentryform.DataEntryFormService.*;
+
+import java.util.Collection;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hisp.dhis.constant.Constant;
+import org.hisp.dhis.constant.ConstantService;
+import org.hisp.dhis.dataelement.DataElement;
+import org.hisp.dhis.dataelement.DataElementCategoryCombo;
+import org.hisp.dhis.dataelement.DataElementCategoryOptionCombo;
+import org.hisp.dhis.dataelement.DataElementCategoryService;
+import org.hisp.dhis.dataelement.DataElementService;
+import org.hisp.dhis.dataentryform.DataEntryForm;
+import org.hisp.dhis.dataentryform.DataEntryFormService;
+import org.hisp.dhis.expression.Expression;
+import org.hisp.dhis.expression.ExpressionService;
+import org.hisp.dhis.indicator.Indicator;
+import org.hisp.dhis.indicator.IndicatorService;
+import org.hisp.dhis.system.startup.AbstractStartupRoutine;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * Upgrades indicator formulas, expressions (for validation rules) and custom
+ * data entry forms from using identifiers to using uids.
+ * 
+ * @author Lars Helge Overland
+ */
+public class ExpressionUpgrader
+    extends AbstractStartupRoutine
+{
+    private static final String OLD_OPERAND_EXPRESSION = "\\[(\\d+)\\.?(\\d*)\\]";
+    private static final String OLD_CONSTANT_EXPRESSION = "\\[C(\\d+?)\\]";
+
+    private final Pattern OLD_OPERAND_PATTERN = Pattern.compile( OLD_OPERAND_EXPRESSION );
+    private final Pattern OLD_CONSTANT_PATTERN = Pattern.compile( OLD_CONSTANT_EXPRESSION );
+
+    private static final Log log = LogFactory.getLog( ExpressionUpgrader.class );
+    
+    @Autowired
+    private DataEntryFormService dataEntryFormService;
+    
+    @Autowired
+    private DataElementService dataElementService;
+    
+    @Autowired
+    private DataElementCategoryService categoryService;
+    
+    @Autowired
+    private IndicatorService indicatorService;
+    
+    @Autowired
+    private ConstantService constantService;
+    
+    @Autowired
+    private ExpressionService expressionService;
+    
+    @Override
+    public void execute()
+        throws Exception
+    {
+        upgradeIndicators();
+        upgradeExpressions();
+        upgradeDataEntryForms();
+    }
+    
+    private void upgradeIndicators()
+    {
+        Collection<Indicator> indicators = indicatorService.getAllIndicators();
+        
+        for ( Indicator indicator : indicators )
+        {
+            String numerator = upgradeExpression( indicator.getNumerator() );
+            String denominator = upgradeExpression( indicator.getDenominator() );
+            
+            if ( numerator != null || denominator != null )
+            {
+                indicator.setNumerator( numerator );
+                indicator.setDenominator( denominator );
+                indicatorService.updateIndicator( indicator );
+            }
+        }
+    }
+
+    private void upgradeExpressions()
+    {
+        Collection<Expression> expressions = expressionService.getAllExpressions();
+        
+        for ( Expression expression : expressions )
+        {
+            String expr = upgradeExpression( expression.getExpression() );
+            
+            if ( expr != null )
+            {
+                expression.setExpression( expr );
+                expressionService.updateExpression( expression );
+            }
+        }
+    }
+    
+    private String upgradeExpression( String expression )
+    {
+        if ( expression == null || expression.trim().isEmpty() )
+        {
+            return null;
+        }
+        
+        boolean changes = false;
+        
+        StringBuffer sb = new StringBuffer();
+
+        try
+        {
+            // -----------------------------------------------------------------
+            // Constants
+            // -----------------------------------------------------------------
+    
+            Matcher matcher = OLD_CONSTANT_PATTERN.matcher( expression );
+            
+            while ( matcher.find() )
+            {
+                Constant constant = constantService.getConstant( Integer.parseInt( matcher.group( 1 ) ) );
+                String replacement = "C{" + constant.getUid() + "}";
+                matcher.appendReplacement( sb, replacement );
+                changes = true;
+            }
+            
+            matcher.appendTail( sb );
+            expression = sb.toString();
+
+            // -----------------------------------------------------------------
+            // Operands
+            // -----------------------------------------------------------------
+    
+            matcher = OLD_OPERAND_PATTERN.matcher( expression );
+            sb = new StringBuffer();
+            
+            while ( matcher.find() )
+            {
+                DataElement de = dataElementService.getDataElement( Integer.parseInt( matcher.group( 1 ) ) );
+                String replacement = "#{" + de.getUid();
+                
+                if ( matcher.groupCount() == 2 && matcher.group( 2 ) != null && !matcher.group( 2 ).trim().isEmpty() )
+                {
+                    DataElementCategoryOptionCombo coc = categoryService.getDataElementCategoryOptionCombo( Integer.parseInt( matcher.group( 2 ) ) );
+                    replacement += "." + coc.getUid();
+                }
+                
+                replacement += "}";
+                matcher.appendReplacement( sb, replacement );                
+                changes = true;
+            }
+    
+            matcher.appendTail( sb );
+            expression = sb.toString();            
+        }
+        catch ( Exception ex )
+        {
+            log.error( "Failed to upgrade expression: " + expression );
+            log.error( ex ); // Log and continue
+        }
+        
+        if ( changes )
+        {
+            log.info( "Upgraded expression: " + expression );
+        }
+        
+        return changes ? expression : null;
+    }
+    
+    private void upgradeDataEntryForms()
+    {
+        Collection<DataEntryForm> forms = dataEntryFormService.getAllDataEntryForms();
+        
+        for ( DataEntryForm form : forms )
+        {
+            if ( DataEntryForm.CURRENT_FORMAT > form.getFormat() && form.getHtmlCode() != null && !form.getHtmlCode().trim().isEmpty() )
+            {
+                try
+                {
+                    // ---------------------------------------------------------
+                    // Identifiers
+                    // ---------------------------------------------------------
+
+                    Matcher matcher = IDENTIFIER_PATTERN.matcher( form.getHtmlCode() );
+                    StringBuffer sb = new StringBuffer();
+                    
+                    while ( matcher.find() )
+                    {
+                        DataElement de = dataElementService.getDataElement( Integer.parseInt( matcher.group( 1 ) ) );
+                        DataElementCategoryOptionCombo coc = categoryService.getDataElementCategoryOptionCombo( Integer.parseInt( matcher.group( 2 ) ) );                        
+                        String replacement = "id=\"" + de.getUid() + "-" + coc.getUid() + "-val\"";                        
+                        matcher.appendReplacement( sb, replacement );
+                    }
+                    
+                    matcher.appendTail( sb );                    
+                    form.setHtmlCode( sb.toString() );
+
+                    // ---------------------------------------------------------
+                    // Data element totals
+                    // ---------------------------------------------------------
+
+                    matcher = DATAELEMENT_TOTAL_PATTERN.matcher( form.getHtmlCode() );
+                    sb = new StringBuffer();
+                    
+                    while ( matcher.find() )
+                    {
+                        DataElement de = dataElementService.getDataElement( Integer.parseInt( matcher.group( 1 ) ) );
+                        String replacement = "dataelementid=\"" + de.getUid() + "\"";
+                        matcher.appendReplacement( sb, replacement );
+                    }
+
+                    matcher.appendTail( sb );                    
+                    form.setHtmlCode( sb.toString() );
+
+                    // ---------------------------------------------------------
+                    // Indicators
+                    // ---------------------------------------------------------
+
+                    matcher = INDICATOR_PATTERN.matcher( form.getHtmlCode() );
+                    sb = new StringBuffer();
+                    
+                    while ( matcher.find() )
+                    {
+                        Indicator in = indicatorService.getIndicator( Integer.parseInt( matcher.group( 1 ) ) );
+                        String replacement = "indicatorid=\"" + in.getUid() + "\"";
+                        matcher.appendReplacement( sb, replacement );
+                    }
+
+                    matcher.appendTail( sb );                    
+                    form.setHtmlCode( sb.toString() );
+
+                    // ---------------------------------------------------------
+                    // Dynamic input
+                    // ---------------------------------------------------------
+
+                    matcher = DYNAMIC_INPUT_PATTERN.matcher( form.getHtmlCode() );
+                    sb = new StringBuffer();
+                    
+                    while ( matcher.find() )
+                    {
+                        DataElementCategoryOptionCombo coc = categoryService.getDataElementCategoryOptionCombo( Integer.parseInt( matcher.group( 2 ) ) );
+                        String replacement = matcher.group( 1 ) + "-" + coc.getUid() + "-dyninput";
+                        matcher.appendReplacement( sb, replacement );
+                    }
+
+                    matcher.appendTail( sb );                    
+                    form.setHtmlCode( sb.toString() );
+
+                    // ---------------------------------------------------------
+                    // Dynamic select
+                    // ---------------------------------------------------------
+
+                    matcher = DYNAMIC_SELECT_PATTERN.matcher( form.getHtmlCode() );
+                    sb = new StringBuffer();
+                    
+                    while ( matcher.find() )
+                    {
+                        DataElementCategoryCombo cc = categoryService.getDataElementCategoryCombo( Integer.parseInt( matcher.group( 1 ) ) );
+                        String replacement = "dynselect=\"" + cc.getUid() + "\"";
+                        matcher.appendReplacement( sb, replacement );
+                    }
+
+                    matcher.appendTail( sb );                    
+                    form.setHtmlCode( sb.toString() );
+
+                    // ---------------------------------------------------------
+                    // Update format and save
+                    // ---------------------------------------------------------
+
+                    form.setFormat( DataEntryForm.CURRENT_FORMAT );                    
+                    dataEntryFormService.updateDataEntryForm( form );
+                    
+                    log.info( "Upgraded custom data entry form: " + form.getName() );
+                }
+                catch ( Exception ex )
+                {
+                    log.error( "Upgrading custom data entry form failed: " + form.getName() );
+                    log.error( ex ); // Log and continue
+                }
+            }
+        }
+    }
+}

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/validation/DefaultValidationRuleService.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/validation/DefaultValidationRuleService.java	2012-10-10 18:17:25 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/validation/DefaultValidationRuleService.java	2013-01-05 15:22:55 +0000
@@ -136,7 +136,7 @@
 
     public Collection<ValidationResult> validate( Date startDate, Date endDate, Collection<OrganisationUnit> sources )
     {
-        Map<Integer, Double> constantMap = constantService.getConstantMap();
+        Map<String, Double> constantMap = constantService.getConstantMap();
         
         Collection<ValidationResult> validationViolations = new HashSet<ValidationResult>();
 
@@ -145,14 +145,14 @@
         for ( OrganisationUnit source : sources )
         {
             Collection<ValidationRule> relevantRules = getRelevantValidationRules( source.getDataElementsInDataSets() );
-
+            
             Set<DataElement> dataElements = getDataElementsInValidationRules( relevantRules ); //TODO move outside loop?
-
+            
             if ( relevantRules != null && relevantRules.size() > 0 )
             {
                 for ( Period period : relevantPeriods )
                 {
-                    validationViolations.addAll( validateInternal( period, source, relevantRules, dataElements, constantMap, false,
+                    validationViolations.addAll( validateInternal( period, source, relevantRules, dataElements, constantMap, 
                         validationViolations.size() ) );
                 }
             }
@@ -164,7 +164,7 @@
     public Collection<ValidationResult> validate( Date startDate, Date endDate, Collection<OrganisationUnit> sources,
         ValidationRuleGroup group )
     {
-        Map<Integer, Double> constantMap = constantService.getConstantMap();
+        Map<String, Double> constantMap = constantService.getConstantMap();
         
         Collection<ValidationResult> validationViolations = new HashSet<ValidationResult>();
 
@@ -181,7 +181,7 @@
             {
                 for ( Period period : relevantPeriods )
                 {
-                    validationViolations.addAll( validateInternal( period, source, relevantRules, dataElements, constantMap, false,
+                    validationViolations.addAll( validateInternal( period, source, relevantRules, dataElements, constantMap, 
                         validationViolations.size() ) );
                 }
             }
@@ -192,7 +192,7 @@
 
     public Collection<ValidationResult> validate( Date startDate, Date endDate, OrganisationUnit source )
     {
-        Map<Integer, Double> constantMap = constantService.getConstantMap();
+        Map<String, Double> constantMap = constantService.getConstantMap();
         
         Collection<ValidationResult> validationViolations = new HashSet<ValidationResult>();
 
@@ -204,7 +204,7 @@
 
         for ( Period period : relevantPeriods )
         {
-            validationViolations.addAll( validateInternal( period, source, relevantRules, dataElements, constantMap, false, validationViolations
+            validationViolations.addAll( validateInternal( period, source, relevantRules, dataElements, constantMap, validationViolations
                 .size() ) );
         }
 
@@ -213,7 +213,7 @@
 
     public Collection<ValidationResult> validate( DataSet dataSet, Period period, OrganisationUnit source )
     {
-        Map<Integer, Double> constantMap = constantService.getConstantMap();
+        Map<String, Double> constantMap = constantService.getConstantMap();
         
         Collection<ValidationRule> relevantRules = null;
         
@@ -228,7 +228,7 @@
         
         Set<DataElement> dataElements = getDataElementsInValidationRules( relevantRules );
         
-        return validateInternal( period, source, relevantRules, dataElements, constantMap, false, 0 );
+        return validateInternal( period, source, relevantRules, dataElements, constantMap, 0 );
     }
 
     public Collection<DataElement> getDataElementsInValidationRules()
@@ -254,13 +254,16 @@
      * @param period the period to validate for.
      * @param source the source to validate for.
      * @param validationRules the rules to validate.
+     * @param dataElementsInRules the data elements which are part of the rules expressions.
+     * @param constantMap the constants which are part of the rule expressions.
+     * @param currentSize the current number of validation violations.
      * @returns a collection of rules that did not pass validation.
      */
     private Collection<ValidationResult> validateInternal( Period period, OrganisationUnit unit,
-        Collection<ValidationRule> validationRules, Set<DataElement> dataElementsInRules, Map<Integer, Double> constantMap, boolean aggregate, int currentSize )
+        Collection<ValidationRule> validationRules, Set<DataElement> dataElementsInRules, Map<String, Double> constantMap, int currentSize )
     {
         Map<DataElementOperand, Double> valueMap = dataValueService.getDataValueMap( dataElementsInRules, period, unit );
-        
+
         final Collection<ValidationResult> validationViolations = new HashSet<ValidationResult>();
 
         if ( currentSize < MAX_VIOLATIONS && !valueMap.isEmpty() )

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/resources/META-INF/dhis/beans.xml'
--- dhis-2/dhis-services/dhis-service-core/src/main/resources/META-INF/dhis/beans.xml	2013-01-03 12:43:44 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/resources/META-INF/dhis/beans.xml	2013-01-05 15:23:46 +0000
@@ -267,7 +267,7 @@
     <property name="cacheable" value="true" />
   </bean>
 
-  <bean id="org.hisp.dhis.constant.ConstantStore" class="org.hisp.dhis.hibernate.HibernateGenericStore">
+  <bean id="org.hisp.dhis.constant.ConstantStore" class="org.hisp.dhis.common.hibernate.HibernateIdentifiableObjectStore">
     <property name="sessionFactory" ref="sessionFactory" />
     <property name="clazz" value="org.hisp.dhis.constant.Constant" />
   </bean>
@@ -769,6 +769,11 @@
     <property name="skipInTests" value="true" />
   </bean>
 
+  <bean id="org.hisp.dhis.startup.ExpressionUpgrader" class="org.hisp.dhis.startup.ExpressionUpgrader">
+    <property name="runlevel" value="6" />
+    <property name="skipInTests" value="true" />
+  </bean>
+
   <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
     <property name="targetObject" ref="org.hisp.dhis.system.startup.StartupRoutineExecutor" />
     <property name="targetMethod" value="addStartupRoutines" />
@@ -783,6 +788,7 @@
           <ref local="org.hisp.dhis.dataelement.DataElementDefaultDimensionPopulator" />
           <ref local="org.hisp.dhis.organisationunit.OrganisationUnitGroupSetPopulator" />
           <ref local="org.hisp.dhis.dataentryform.DataEntryFormUpgrader" />
+          <ref local="org.hisp.dhis.startup.ExpressionUpgrader" />
         </list>
       </list>
     </property>

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/dataentryform/DataEntryFormServiceTest.java'
--- dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/dataentryform/DataEntryFormServiceTest.java	2012-11-20 17:04:08 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/dataentryform/DataEntryFormServiceTest.java	2013-01-04 18:10:25 +0000
@@ -65,9 +65,9 @@
     
     private I18n i18n;
     
-    private int dataElementId;
+    private String dataElementUid;
     
-    private int categoryOptionComboId;
+    private String categoryOptionComboUid;
 
     // -------------------------------------------------------------------------
     // Fixture
@@ -89,11 +89,12 @@
         
         dataElement = createDataElement( 'A' );
         
-        dataElementId = dataElementService.addDataElement( dataElement );
+        dataElementService.addDataElement( dataElement );
         
         categoryOptionCombo = categoryService.getDefaultDataElementCategoryOptionCombo();
         
-        categoryOptionComboId = categoryOptionCombo.getId();
+        dataElementUid = dataElement.getUid();
+        categoryOptionComboUid = categoryOptionCombo.getUid();
         
         i18n = new MockI18n();
     }
@@ -249,14 +250,14 @@
     @Test
     public void testGetOperands()
     {
-        String html = "<table><tr><td><input id=\"1434-11-val\" style=\"width:4em;text-align:center\" /></td></tr></table>";
+        String html = "<table><tr><td><input id=\"abc-def-val\" style=\"width:4em;text-align:center\" /></td></tr></table>";
         DataEntryForm dataEntryForm = new DataEntryForm( "FormA", html );
         DataSet dataSet = createDataSet( 'A', new MonthlyPeriodType() );
         dataSet.setDataEntryForm( dataEntryForm );
         
         Set<DataElementOperand> operands = dataEntryFormService.getOperandsInDataEntryForm( dataSet );
         
-        DataElementOperand operand = new DataElementOperand( 1434, 11 );
+        DataElementOperand operand = new DataElementOperand( "abc", "def" );
         
         assertEquals( 1, operands.size() );
         assertTrue( operands.contains( operand ) );
@@ -274,13 +275,13 @@
     
     @Test
     public void testPrepareForEdit()
-    {
-        String html = "<table><tr><td><input id=\"" + dataElementId + "-" + categoryOptionComboId + "-val\" style=\"width:4em;text-align:center\" title=\"\" value=\"\" /></td></tr></table>";
-        String title = "" + dataElementId + " - " + dataElement.getName() + " - " + categoryOptionComboId + " - " + categoryOptionCombo.getName() + " - " + dataElement.getType();
+    {        
+        String html = "<table><tr><td><input id=\"" + dataElementUid + "-" + categoryOptionComboUid + "-val\" style=\"width:4em;text-align:center\" title=\"\" value=\"\" /></td></tr></table>";
+        String title = "" + dataElementUid + " - " + dataElement.getName() + " - " + categoryOptionComboUid + " - " + categoryOptionCombo.getName() + " - " + dataElement.getType();
         String value = "[ " + dataElement.getName() + " " + categoryOptionCombo.getName() + " ]";
-        String expected = "<table><tr><td><input id=\"" + dataElementId + "-" + categoryOptionComboId + "-val\" style=\"width:4em;text-align:center\" title=\"" + title + "\" value=\"" + value + "\" /></td></tr></table>";
+        String expected = "<table><tr><td><input id=\"" + dataElementUid + "-" + categoryOptionComboUid + "-val\" style=\"width:4em;text-align:center\" title=\"" + title + "\" value=\"" + value + "\" /></td></tr></table>";
         String actual = dataEntryFormService.prepareDataEntryFormForEdit( html, i18n );
-        
+
         assertEquals( expected.length(), actual.length() );
     }
 }

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/expression/ExpressionServiceTest.java'
--- dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/expression/ExpressionServiceTest.java	2012-11-20 17:04:08 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/expression/ExpressionServiceTest.java	2013-01-04 18:10:25 +0000
@@ -32,7 +32,7 @@
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.hisp.dhis.expression.Expression.SEPARATOR;
-import static org.hisp.dhis.expression.ExpressionService.DAYS_EXPRESSION;
+import static org.hisp.dhis.expression.ExpressionService.*;
 
 import java.util.Collection;
 import java.util.HashMap;
@@ -59,7 +59,6 @@
 
 /**
  * @author Lars Helge Overland
- * @version $Id$
  */
 public class ExpressionServiceTest
     extends DhisTest
@@ -92,21 +91,9 @@
 
     private OrganisationUnit source;
 
-    private int dataElementIdA;
-
-    private int dataElementIdB;
-
-    private int dataElementIdC;
-
-    private int dataElementIdD;
-
-    private int dataElementIdE;
-
     private DataElementCategoryOptionCombo categoryOptionCombo;
-
-    private int categoryOptionComboId;
-
-    private int constantIdA;
+    
+    private Constant constantA;
 
     private String expressionA;
 
@@ -179,15 +166,15 @@
         dataElementD = createDataElement( 'D' );
         dataElementE = createDataElement( 'E', categoryCombo );
 
-        dataElementIdA = dataElementService.addDataElement( dataElementA );
-        dataElementIdB = dataElementService.addDataElement( dataElementB );
-        dataElementIdC = dataElementService.addDataElement( dataElementC );
-        dataElementIdD = dataElementService.addDataElement( dataElementD );
-        dataElementIdE = dataElementService.addDataElement( dataElementE );
+        dataElementService.addDataElement( dataElementA );
+        dataElementService.addDataElement( dataElementB );
+        dataElementService.addDataElement( dataElementC );
+        dataElementService.addDataElement( dataElementD );
+        dataElementService.addDataElement( dataElementE );
 
         categoryOptionCombo = categoryService.getDefaultDataElementCategoryOptionCombo();
 
-        categoryOptionComboId = categoryOptionCombo.getId();
+        categoryOptionCombo.getId();
         optionCombos.add( categoryOptionCombo );
 
         period = createPeriod( getDate( 2000, 1, 1 ), getDate( 2000, 2, 1 ) );
@@ -196,15 +183,17 @@
 
         organisationUnitService.addOrganisationUnit( source );
 
-        constantIdA = constantService.saveConstant( new Constant( "ConstantA", 2.0 ) );
-        
-        expressionA = "[" + dataElementIdA + SEPARATOR + categoryOptionComboId + "]+[" + dataElementIdB + SEPARATOR
-            + categoryOptionComboId + "]";
-        expressionB = "[" + dataElementIdC + SEPARATOR + categoryOptionComboId + "]-[" + dataElementIdD + SEPARATOR
-            + categoryOptionComboId + "]";
-        expressionC = "[" + dataElementIdA + SEPARATOR + categoryOptionComboId + "]+[" + dataElementIdE + "]-10";
-        expressionD = "[" + dataElementIdA + SEPARATOR + categoryOptionComboId + "]+" + DAYS_EXPRESSION;
-        expressionE = "[" + dataElementIdA + SEPARATOR + categoryOptionComboId + "]*[C" + constantIdA + "]";
+        constantA = new Constant( "ConstantA", 2.0 );
+        
+        constantService.saveConstant( constantA );
+        
+        expressionA = "#{" + dataElementA.getUid() + SEPARATOR + categoryOptionCombo.getUid() + "}+#{" + dataElementB.getUid() + SEPARATOR
+            + categoryOptionCombo.getUid() + "}";
+        expressionB = "#{" + dataElementC.getUid() + SEPARATOR + categoryOptionCombo.getUid() + "}-#{" + dataElementD.getUid() + SEPARATOR
+            + categoryOptionCombo.getUid() + "}";
+        expressionC = "#{" + dataElementA.getUid() + SEPARATOR + categoryOptionCombo.getUid() + "}+#{" + dataElementE.getUid() + "}-10";
+        expressionD = "#{" + dataElementA.getUid() + SEPARATOR + categoryOptionCombo.getUid() + "}+" + DAYS_SYMBOL;
+        expressionE = "#{" + dataElementA.getUid() + SEPARATOR + categoryOptionCombo.getUid() + "}*C{" + constantA.getUid() + "}";
 
         descriptionA = "Expression A";
         descriptionB = "Expression B";
@@ -238,11 +227,11 @@
 
         Set<DataElementCategoryOptionCombo> categoryOptionCombos = categoryCombo.getOptionCombos();
 
-        assertTrue( actual.contains( "[" + dataElementIdA + SEPARATOR + categoryOptionComboId + "]" ) );
+        assertTrue( actual.contains( "#{" + dataElementA.getUid() + SEPARATOR + categoryOptionCombo.getUid() + "}" ) );
 
         for ( DataElementCategoryOptionCombo categoryOptionCombo : categoryOptionCombos )
         {
-            assertTrue( actual.contains( "[" + dataElementIdE + SEPARATOR + categoryOptionCombo.getId() + "]" ) );
+            assertTrue( actual.contains( "#{" + dataElementE.getUid() + SEPARATOR + categoryOptionCombo.getUid() + "}" ) );
         }
     }
 
@@ -271,32 +260,14 @@
         assertNotNull( operands );
         assertEquals( 2, operands.size() );
 
-        DataElementOperand operandA = new DataElementOperand( dataElementIdA, categoryOptionComboId );
-        DataElementOperand operandB = new DataElementOperand( dataElementIdB, categoryOptionComboId );
+        DataElementOperand operandA = new DataElementOperand( dataElementA.getUid(), categoryOptionCombo.getUid() );
+        DataElementOperand operandB = new DataElementOperand( dataElementB.getUid(), categoryOptionCombo.getUid() );
 
         assertTrue( operands.contains( operandA ) );
         assertTrue( operands.contains( operandB ) );
     }
 
     @Test
-    public void testConvertExpression()
-    {
-        Map<Object, Integer> dataElementMapping = new HashMap<Object, Integer>();
-        dataElementMapping.put( 1, 4 );
-        dataElementMapping.put( 2, 5 );
-
-        Map<Object, Integer> categoryOptionComboMapping = new HashMap<Object, Integer>();
-        categoryOptionComboMapping.put( 1, 6 );
-        categoryOptionComboMapping.put( 2, 7 );
-
-        String expression = "[1.1]+2+[2.2]";
-        String expected = "[4.6]+2+[5.7]";
-
-        assertEquals( expected, expressionService.convertExpression( expression, dataElementMapping,
-            categoryOptionComboMapping ) );
-    }
-
-    @Test
     public void testExpressionIsValid()
     {
         assertEquals( ExpressionService.VALID, expressionService.expressionIsValid( expressionA ) );
@@ -305,20 +276,16 @@
         assertEquals( ExpressionService.VALID, expressionService.expressionIsValid( expressionD ) );
         assertEquals( ExpressionService.VALID, expressionService.expressionIsValid( expressionE ) );
 
-        expressionA = "[" + dataElementIdA + SEPARATOR + "foo" + "] + 12";
-
-        assertEquals( ExpressionService.ID_NOT_NUMERIC, expressionService.expressionIsValid( expressionA ) );
-
-        expressionA = "[" + 999 + SEPARATOR + categoryOptionComboId + "] + 12";
+        expressionA = "#{NonExistingUid" + SEPARATOR + categoryOptionCombo.getUid() + "} + 12";
 
         assertEquals( ExpressionService.DATAELEMENT_DOES_NOT_EXIST, expressionService.expressionIsValid( expressionA ) );
 
-        expressionA = "[" + dataElementIdA + SEPARATOR + 999 + "] + 12";
+        expressionA = "#{" + dataElementA.getUid() + SEPARATOR + 999 + "} + 12";
 
         assertEquals( ExpressionService.CATEGORYOPTIONCOMBO_DOES_NOT_EXIST, expressionService
             .expressionIsValid( expressionA ) );
 
-        expressionA = "[" + dataElementIdA + SEPARATOR + categoryOptionComboId + "] + ( 12";
+        expressionA = "#{" + dataElementA.getUid() + SEPARATOR + categoryOptionCombo.getUid() + "} + ( 12";
 
         assertEquals( ExpressionService.EXPRESSION_NOT_WELL_FORMED, expressionService.expressionIsValid( expressionA ) );
 
@@ -326,11 +293,7 @@
 
         assertEquals( ExpressionService.EXPRESSION_NOT_WELL_FORMED, expressionService.expressionIsValid( expressionA ) );
         
-        expressionA = "12 + [Cfoo]";
-
-        assertEquals( ExpressionService.ID_NOT_NUMERIC, expressionService.expressionIsValid( expressionA ) );
-
-        expressionA = "12 + [C999999]";
+        expressionA = "12 + C{999999}";
 
         assertEquals( ExpressionService.CONSTANT_DOES_NOT_EXIST, expressionService.expressionIsValid( expressionA ) );
     }
@@ -344,22 +307,22 @@
         
         description = expressionService.getExpressionDescription( expressionD );
         
-        assertEquals( description, "DataElementA+" + ExpressionService.DAYS_DESCRIPTION );
+        assertEquals( "DataElementA+" + ExpressionService.DAYS_DESCRIPTION, description );
 
         description = expressionService.getExpressionDescription( expressionE );
         
-        assertEquals( description, "DataElementA*ConstantA" );
+        assertEquals( "DataElementA*ConstantA", description );
     }
 
     @Test
     public void testGenerateExpressionMap()
     {
         Map<DataElementOperand, Double> valueMap = new HashMap<DataElementOperand, Double>();
-        valueMap.put( new DataElementOperand( dataElementIdA, categoryOptionComboId ), new Double( 12 ) );
-        valueMap.put( new DataElementOperand( dataElementIdB, categoryOptionComboId ), new Double( 34 ) );
+        valueMap.put( new DataElementOperand( dataElementA.getUid(), categoryOptionCombo.getUid() ), new Double( 12 ) );
+        valueMap.put( new DataElementOperand( dataElementB.getUid(), categoryOptionCombo.getUid() ), new Double( 34 ) );
         
-        Map<Integer, Double> constantMap = new HashMap<Integer, Double>();
-        constantMap.put( constantIdA, 2.0 );
+        Map<String, Double> constantMap = new HashMap<String, Double>();
+        constantMap.put( constantA.getUid(), 2.0 );
 
         assertEquals( "12.0+34.0", expressionService.generateExpression( expressionA, valueMap, constantMap, null, false ) );
         assertEquals( "12.0+5", expressionService.generateExpression( expressionD, valueMap, constantMap, 5, false ) );

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/validation/ValidationRuleServiceTest.java'
--- dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/validation/ValidationRuleServiceTest.java	2012-11-20 17:04:08 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/validation/ValidationRuleServiceTest.java	2013-01-04 18:10:25 +0000
@@ -77,14 +77,6 @@
 
     private DataElement dataElementD;
 
-    private int dataElementIdA;
-
-    private int dataElementIdB;
-
-    private int dataElementIdC;
-
-    private int dataElementIdD;
-
     private Set<DataElement> dataElementsA = new HashSet<DataElement>();
 
     private Set<DataElement> dataElementsB = new HashSet<DataElement>();
@@ -127,9 +119,9 @@
 
     private PeriodType periodType;
 
-    // ----------------------------------------------------------------------
+    // -------------------------------------------------------------------------
     // Fixture
-    // ----------------------------------------------------------------------
+    // -------------------------------------------------------------------------
 
     @Override
     public void setUpTest()
@@ -158,10 +150,10 @@
         dataElementC = createDataElement( 'C' );
         dataElementD = createDataElement( 'D' );
 
-        dataElementIdA = dataElementService.addDataElement( dataElementA );
-        dataElementIdB = dataElementService.addDataElement( dataElementB );
-        dataElementIdC = dataElementService.addDataElement( dataElementC );
-        dataElementIdD = dataElementService.addDataElement( dataElementD );
+        dataElementService.addDataElement( dataElementA );
+        dataElementService.addDataElement( dataElementB );
+        dataElementService.addDataElement( dataElementC );
+        dataElementService.addDataElement( dataElementD );
 
         dataElementsA.add( dataElementA );
         dataElementsA.add( dataElementB );
@@ -174,16 +166,16 @@
 
         categoryOptionCombo = categoryCombo.getOptionCombos().iterator().next();
 
-        String suffix = SEPARATOR + categoryOptionCombo.getId();
+        String suffix = SEPARATOR + categoryOptionCombo.getUid();
 
         optionCombos = new HashSet<DataElementCategoryOptionCombo>();
         optionCombos.add( categoryOptionCombo );
 
-        expressionA = new Expression( "[" + dataElementIdA + suffix + "] + [" + dataElementIdB + suffix + "]",
+        expressionA = new Expression( "#{" + dataElementA.getUid() + suffix + "} + #{" + dataElementB.getUid() + suffix + "}",
             "descriptionA", dataElementsA, optionCombos );
-        expressionB = new Expression( "[" + dataElementIdC + suffix + "] - [" + dataElementIdD + suffix + "]",
+        expressionB = new Expression( "#{" + dataElementC.getUid() + suffix + "} - #{" + dataElementD.getUid() + suffix + "}",
             "descriptionB", dataElementsB , optionCombos);
-        expressionC = new Expression( "[" + dataElementIdB + suffix + "] * 2", "descriptionC", dataElementsC, optionCombos);
+        expressionC = new Expression( "#{" + dataElementB.getUid() + suffix + "} * 2", "descriptionC", dataElementsC, optionCombos );
 
         expressionService.addExpression( expressionA );
         expressionService.addExpression( expressionB );
@@ -240,9 +232,9 @@
         return true;
     }
 
-    // ----------------------------------------------------------------------
+    // -------------------------------------------------------------------------
     // Business logic tests
-    // ----------------------------------------------------------------------
+    // -------------------------------------------------------------------------
 
     @Test
     public void testValidateDateDateSources()
@@ -293,7 +285,7 @@
                 .getOperator(), result.getRightsideValue() ) );
         }
 
-        assertEquals( results.size(), 8 );
+        assertEquals( 8, results.size() );
         assertEquals( reference, results );
     }
 
@@ -418,9 +410,9 @@
         assertEquals( reference, results );
     }
 
-    // ----------------------------------------------------------------------
+    // -------------------------------------------------------------------------
     // CURD functionality tests
-    // ----------------------------------------------------------------------
+    // -------------------------------------------------------------------------
 
     @Test
     public void testSaveValidationRule()

=== renamed file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/datamart/CrossTabDataValue.java' => 'dhis-2/dhis-services/dhis-service-datamart-default/src/main/java/org/hisp/dhis/datamart/CrossTabDataValue.java'
=== modified file 'dhis-2/dhis-services/dhis-service-datamart-default/src/main/java/org/hisp/dhis/datamart/DataMartManager.java'
--- dhis-2/dhis-services/dhis-service-datamart-default/src/main/java/org/hisp/dhis/datamart/DataMartManager.java	2012-11-08 08:33:41 +0000
+++ dhis-2/dhis-services/dhis-service-datamart-default/src/main/java/org/hisp/dhis/datamart/DataMartManager.java	2013-01-05 15:22:55 +0000
@@ -1,11 +1,41 @@
 package org.hisp.dhis.datamart;
 
+/*
+ * Copyright (c) 2004-2012, University of Oslo
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this
+ *   list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of the HISP project nor the names of its contributors may
+ *   be used to endorse or promote products derived from this software without
+ *   specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
 import java.util.Collection;
 import java.util.Map;
 import java.util.Set;
 
 import org.hisp.dhis.dataelement.DataElementOperand;
 
+/**
+ * @author Lars Helge Overland
+ */
 public interface DataMartManager
 {
     /**

=== modified file 'dhis-2/dhis-services/dhis-service-datamart-default/src/main/java/org/hisp/dhis/datamart/JdbcDataMartManager.java'
--- dhis-2/dhis-services/dhis-service-datamart-default/src/main/java/org/hisp/dhis/datamart/JdbcDataMartManager.java	2012-11-08 08:33:41 +0000
+++ dhis-2/dhis-services/dhis-service-datamart-default/src/main/java/org/hisp/dhis/datamart/JdbcDataMartManager.java	2013-01-05 15:22:55 +0000
@@ -84,9 +84,12 @@
         for ( DataElementOperand operand : operands )
         {
             final String sql = 
-                "SELECT COUNT(*) FROM datavalue " + 
-                "WHERE dataelementid=" + operand.getDataElementId() + " " +
-                "AND categoryoptioncomboid=" + operand.getOptionComboId();
+                "SELECT COUNT(*) " +
+                "FROM datavalue dv " +
+                "LEFT JOIN dataelement de ON dv.dataelementid = de.dataelementid " +
+                "LEFT JOIN categoryoptioncombo coc ON dv.categoryoptioncomboid = coc.categoryoptioncomboid " +
+                "WHERE de.uid = '" + operand.getDataElementId() + "' " +
+                "AND coc.uid = '" + operand.getOptionComboId()+ "'";
             
             Integer count = holder.queryForInteger( sql );
             
@@ -107,8 +110,10 @@
         try
         {
             final String sql =
-                "SELECT dataelementid, categoryoptioncomboid, value " +
-                "FROM datavalue " +
+                "SELECT de.uid, coc.uid, value " +
+                "FROM datavalue dv " +
+                "LEFT JOIN dataelement de ON dv.dataelementid = de.dataelementid " +
+                "LEFT JOIN categoryoptioncombo coc ON dv.categoryoptioncomboid = coc.categoryoptioncomboid " +
                 "WHERE periodid = " + periodId + " " +
                 "AND sourceid = " + sourceId;
             
@@ -118,7 +123,7 @@
             
             while ( resultSet.next() )
             {
-                final DataElementOperand operand = new DataElementOperand( resultSet.getInt( 1 ), resultSet.getInt( 2 ) );
+                final DataElementOperand operand = new DataElementOperand( resultSet.getString( 1 ), resultSet.getString( 2 ) );
                 
                 map.put( operand, resultSet.getString( 3 ) );
             }
@@ -270,6 +275,10 @@
     {
         executeSilently( "insert into aggregatedorgunitindicatorvalue select * from aggregatedorgunitindicatorvalue_temp" );
     }
+    
+    // -------------------------------------------------------------------------
+    // Supportive methods
+    // -------------------------------------------------------------------------
 
     private void executeSilently( String sql )
     {

=== modified file 'dhis-2/dhis-services/dhis-service-datamart-default/src/main/java/org/hisp/dhis/datamart/dataelement/DataElementDataMart.java'
--- dhis-2/dhis-services/dhis-service-datamart-default/src/main/java/org/hisp/dhis/datamart/dataelement/DataElementDataMart.java	2012-11-08 08:33:41 +0000
+++ dhis-2/dhis-services/dhis-service-datamart-default/src/main/java/org/hisp/dhis/datamart/dataelement/DataElementDataMart.java	2013-01-05 15:22:55 +0000
@@ -28,6 +28,7 @@
  */
 
 import java.util.Collection;
+import java.util.Map;
 import java.util.concurrent.Future;
 
 import org.amplecode.quick.BatchHandler;
@@ -46,5 +47,7 @@
 {
     Future<?> exportDataValues( Collection<DataElementOperand> operands, Collection<Period> periods, 
         Collection<OrganisationUnit> organisationUnits, Collection<OrganisationUnitGroup> organisationUnitGroups, 
-        DataElementOperandList operandList, OrganisationUnitHierarchy hierarchy, Class<? extends BatchHandler<AggregatedDataValue>> clazz, String key );
+        DataElementOperandList operandList, OrganisationUnitHierarchy hierarchy, 
+        Map<String, Integer> dataElementUidIdMap, Map<String, Integer> categoryOptionComboUidIdMap,
+        Class<? extends BatchHandler<AggregatedDataValue>> clazz, String key );
 }

=== modified file 'dhis-2/dhis-services/dhis-service-datamart-default/src/main/java/org/hisp/dhis/datamart/dataelement/DefaultDataElementDataMart.java'
--- dhis-2/dhis-services/dhis-service-datamart-default/src/main/java/org/hisp/dhis/datamart/dataelement/DefaultDataElementDataMart.java	2012-11-08 08:33:41 +0000
+++ dhis-2/dhis-services/dhis-service-datamart-default/src/main/java/org/hisp/dhis/datamart/dataelement/DefaultDataElementDataMart.java	2013-01-05 15:22:55 +0000
@@ -140,7 +140,9 @@
     @Async
     public Future<?> exportDataValues( Collection<DataElementOperand> operands, Collection<Period> periods, 
         Collection<OrganisationUnit> organisationUnits, Collection<OrganisationUnitGroup> organisationUnitGroups, 
-        DataElementOperandList operandList, OrganisationUnitHierarchy hierarchy, Class<? extends BatchHandler<AggregatedDataValue>> clazz, String key )
+        DataElementOperandList operandList, OrganisationUnitHierarchy hierarchy, 
+        Map<String, Integer> dataElementUidIdMap, Map<String, Integer> categoryOptionComboUidIdMap,
+        Class<? extends BatchHandler<AggregatedDataValue>> clazz, String key )
     {
         statementManager.initialise(); // Running in separate thread
         
@@ -189,8 +191,8 @@
                             
                             final double value = getRounded( entry.getValue(), DECIMALS );
                             
-                            aggregatedValue.setDataElementId( entry.getKey().getDataElementId() );
-                            aggregatedValue.setCategoryOptionComboId( entry.getKey().getOptionComboId() );
+                            aggregatedValue.setDataElementId( dataElementUidIdMap.get( entry.getKey().getDataElementId() ) );
+                            aggregatedValue.setCategoryOptionComboId( categoryOptionComboUidIdMap.get( entry.getKey().getOptionComboId() ) );
                             aggregatedValue.setPeriodId( period.getId() );
                             aggregatedValue.setPeriodTypeId( period.getPeriodType().getId() );
                             aggregatedValue.setOrganisationUnitId( unit.getId() );

=== modified file 'dhis-2/dhis-services/dhis-service-datamart-default/src/main/java/org/hisp/dhis/datamart/engine/DefaultDataMartEngine.java'
--- dhis-2/dhis-services/dhis-service-datamart-default/src/main/java/org/hisp/dhis/datamart/engine/DefaultDataMartEngine.java	2012-11-08 08:33:41 +0000
+++ dhis-2/dhis-services/dhis-service-datamart-default/src/main/java/org/hisp/dhis/datamart/engine/DefaultDataMartEngine.java	2013-01-05 15:22:55 +0000
@@ -37,6 +37,7 @@
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.Future;
 
@@ -231,6 +232,9 @@
         final Collection<OrganisationUnitGroup> organisationUnitGroups = organisationUnitGroupService.getOrganisationUnitGroups( organisationUnitGroupIds );
         final Collection<DataElement> dataElements = dataElementService.getDataElements( dataElementIds );
 
+        final Map<String, Integer> dataElementUidIdMap = dataElementService.getDataElementUidIdMap();
+        final Map<String, Integer> categoryOptionComboUidIdMap = categoryService.getDataElementCategoryOptionComboUidIdMap();
+        
         clock.logTime( "Retrieved meta-data objects" );
         notifier.notify( id, DATAMART, "Filtering meta-data" );
 
@@ -342,7 +346,8 @@
             for ( List<OrganisationUnit> organisationUnitPage : organisationUnitPages )
             {
                 futures.add( dataElementDataMart.exportDataValues( allOperands, periods, organisationUnitPage, 
-                    null, new DataElementOperandList( indicatorOperands ), hierarchy, AggregatedDataValueTempBatchHandler.class, key ) );
+                    null, new DataElementOperandList( indicatorOperands ), hierarchy,
+                    dataElementUidIdMap, categoryOptionComboUidIdMap, AggregatedDataValueTempBatchHandler.class, key ) );
             }
 
             ConcurrentUtils.waitForCompletion( futures );
@@ -478,7 +483,8 @@
                 for ( List<OrganisationUnit> organisationUnitPage : organisationUnitPages )
                 {
                     futures.add( dataElementDataMart.exportDataValues( allOperands, periods, organisationUnitPage, 
-                        organisationUnitGroups, new DataElementOperandList( indicatorOperands ), hierarchy, AggregatedOrgUnitDataValueTempBatchHandler.class, key ) );
+                        organisationUnitGroups, new DataElementOperandList( indicatorOperands ), hierarchy, 
+                        dataElementUidIdMap, categoryOptionComboUidIdMap, AggregatedOrgUnitDataValueTempBatchHandler.class, key ) );
                 }
 
                 ConcurrentUtils.waitForCompletion( futures );

=== modified file 'dhis-2/dhis-services/dhis-service-datamart-default/src/main/java/org/hisp/dhis/datamart/indicator/DefaultIndicatorDataMart.java'
--- dhis-2/dhis-services/dhis-service-datamart-default/src/main/java/org/hisp/dhis/datamart/indicator/DefaultIndicatorDataMart.java	2012-11-08 08:33:41 +0000
+++ dhis-2/dhis-services/dhis-service-datamart-default/src/main/java/org/hisp/dhis/datamart/indicator/DefaultIndicatorDataMart.java	2013-01-04 18:10:25 +0000
@@ -141,7 +141,7 @@
         
         final AggregatedIndicatorValue indicatorValue = new AggregatedIndicatorValue();
         
-        final Map<Integer, Double> constantMap = constantService.getConstantMap();
+        final Map<String, Double> constantMap = constantService.getConstantMap();
 
         organisationUnitGroups = organisationUnitGroups != null ? organisationUnitGroups : DataMartEngine.DUMMY_ORG_UNIT_GROUPS;
         

=== modified file 'dhis-2/dhis-services/dhis-service-datamart-default/src/test/java/org/hisp/dhis/datamart/DataMartServiceOrgUnitTest.java'
--- dhis-2/dhis-services/dhis-service-datamart-default/src/test/java/org/hisp/dhis/datamart/DataMartServiceOrgUnitTest.java	2012-12-21 12:59:39 +0000
+++ dhis-2/dhis-services/dhis-service-datamart-default/src/test/java/org/hisp/dhis/datamart/DataMartServiceOrgUnitTest.java	2013-01-05 15:22:55 +0000
@@ -443,10 +443,10 @@
         DataElement dataElementE = createDataElement( 'E', DataElement.VALUE_TYPE_INT, DataElement.AGGREGATION_OPERATOR_AVERAGE, categoryCombo );
         DataElement dataElementF = createDataElement( 'F', DataElement.VALUE_TYPE_INT, DataElement.AGGREGATION_OPERATOR_AVERAGE, categoryCombo );
         
-        int idC = dataElementService.addDataElement( dataElementC );
-        int idD = dataElementService.addDataElement( dataElementD );
-        int idE = dataElementService.addDataElement( dataElementE );
-        int idF = dataElementService.addDataElement( dataElementF );
+        dataElementService.addDataElement( dataElementC );
+        dataElementService.addDataElement( dataElementD );
+        dataElementService.addDataElement( dataElementE );
+        dataElementService.addDataElement( dataElementF );
 
         dataSet.getDataElements().add( dataElementC );
         dataSet.getDataElements().add( dataElementD );
@@ -504,11 +504,11 @@
         
         Indicator indicatorA = createIndicator( 'A', indicatorType );
         
-        String suffix = "." + categoryOptionCombo.getId();
-        
-        indicatorA.setNumerator( "[" + idC + suffix + "]*[" + idD + suffix + "]" );
-        
-        indicatorA.setDenominator( "[" + idE + suffix + "]+[" + idF + suffix + "]" );
+        String suffix = "." + categoryOptionCombo.getUid();
+        
+        indicatorA.setNumerator( "#{" + dataElementC.getUid() + suffix + "}*#{" + dataElementD.getUid() + suffix + "}" );
+        
+        indicatorA.setDenominator( "#{" + dataElementE.getUid() + suffix + "}+#{" + dataElementF.getUid() + suffix + "}" );
         
         indicatorIds.add( indicatorService.addIndicator( indicatorA ) );
 

=== modified file 'dhis-2/dhis-services/dhis-service-datamart-default/src/test/java/org/hisp/dhis/datamart/DataMartServiceTest.java'
--- dhis-2/dhis-services/dhis-service-datamart-default/src/test/java/org/hisp/dhis/datamart/DataMartServiceTest.java	2012-12-21 12:59:39 +0000
+++ dhis-2/dhis-services/dhis-service-datamart-default/src/test/java/org/hisp/dhis/datamart/DataMartServiceTest.java	2013-01-05 15:22:55 +0000
@@ -384,10 +384,10 @@
         DataElement dataElementE = createDataElement( 'E', DataElement.VALUE_TYPE_INT, DataElement.AGGREGATION_OPERATOR_AVERAGE, categoryCombo );
         DataElement dataElementF = createDataElement( 'F', DataElement.VALUE_TYPE_INT, DataElement.AGGREGATION_OPERATOR_AVERAGE, categoryCombo );
         
-        int idC = dataElementService.addDataElement( dataElementC );
-        int idD = dataElementService.addDataElement( dataElementD );
-        int idE = dataElementService.addDataElement( dataElementE );
-        int idF = dataElementService.addDataElement( dataElementF );
+        dataElementService.addDataElement( dataElementC );
+        dataElementService.addDataElement( dataElementD );
+        dataElementService.addDataElement( dataElementE );
+        dataElementService.addDataElement( dataElementF );
 
         dataSet.getDataElements().add( dataElementC );
         dataSet.getDataElements().add( dataElementD );
@@ -457,11 +457,11 @@
         
         Indicator indicatorA = createIndicator( 'A', indicatorType );
         
-        String suffix = "." + categoryOptionCombo.getId();
-        
-        indicatorA.setNumerator( "[" + idC + suffix + "]*[" + idD + suffix + "]" );
-        
-        indicatorA.setDenominator( "[" + idE + suffix + "]+[" + idF + suffix + "]" );
+        String suffix = "." + categoryOptionCombo.getUid();
+        
+        indicatorA.setNumerator( "#{" + dataElementC.getUid() + suffix + "}*#{" + dataElementD.getUid() + suffix + "}" );
+        
+        indicatorA.setDenominator( "#{" + dataElementE.getUid() + suffix + "}+#{" + dataElementF.getUid() + suffix + "}" );
         
         indicatorIds.add( indicatorService.addIndicator( indicatorA ) );
         
@@ -492,10 +492,10 @@
         DataElement dataElementE = createDataElement( 'E', DataElement.VALUE_TYPE_INT, DataElement.AGGREGATION_OPERATOR_AVERAGE, categoryCombo );
         DataElement dataElementF = createDataElement( 'F', DataElement.VALUE_TYPE_INT, DataElement.AGGREGATION_OPERATOR_AVERAGE, categoryCombo );
         
-        int idC = dataElementService.addDataElement( dataElementC );
-        int idD = dataElementService.addDataElement( dataElementD );
-        int idE = dataElementService.addDataElement( dataElementE );
-        int idF = dataElementService.addDataElement( dataElementF );
+        dataElementService.addDataElement( dataElementC );
+        dataElementService.addDataElement( dataElementD );
+        dataElementService.addDataElement( dataElementE );
+        dataElementService.addDataElement( dataElementF );
 
         dataSet.getDataElements().add( dataElementC );
         dataSet.getDataElements().add( dataElementD );
@@ -543,11 +543,11 @@
         
         indicatorA.setAnnualized( true );
         
-        String suffix = Expression.SEPARATOR + categoryOptionCombo.getId();
-        
-        indicatorA.setNumerator( "[" + idC + suffix + "]*[" + idD + suffix + "]" );
-        
-        indicatorA.setDenominator( "[" + idE + suffix + "]+[" + idF + suffix + "]" );
+        String suffix = Expression.SEPARATOR + categoryOptionCombo.getUid();
+        
+        indicatorA.setNumerator( "#{" + dataElementC.getUid() + suffix + "}*#{" + dataElementD.getUid() + suffix + "}" );
+        
+        indicatorA.setDenominator( "#{" + dataElementE.getUid() + suffix + "}+#{" + dataElementF.getUid() + suffix + "}" );
         
         indicatorIds.add( indicatorService.addIndicator( indicatorA ) );
         

=== modified file 'dhis-2/dhis-services/dhis-service-datamart-default/src/test/java/org/hisp/dhis/datamart/crosstab/CrossTabStoreTest.java'
--- dhis-2/dhis-services/dhis-service-datamart-default/src/test/java/org/hisp/dhis/datamart/crosstab/CrossTabStoreTest.java	2012-11-08 08:33:41 +0000
+++ dhis-2/dhis-services/dhis-service-datamart-default/src/test/java/org/hisp/dhis/datamart/crosstab/CrossTabStoreTest.java	2013-01-05 15:22:55 +0000
@@ -28,10 +28,10 @@
         crossTabStore = (CrossTabStore) getBean( CrossTabStore.ID );
         
         operands = new ArrayList<DataElementOperand>();
-        operands.add( new DataElementOperand( 1, 1 ) );
-        operands.add( new DataElementOperand( 1, 2 ) );
-        operands.add( new DataElementOperand( 2, 1 ) );
-        operands.add( new DataElementOperand( 2, 2 ) );        
+        operands.add( new DataElementOperand( "a", "a" ) );
+        operands.add( new DataElementOperand( "a", "b" ) );
+        operands.add( new DataElementOperand( "b", "a" ) );
+        operands.add( new DataElementOperand( "b", "b" ) );        
     }
 
     @Override

=== modified file 'dhis-2/dhis-services/dhis-service-importexport/src/main/java/org/hisp/dhis/importexport/DefaultImportService.java'
--- dhis-2/dhis-services/dhis-service-importexport/src/main/java/org/hisp/dhis/importexport/DefaultImportService.java	2012-03-28 16:04:53 +0000
+++ dhis-2/dhis-services/dhis-service-importexport/src/main/java/org/hisp/dhis/importexport/DefaultImportService.java	2013-01-04 18:10:25 +0000
@@ -64,6 +64,7 @@
 
     static public final String DXF1URI = "http://dhis2.org/schema/dxf/1.0";;
     static public final String DXF2URI = "http://dhis2.org/schema/dxf/2.0";;
+    
     // -------------------------------------------------------------------------
     // Dependencies
     // -------------------------------------------------------------------------

=== modified file 'dhis-2/dhis-services/dhis-service-importexport/src/main/java/org/hisp/dhis/importexport/analysis/IndicatorFormulaIdentifier.java'
--- dhis-2/dhis-services/dhis-service-importexport/src/main/java/org/hisp/dhis/importexport/analysis/IndicatorFormulaIdentifier.java	2011-12-26 10:07:59 +0000
+++ dhis-2/dhis-services/dhis-service-importexport/src/main/java/org/hisp/dhis/importexport/analysis/IndicatorFormulaIdentifier.java	2013-01-04 18:10:25 +0000
@@ -40,9 +40,9 @@
     
     private String formula;
     
-    private Integer identifier;
+    private String identifier;
     
-    public IndicatorFormulaIdentifier( String indicator, String formula, Integer identifier )
+    public IndicatorFormulaIdentifier( String indicator, String formula, String identifier )
     {
         this.indicator = indicator;
         this.formula = formula;
@@ -69,12 +69,12 @@
         this.formula = formula;
     }
 
-    public Integer getIdentifier()
+    public String getIdentifier()
     {
         return identifier;
     }
 
-    public void setIdentifier( Integer identifier )
+    public void setIdentifier( String identifier )
     {
         this.identifier = identifier;
     }

=== modified file 'dhis-2/dhis-services/dhis-service-importexport/src/main/java/org/hisp/dhis/importexport/dxf/converter/DXFConverter.java'
--- dhis-2/dhis-services/dhis-service-importexport/src/main/java/org/hisp/dhis/importexport/dxf/converter/DXFConverter.java	2012-02-01 14:18:43 +0000
+++ dhis-2/dhis-services/dhis-service-importexport/src/main/java/org/hisp/dhis/importexport/dxf/converter/DXFConverter.java	2013-01-05 15:22:55 +0000
@@ -27,6 +27,10 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+import static org.apache.commons.lang.StringUtils.defaultIfEmpty;
+
+import javax.xml.namespace.QName;
+
 import org.amplecode.quick.BatchHandler;
 import org.amplecode.quick.BatchHandlerFactory;
 import org.amplecode.staxwax.reader.XMLReader;
@@ -118,10 +122,6 @@
 import org.hisp.dhis.reporttable.ReportTableService;
 import org.hisp.dhis.validation.ValidationRuleService;
 
-import javax.xml.namespace.QName;
-
-import static org.apache.commons.lang.StringUtils.defaultIfEmpty;
-
 /**
  * DXFConverter class This does NOT implement XMLConverter, because we need to
  * pass ProcessState in read() method.
@@ -591,9 +591,8 @@
                     IndicatorBatchHandler.class ).init();
 
                 XMLConverter converter = new IndicatorConverter( batchHandler, importObjectService, indicatorService,
-                    expressionService, objectMappingGenerator.getIndicatorTypeMapping( params.skipMapping() ),
-                    objectMappingGenerator.getDataElementMapping( params.skipMapping() ), objectMappingGenerator
-                        .getCategoryOptionComboMapping( params.skipMapping() ), importAnalyser );
+                    objectMappingGenerator.getIndicatorTypeMapping( params.skipMapping() ),
+                    importAnalyser );
 
                 converterInvoker.invokeRead( converter, reader, params );
 
@@ -916,9 +915,7 @@
 
                 state.setMessage( "importing_validation_rules" );
 
-                XMLConverter converter = new ValidationRuleConverter( importObjectService, validationRuleService,
-                    expressionService, objectMappingGenerator.getDataElementMapping( params.skipMapping() ),
-                    objectMappingGenerator.getCategoryOptionComboMapping( params.skipMapping() ) );
+                XMLConverter converter = new ValidationRuleConverter( importObjectService, validationRuleService, expressionService );
 
                 converterInvoker.invokeRead( converter, reader, params );
 

=== modified file 'dhis-2/dhis-services/dhis-service-importexport/src/main/java/org/hisp/dhis/importexport/dxf/converter/IndicatorConverter.java'
--- dhis-2/dhis-services/dhis-service-importexport/src/main/java/org/hisp/dhis/importexport/dxf/converter/IndicatorConverter.java	2012-10-18 13:04:28 +0000
+++ dhis-2/dhis-services/dhis-service-importexport/src/main/java/org/hisp/dhis/importexport/dxf/converter/IndicatorConverter.java	2013-01-04 18:10:25 +0000
@@ -33,7 +33,6 @@
 import org.amplecode.quick.BatchHandler;
 import org.amplecode.staxwax.reader.XMLReader;
 import org.amplecode.staxwax.writer.XMLWriter;
-import org.hisp.dhis.expression.ExpressionService;
 import org.hisp.dhis.importexport.ExportParams;
 import org.hisp.dhis.importexport.ImportObjectService;
 import org.hisp.dhis.importexport.ImportParams;
@@ -72,15 +71,9 @@
     // -------------------------------------------------------------------------
     // Properties
     // -------------------------------------------------------------------------
-
-    private ExpressionService expressionService;
     
     private Map<Object, Integer> indicatorTypeMapping;
     
-    private Map<Object, Integer> dataElementMapping;
-    
-    private Map<Object, Integer> categoryOptionComboMapping;
-    
     // -------------------------------------------------------------------------
     // Constructor
     // -------------------------------------------------------------------------
@@ -99,27 +92,18 @@
      * @param batchHandler the batchHandler to use.
      * @param importObjectService the importObjectService to use.
      * @param indicatorService the indicatorService to use.
-     * @param expressionService the expressionService to use.
-     * @param indicatorTypeMapping the indicatorTypeMapping to use.
-     * @param dataElementMapping the dataElementMapping to use.
      * @param categoryOptionComboMapping the categoryOptionComboMapping to use.
      */
     public IndicatorConverter( BatchHandler<Indicator> batchHandler, 
         ImportObjectService importObjectService, 
         IndicatorService indicatorService,
-        ExpressionService expressionService,
         Map<Object, Integer> indicatorTypeMapping, 
-        Map<Object, Integer> dataElementMapping,
-        Map<Object, Integer> categoryOptionComboMapping,
         ImportAnalyser importAnalyser )
     {
         this.batchHandler = batchHandler;
         this.importObjectService = importObjectService;
         this.indicatorService = indicatorService;
-        this.expressionService = expressionService;
         this.indicatorTypeMapping = indicatorTypeMapping;
-        this.dataElementMapping = dataElementMapping;
-        this.categoryOptionComboMapping = categoryOptionComboMapping;
         this.importAnalyser = importAnalyser;
     }    
 
@@ -188,9 +172,9 @@
             indicator.setDescription( values.get( FIELD_DESCRIPTION ) );
             indicator.setAnnualized( Boolean.parseBoolean( values.get( FIELD_ANNUALIZED ) ) );
             indicator.getIndicatorType().setId( indicatorTypeMapping.get( Integer.parseInt( values.get( FIELD_INDICATOR_TYPE ) ) ) );
-            indicator.setNumerator( expressionService.convertExpression( values.get( FIELD_NUMERATOR ), dataElementMapping, categoryOptionComboMapping ) );
+            indicator.setNumerator( values.get( FIELD_NUMERATOR ) );
             indicator.setNumeratorDescription( values.get( FIELD_NUMERATOR_DESCRIPTION ) );
-            indicator.setDenominator( expressionService.convertExpression( values.get( FIELD_DENOMINATOR ), dataElementMapping, categoryOptionComboMapping ) );
+            indicator.setDenominator( values.get( FIELD_DENOMINATOR ) );
             indicator.setDenominatorDescription( values.get( FIELD_DENOMINATOR_DESCRIPTION ) );
             indicator.setLastUpdated( DateUtils.getMediumDate( values.get( FIELD_LAST_UPDATED ) ) );            
             

=== modified file 'dhis-2/dhis-services/dhis-service-importexport/src/main/java/org/hisp/dhis/importexport/dxf/converter/ValidationRuleConverter.java'
--- dhis-2/dhis-services/dhis-service-importexport/src/main/java/org/hisp/dhis/importexport/dxf/converter/ValidationRuleConverter.java	2011-12-26 10:07:59 +0000
+++ dhis-2/dhis-services/dhis-service-importexport/src/main/java/org/hisp/dhis/importexport/dxf/converter/ValidationRuleConverter.java	2013-01-05 15:22:55 +0000
@@ -70,14 +70,6 @@
     private static final String FIELD_RIGHTSIDE_DESCRIPTION = "rightSideDescription";
 
     // -------------------------------------------------------------------------
-    // Properties
-    // -------------------------------------------------------------------------
-
-    private Map<Object, Integer> dataElementMapping;
-
-    private Map<Object, Integer> categoryOptionComboMapping;
-
-    // -------------------------------------------------------------------------
     // Constructor
     // -------------------------------------------------------------------------
 
@@ -107,14 +99,11 @@
      * @param dataElementMapping the data element mapping to use.
      */
     public ValidationRuleConverter( ImportObjectService importObjectService,
-        ValidationRuleService validationRuleService, ExpressionService expressionService,
-        Map<Object, Integer> dataElementMapping, Map<Object, Integer> categoryOptionComboMapping )
+        ValidationRuleService validationRuleService, ExpressionService expressionService )
     {
         this.importObjectService = importObjectService;
         this.validationRuleService = validationRuleService;
         this.expressionService = expressionService;
-        this.dataElementMapping = dataElementMapping;
-        this.categoryOptionComboMapping = categoryOptionComboMapping;
     }
 
     // -------------------------------------------------------------------------
@@ -180,18 +169,18 @@
             validationRule.setType( values.get( FIELD_TYPE ) );
             validationRule.setOperator( Operator.valueOf( values.get( FIELD_OPERATOR ) ) );
 
-            validationRule.getLeftSide().setExpression(
-                expressionService.convertExpression( values.get( FIELD_LEFTSIDE_EXPRESSION ), dataElementMapping,
-                    categoryOptionComboMapping ) );
+            validationRule.getLeftSide().setExpression( values.get( FIELD_LEFTSIDE_EXPRESSION ) );
             validationRule.getLeftSide().setDescription( values.get( FIELD_LEFTSIDE_DESCRIPTION ) );
+            System.out.println("exp " + expressionService );
+            System.out.println("val " + validationRule.getLeftSide() );
+            System.out.println("exp " + validationRule.getLeftSide().getExpression());
+            
             validationRule.getLeftSide().setDataElementsInExpression(
                 expressionService.getDataElementsInExpression( validationRule.getLeftSide().getExpression() ) );
             validationRule.getLeftSide().setOptionCombosInExpression(
                 expressionService.getOptionCombosInExpression( validationRule.getLeftSide().getExpression() ) );
 
-            validationRule.getRightSide().setExpression(
-                expressionService.convertExpression( values.get( FIELD_RIGHTSIDE_EXPRESSION ), dataElementMapping,
-                    categoryOptionComboMapping ) );
+            validationRule.getRightSide().setExpression( values.get( FIELD_RIGHTSIDE_EXPRESSION ) );
             validationRule.getRightSide().setDescription( values.get( FIELD_RIGHTSIDE_DESCRIPTION ) );
             validationRule.getRightSide().setDataElementsInExpression(
                 expressionService.getDataElementsInExpression( validationRule.getRightSide().getExpression() ) );

=== modified file 'dhis-2/dhis-services/dhis-service-importexport/src/main/java/org/hisp/dhis/importexport/service/DefaultImportObjectManager.java'
--- dhis-2/dhis-services/dhis-service-importexport/src/main/java/org/hisp/dhis/importexport/service/DefaultImportObjectManager.java	2012-10-02 18:18:48 +0000
+++ dhis-2/dhis-services/dhis-service-importexport/src/main/java/org/hisp/dhis/importexport/service/DefaultImportObjectManager.java	2013-01-04 18:10:25 +0000
@@ -593,8 +593,6 @@
             .init();
 
         Map<Object, Integer> indicatorTypeMapping = objectMappingGenerator.getIndicatorTypeMapping( false );
-        Map<Object, Integer> dataElementMapping = objectMappingGenerator.getDataElementMapping( false );
-        Map<Object, Integer> categoryOptionComboMapping = objectMappingGenerator.getCategoryOptionComboMapping( false );
 
         Collection<ImportObject> importObjects = importObjectStore.getImportObjects( Indicator.class );
 
@@ -604,10 +602,6 @@
         {
             Indicator object = (Indicator) importObject.getObject();
             object.getIndicatorType().setId( indicatorTypeMapping.get( object.getIndicatorType().getId() ) );
-            object.setNumerator( expressionService.convertExpression( object.getNumerator(), dataElementMapping,
-                categoryOptionComboMapping ) );
-            object.setDenominator( expressionService.convertExpression( object.getDenominator(), dataElementMapping,
-                categoryOptionComboMapping ) );
             importer.importObject( object, params );
         }
 

=== modified file 'dhis-2/dhis-services/dhis-service-importexport/src/test/java/org/hisp/dhis/importexport/analysis/ImportAnalyserTest.java'
--- dhis-2/dhis-services/dhis-service-importexport/src/test/java/org/hisp/dhis/importexport/analysis/ImportAnalyserTest.java	2012-11-20 17:04:08 +0000
+++ dhis-2/dhis-services/dhis-service-importexport/src/test/java/org/hisp/dhis/importexport/analysis/ImportAnalyserTest.java	2013-01-04 18:10:25 +0000
@@ -30,8 +30,6 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
-import static org.hisp.dhis.importexport.analysis.IndicatorFormulaIdentifier.DENOMINATOR;
-import static org.hisp.dhis.importexport.analysis.IndicatorFormulaIdentifier.NUMERATOR;
 
 import java.util.List;
 
@@ -112,46 +110,4 @@
         assertTrue( violations.contains( new EntityPropertyValue( OrganisationUnit.class, "shortname", "OrganisationUnitShortA" ) ) );
         assertTrue( violations.contains( new EntityPropertyValue( OrganisationUnit.class, "code", "OrganisationUnitCodeA" ) ) );
     }
-
-    @Test
-    public void testNonExistingDataElementIdentifiers()
-    {
-        DataElement dataElementA = new DataElement();
-        dataElementA.setId( 1 );
-        
-        DataElement dataElementB = new DataElement();
-        dataElementB.setId( 2 );
-        
-        Indicator indicatorA = new Indicator();
-        indicatorA.setName( "IndicatorA" );
-        indicatorA.setNumerator( "[1.4]+[2.4]" );
-        indicatorA.setDenominator( "[1.4]" );
-
-        Indicator indicatorB = new Indicator();
-        indicatorB.setName( "IndicatorB" );
-        indicatorB.setNumerator( "[1.4]+[2.4]" );
-        indicatorB.setDenominator( "[3.4]" );
-
-        Indicator indicatorC = new Indicator();
-        indicatorC.setName( "IndicatorC" );
-        indicatorC.setNumerator( "[3.4]+[4.4]" );
-        indicatorC.setDenominator( "[5.4]" );
-        
-        analyser.addObject( dataElementA );
-        analyser.addObject( dataElementB );
-        analyser.addObject( indicatorA );
-        analyser.addObject( indicatorB );
-        analyser.addObject( indicatorC );
-        
-        ImportAnalysis analysis = analyser.getImportAnalysis();
-        List<IndicatorFormulaIdentifier> identifiers = analysis.getNonExistingDataElementIdentifiers();
-
-        assertNotNull( identifiers );
-        assertEquals( 4, identifiers.size() );
-        
-        assertTrue( identifiers.contains( new IndicatorFormulaIdentifier( "IndicatorB", DENOMINATOR, 3 ) ) );
-        assertTrue( identifiers.contains( new IndicatorFormulaIdentifier( "IndicatorC", NUMERATOR, 3 ) ) );
-        assertTrue( identifiers.contains( new IndicatorFormulaIdentifier( "IndicatorC", NUMERATOR, 4 ) ) );
-        assertTrue( identifiers.contains( new IndicatorFormulaIdentifier( "IndicatorC", DENOMINATOR, 5 ) ) );
-    }
 }

=== modified file 'dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/datasetreport/impl/DefaultDataSetReportService.java'
--- dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/datasetreport/impl/DefaultDataSetReportService.java	2012-10-18 19:13:26 +0000
+++ dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/datasetreport/impl/DefaultDataSetReportService.java	2013-01-05 15:22:55 +0000
@@ -200,7 +200,7 @@
                     }
                     else
                     {
-                        value = valueMap.get( dataElement.getId() + SEPARATOR + optionCombo.getId() );
+                        value = valueMap.get( dataElement.getUid() + SEPARATOR + optionCombo.getUid() );
                     }
 
                     grid.addValue( value );
@@ -210,7 +210,7 @@
                 {
                     for ( DataElementCategoryOption categoryOption : categoryCombo.getCategoryOptions() )
                     {
-                        Double value = subTotalMap.get( dataElement.getId() + SEPARATOR + categoryOption.getId() );
+                        Double value = subTotalMap.get( dataElement.getUid() + SEPARATOR + categoryOption.getUid() );
 
                         grid.addValue( value );
                     }
@@ -218,7 +218,7 @@
 
                 if ( categoryCombo.doTotal() && !selectedUnitOnly ) // Total
                 {
-                    Double value = totalMap.get( String.valueOf( dataElement.getId() ) );
+                    Double value = totalMap.get( String.valueOf( dataElement.getUid() ) );
 
                     grid.addValue( value );
                 }
@@ -295,7 +295,7 @@
                 }
                 else
                 {
-                    value = valueMap.get( dataElement.getId() + SEPARATOR + optionCombo.getId() );
+                    value = valueMap.get( dataElement.getUid() + SEPARATOR + optionCombo.getUid() );
                 }
 
                 grid.addValue( value );
@@ -315,7 +315,7 @@
 
             grid.addValue( indicator.getName() );
             
-            Double value = indicatorValueMap.get( String.valueOf( indicator.getId() ) );
+            Double value = indicatorValueMap.get( String.valueOf( indicator.getUid() ) );
             
             grid.addValue( value );
             

=== modified file 'dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/datasetreport/jdbc/JdbcDataSetReportStore.java'
--- dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/datasetreport/jdbc/JdbcDataSetReportStore.java	2012-12-29 16:37:15 +0000
+++ dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/datasetreport/jdbc/JdbcDataSetReportStore.java	2013-01-05 15:22:55 +0000
@@ -78,25 +78,29 @@
         if ( !dataElements.isEmpty() )
         {
             final String sql = rawData ?
-                "select dataelementid, categoryoptioncomboid, value " +
-                "from datavalue " +
-                "where dataelementid in (" + getCommaDelimitedString( getIdentifiers( DataElement.class, dataElements ) ) + ") " +
-                "and periodid = " + period.getId() + " " +
-                "and sourceid = " + unit.getId()
+                "select de.uid, coc.uid, dv.value " +
+                "from datavalue dv " +
+                "left join dataelement de on dv.dataelementid = de.dataelementid " +
+                "left join categoryoptioncombo coc on dv.categoryoptioncomboid = coc.categoryoptioncomboid " +
+                "where dv.dataelementid in (" + getCommaDelimitedString( getIdentifiers( DataElement.class, dataElements ) ) + ") " +
+                "and dv.periodid = " + period.getId() + " " +
+                "and dv.sourceid = " + unit.getId()
                 :
-                "select dataelementid, categoryoptioncomboid, value " +
-                "from aggregateddatavalue " +
-                "where dataelementid in (" + getCommaDelimitedString( getIdentifiers( DataElement.class, dataElements ) ) + ") " +
-                "and periodid = " + period.getId() + " " +
-                "and organisationunitid = " + unit.getId();            
+                "select de.uid, coc.uid, dv.value " +
+                "from aggregateddatavalue dv " +
+                "left join dataelement de on dv.dataelementid = de.dataelementid " +
+                "left join categoryoptioncombo coc on dv.categoryoptioncomboid = coc.categoryoptioncomboid " +
+                "where dv.dataelementid in (" + getCommaDelimitedString( getIdentifiers( DataElement.class, dataElements ) ) + ") " +
+                "and dv.periodid = " + period.getId() + " " +
+                "and dv.organisationunitid = " + unit.getId();            
             
             SqlRowSet rowSet = jdbcTemplate.queryForRowSet( sql );
             
             while ( rowSet.next() )
             {
-                int dataElementId = rowSet.getInt( "dataelementid" );
-                int categoryOptionComboId = rowSet.getInt( "categoryoptioncomboid" );
-                Double value = rowSet.getDouble( "value" );
+                String dataElementId = rowSet.getString( 1 );
+                String categoryOptionComboId = rowSet.getString( 2 );
+                Double value = rowSet.getDouble( 3 );
                 
                 map.put( dataElementId + SEPARATOR + categoryOptionComboId, value );
             }
@@ -119,20 +123,21 @@
                 for ( DataElementCategoryOption categoryOption : categoryCombo.getCategoryOptions() )
                 {
                     final String sql = 
-                        "select dataelementid, sum(value) as total " +
-                        "from aggregateddatavalue " +
-                        "where dataelementid in (" + getCommaDelimitedString( getIdentifiers( DataElement.class, dataElements ) ) + ") " +
-                        "and categoryoptioncomboid in (" + getCommaDelimitedString( getIdentifiers( DataElementCategoryOptionCombo.class, categoryOption.getCategoryOptionCombos() ) ) + ") " +
-                        "and periodid = " + period.getId() + " " +
-                        "and organisationunitid = " + unit.getId() + " " +
-                        "group by dataelementid";
+                        "select de.uid, sum(dv.value) as total " +
+                        "from aggregateddatavalue dv " +
+                        "left join dataelement de on dv.dataelementid = de.dataelementid " +
+                        "where dv.dataelementid in (" + getCommaDelimitedString( getIdentifiers( DataElement.class, dataElements ) ) + ") " +
+                        "and dv.categoryoptioncomboid in (" + getCommaDelimitedString( getIdentifiers( DataElementCategoryOptionCombo.class, categoryOption.getCategoryOptionCombos() ) ) + ") " +
+                        "and dv.periodid = " + period.getId() + " " +
+                        "and dv.organisationunitid = " + unit.getId() + " " +
+                        "group by de.uid";
                     
                     SqlRowSet rowSet = jdbcTemplate.queryForRowSet( sql );
                     
                     while ( rowSet.next() )
                     {
-                        int dataElementId = rowSet.getInt( "dataelementid" );
-                        Double value = rowSet.getDouble( "total" );
+                        String dataElementId = rowSet.getString( 1 );
+                        Double value = rowSet.getDouble( 2 );
                         
                         map.put( dataElementId + SEPARATOR + categoryOption.getId(), value );
                     }
@@ -154,19 +159,20 @@
         if ( !dataElements.isEmpty() )
         {
             final String sql = 
-                "select dataelementid, sum(value) as total " +
-                "from aggregateddatavalue " +
-                "where dataelementid in (" + getCommaDelimitedString( getIdentifiers( DataElement.class, dataElements ) ) + ") " +
-                "and periodid = " + period.getId() + " " +
-                "and organisationunitid = " + unit.getId() + " " +
-                "group by dataelementid";
+                "select de.uid, sum(dv.value) as total " +
+                "from aggregateddatavalue dv " +
+                "left join dataelement de on dv.dataelementid = de.dataelementid " +
+                "where dv.dataelementid in (" + getCommaDelimitedString( getIdentifiers( DataElement.class, dataElements ) ) + ") " +
+                "and dv.periodid = " + period.getId() + " " +
+                "and dv.organisationunitid = " + unit.getId() + " " +
+                "group by de.uid";
     
             SqlRowSet rowSet = jdbcTemplate.queryForRowSet( sql );
             
             while ( rowSet.next() )
             {
-                int dataElementId = rowSet.getInt( "dataelementid" );
-                Double value = rowSet.getDouble( "total" );
+                String dataElementId = rowSet.getString( 1 );
+                Double value = rowSet.getDouble( 2 );
                 
                 map.put( String.valueOf( dataElementId ), value );
             }
@@ -184,19 +190,20 @@
         if ( !indicators.isEmpty() )
         {
             final String sql =
-                "select indicatorid, sum(value) as total " +
-                "from aggregatedindicatorvalue " +
-                "where indicatorid in (" + getCommaDelimitedString( getIdentifiers( Indicator.class, indicators ) ) + ") " +
-                "and periodid = " + period.getId() + " " +
-                "and organisationunitid = " + unit.getId() + " " +
-                "group by indicatorid";
+                "select ind.uid, sum(dv.value) as total " +
+                "from aggregatedindicatorvalue dv " +
+                "left join indicator ind on dv.indicatorid = ind.indicatorid " +
+                "where dv.indicatorid in (" + getCommaDelimitedString( getIdentifiers( Indicator.class, indicators ) ) + ") " +
+                "and dv.periodid = " + period.getId() + " " +
+                "and dv.organisationunitid = " + unit.getId() + " " +
+                "group by ind.uid";
     
             SqlRowSet rowSet = jdbcTemplate.queryForRowSet( sql );
             
             while ( rowSet.next() )
             {
-                int indicatorid = rowSet.getInt( "indicatorid" );
-                Double value = rowSet.getDouble( "total" );
+                String indicatorid = rowSet.getString( 1 );
+                Double value = rowSet.getDouble( 2 );
                 
                 map.put( String.valueOf( indicatorid ), value );
             }

=== modified file 'dhis-2/dhis-support/dhis-support-hibernate/src/main/java/org/hisp/dhis/cache/DefaultHibernateCacheManager.java'
--- dhis-2/dhis-support/dhis-support-hibernate/src/main/java/org/hisp/dhis/cache/DefaultHibernateCacheManager.java	2011-12-26 10:07:59 +0000
+++ dhis-2/dhis-support/dhis-support-hibernate/src/main/java/org/hisp/dhis/cache/DefaultHibernateCacheManager.java	2013-01-05 15:22:55 +0000
@@ -32,7 +32,6 @@
 
 /**
  * @author Lars Helge Overland
- * @version $Id: CrossTabDataValue.java 5514 2008-08-04 10:48:07Z larshelg $
  */
 public class DefaultHibernateCacheManager
     implements HibernateCacheManager

=== modified file 'dhis-2/dhis-support/dhis-support-hibernate/src/main/java/org/hisp/dhis/cache/HibernateCacheManager.java'
--- dhis-2/dhis-support/dhis-support-hibernate/src/main/java/org/hisp/dhis/cache/HibernateCacheManager.java	2011-12-26 10:07:59 +0000
+++ dhis-2/dhis-support/dhis-support-hibernate/src/main/java/org/hisp/dhis/cache/HibernateCacheManager.java	2013-01-05 15:22:55 +0000
@@ -31,7 +31,6 @@
 
 /**
  * @author Lars Helge Overland
- * @version $Id: CrossTabDataValue.java 5514 2008-08-04 10:48:07Z larshelg $
  */
 public interface HibernateCacheManager
 {

=== modified file 'dhis-2/dhis-support/dhis-support-test/src/main/java/org/hisp/dhis/DhisConvenienceTest.java'
--- dhis-2/dhis-support/dhis-support-test/src/main/java/org/hisp/dhis/DhisConvenienceTest.java	2012-11-20 17:04:08 +0000
+++ dhis-2/dhis-support/dhis-support-test/src/main/java/org/hisp/dhis/DhisConvenienceTest.java	2013-01-04 18:10:25 +0000
@@ -107,7 +107,7 @@
  */
 public abstract class DhisConvenienceTest
 {
-    private static final String BASE_UID = "123456789a";
+    protected static final String BASE_UID = "123456789a";
 
     private static final String EXT_TEST_DIR = System.getProperty( "user.home" ) + File.separator + "dhis2_test_dir";
 

=== modified file 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/ajax/jsonCategoryOptionCombos.vm'
--- dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/ajax/jsonCategoryOptionCombos.vm	2011-05-16 14:21:57 +0000
+++ dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/ajax/jsonCategoryOptionCombos.vm	2013-01-05 15:22:55 +0000
@@ -3,6 +3,7 @@
 #foreach( $coc in $categoryOptionCombos )
   {
     "id": $!{coc.id},
+    "uid": "$!{coc.uid}",
     "name": "$!encoder.jsonEncode( ${coc.name} )",
 	"default": "$coc.isDefault()"
   }#if( $velocityCount < $size ),#end

=== modified file 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/ajax/jsonDataElementOperands.vm'
--- dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/ajax/jsonDataElementOperands.vm	2011-05-16 14:21:57 +0000
+++ dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/ajax/jsonDataElementOperands.vm	2013-01-05 15:22:55 +0000
@@ -4,12 +4,12 @@
   {
   	"operandName": "$!{operand.operandName}",
     "dataElement": {
-    	"id": "$!{operand.dataElement.id}",
+    	"id": "$!{operand.dataElement.uid}",
     	"name": "$!{operand.dataElement.name}",
     	"type": "$!{operand.dataElement.type}"
     },
     "categoryOptionCombo": {
-    	"id": "$!{operand.categoryOptionCombo.id}",
+    	"id": "$!{operand.categoryOptionCombo.uid}",
     	"name": "$!{operand.categoryOptionCombo.name}"
     }
   }#if( $velocityCount < $size ),#end

=== modified file 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/ajax/jsonDataElements.vm'
--- dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/ajax/jsonDataElements.vm	2012-01-22 11:28:12 +0000
+++ dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/ajax/jsonDataElements.vm	2013-01-05 15:22:55 +0000
@@ -4,7 +4,8 @@
 #set( $groups = $dataElement.groups )
 #set( $dataSets = $dataElement.dataSets )
   {
-	"id":  ${dataElement.id} ,
+	"id":  ${dataElement.id},
+	"uid": "${dataElement.uid}",
 	"name": "$!encoder.jsonEncode( ${dataElement.displayName} )",
 	"alternativeName": "$!encoder.jsonEncode( ${dataElement.alternativeNamee} )",
 	"shortName": "$!encoder.jsonEncode( ${dataElement.displayShortName} )",

=== modified file 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/ajax/jsonIndicators.vm'
--- dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/ajax/jsonIndicators.vm	2012-01-22 11:28:12 +0000
+++ dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/ajax/jsonIndicators.vm	2013-01-05 15:22:55 +0000
@@ -4,6 +4,7 @@
 #set( $groups = $indicator.groups )
   {
     "id": $!{indicator.id},
+    "uid": "$!{indicator.uid}",
     "name": "$!encoder.jsonEncode( ${indicator.displayName} )",
     "alternativeName": "$!encoder.jsonEncode( ${indicator.alternativeNamee} )",
     "shortName": "$!encoder.jsonEncode( ${indicator.displayShortName} )",

=== modified file 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/commons.ajax.js'
--- dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/commons.ajax.js	2012-10-17 18:53:29 +0000
+++ dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/commons.ajax.js	2013-01-05 15:22:55 +0000
@@ -209,7 +209,7 @@
             {
                 jQuery.each( json.operands, function( i, item )
                 {
-                    target.append( '<option value="[' + item.operandId + ']">' + item.operandName
+                    target.append( '<option value="#{' + item.operandId + '}">' + item.operandName
                             + '</option>' );
                 } );
 

=== modified file 'dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/commons/action/GetCategoryOptionCombosAction.java'
--- dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/commons/action/GetCategoryOptionCombosAction.java	2012-09-15 22:53:29 +0000
+++ dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/commons/action/GetCategoryOptionCombosAction.java	2013-01-05 15:22:55 +0000
@@ -78,6 +78,13 @@
     {
         this.categoryComboId = categoryComboId;
     }
+    
+    private String categoryComboUid;
+
+    public void setCategoryComboUid( String categoryComboUid )
+    {
+        this.categoryComboUid = categoryComboUid;
+    }
 
     // -------------------------------------------------------------------------
     // Output
@@ -119,6 +126,15 @@
                 categoryOptionCombos = categoryCombo.getOptionCombos();
             }
         }
+        else if ( categoryComboUid != null )
+        {
+            DataElementCategoryCombo categoryCombo = categoryService.getDataElementCategoryCombo( categoryComboUid );
+            
+            if ( categoryCombo != null )
+            {
+                categoryOptionCombos = categoryCombo.getOptionCombos();
+            }
+        }
 
         return SUCCESS;
     }

=== modified file 'dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/commons/action/GetOrganisationUnitTreeAction.java'
--- dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/commons/action/GetOrganisationUnitTreeAction.java	2012-10-31 09:36:23 +0000
+++ dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/commons/action/GetOrganisationUnitTreeAction.java	2013-01-05 15:22:55 +0000
@@ -27,7 +27,12 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-import com.opensymphony.xwork2.Action;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.UUID;
+
 import org.hisp.dhis.common.comparator.IdentifiableObjectNameComparator;
 import org.hisp.dhis.configuration.ConfigurationService;
 import org.hisp.dhis.organisationunit.OrganisationUnit;
@@ -40,7 +45,7 @@
 import org.hisp.dhis.version.Version;
 import org.hisp.dhis.version.VersionService;
 
-import java.util.*;
+import com.opensymphony.xwork2.Action;
 
 /**
  * @author mortenoh
@@ -214,7 +219,7 @@
             }
         }
 
-        Collection intersection = org.apache.commons.collections.CollectionUtils.intersection(
+        Collection<?> intersection = org.apache.commons.collections.CollectionUtils.intersection(
             organisationUnitService.getRootOrganisationUnits(), rootOrganisationUnits );
 
         if ( intersection.size() > 0 )

=== modified file 'dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/security/AbstractAutomaticAccessProvider.java'
--- dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/security/AbstractAutomaticAccessProvider.java	2012-03-07 14:37:56 +0000
+++ dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/security/AbstractAutomaticAccessProvider.java	2013-01-05 15:22:55 +0000
@@ -34,7 +34,6 @@
 import org.hisp.dhis.security.authority.SystemAuthoritiesProvider;
 import org.hisp.dhis.user.UserService;
 import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.authority.GrantedAuthorityImpl;
 import org.springframework.security.core.authority.SimpleGrantedAuthority;
 
 /**

=== modified file 'dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/security/filter/BasicAuthenticationRequiredFilter.java'
--- dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/security/filter/BasicAuthenticationRequiredFilter.java	2010-11-26 10:54:28 +0000
+++ dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/security/filter/BasicAuthenticationRequiredFilter.java	2013-01-05 15:22:55 +0000
@@ -25,7 +25,6 @@
 public class BasicAuthenticationRequiredFilter
     extends BasicAuthenticationFilter
 {
-
     @Override
     public void doFilter( ServletRequest req, ServletResponse res, FilterChain chain )
         throws IOException, ServletException

=== modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/LoadFormAction.java'
--- dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/LoadFormAction.java	2012-12-01 12:12:01 +0000
+++ dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/LoadFormAction.java	2013-01-04 18:10:25 +0000
@@ -366,7 +366,7 @@
 
             for ( DataElementOperand operand : section.getGreyedFields() )
             {
-                greyedFields.put( operand.getDataElement().getId() + ":" + operand.getCategoryOptionCombo().getId(),
+                greyedFields.put( operand.getDataElement().getUid() + ":" + operand.getCategoryOptionCombo().getUid(),
                     true );
             }
         }

=== modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/SaveValueAction.java'
--- dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/SaveValueAction.java	2012-02-16 19:55:38 +0000
+++ dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/SaveValueAction.java	2013-01-04 18:10:25 +0000
@@ -110,9 +110,9 @@
         this.value = value;
     }
 
-    private int dataElementId;
+    private String dataElementId;
 
-    public void setDataElementId( int dataElementId )
+    public void setDataElementId( String dataElementId )
     {
         this.dataElementId = dataElementId;
     }
@@ -124,9 +124,9 @@
         this.organisationUnitId = organisationUnitId;
     }
 
-    private int optionComboId;
+    private String optionComboId;
 
-    public void setOptionComboId( int optionComboId )
+    public void setOptionComboId( String optionComboId )
     {
         this.optionComboId = optionComboId;
     }

=== modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/customForm.vm'
--- dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/customForm.vm	2012-09-18 09:17:06 +0000
+++ dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/customForm.vm	2013-01-05 15:22:55 +0000
@@ -7,6 +7,6 @@
 <select id="dynselect" class="hidden">
 <option value="-1">[ $i18n.getString( "select_data_element" ) ]</option>
 #foreach( $element in $dataElementsNotInForm )
-<option value="${element.id}">$encoder.htmlEncode( ${element.displayName} )</option>
+<option value="${element.uid}">$encoder.htmlEncode( ${element.displayName} )</option>
 #end
 </select>
\ No newline at end of file

=== modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/defaultForm.vm'
--- dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/defaultForm.vm	2012-10-02 14:18:38 +0000
+++ dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/defaultForm.vm	2013-01-04 18:10:25 +0000
@@ -26,7 +26,7 @@
   #set( $dataElements = $orderedDataElements.get( $categoryCombo )  )
   #set( $optionCombos = $orderedCategoryOptionCombos.get( $categoryCombo.id )  )
   #set( $mark = 0 )
-  #foreach( $optionCombo in $optionCombos )<span id="${optionCombo.id}-optioncombo" class="hidden">${encoder.htmlEncode( $optionCombo.name )}</span>
+  #foreach( $optionCombo in $optionCombos )<span id="${optionCombo.uid}-optioncombo" class="hidden">${encoder.htmlEncode( $optionCombo.name )}</span>
   #end
   #foreach( $dataElement in $dataElements )
   #if( $mark == 1 )
@@ -36,9 +36,9 @@
   #end
   #set( $count = $count + 1 )
   <tr>
-  <td id="${dataElement.id}-cell" #if( $mark == 1 )class="alt"#else class="reg"#end><span id="${dataElement.id}-dataelement">${encoder.htmlEncode( $dataElement.getFormNameFallback() )}</span></td>
+  <td id="${dataElement.uid}-cell" #if( $mark == 1 )class="alt"#else class="reg"#end><span id="${dataElement.uid}-dataelement">${encoder.htmlEncode( $dataElement.getFormNameFallback() )}</span></td>
   #foreach( $optionCombo in $optionCombos )
-  #set( $dataEntryId = "${dataElement.id}-${optionCombo.id}-val" )	    
+  #set( $dataEntryId = "${dataElement.uid}-${optionCombo.uid}-val" )	    
   <td>
   #if( $dataElement.type == "bool" )
   <select name="entryselect" id="$dataEntryId"#if( !$hasAccess ) disabled="disabled"#end tabindex="$tabIndex">

=== modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/javascript/entry.js'
--- dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/javascript/entry.js	2012-12-07 08:10:30 +0000
+++ dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/javascript/entry.js	2013-01-05 15:22:55 +0000
@@ -15,7 +15,7 @@
 // Save
 // -----------------------------------------------------------------------------
 
-var FORMULA_PATTERN = /\[.+?\]/g;
+var FORMULA_PATTERN = /#\{.+?\}/g;
 var SEPARATOR = '.';
 
 function updateDataElementTotals()
@@ -89,7 +89,7 @@
 
         // Remove brackets from expression to simplify extraction of identifiers
 
-        var operand = match.replace( /[\[\]]/g, '' );
+        var operand = match.replace( /[#\{\}]/g, '' );
 
         var dataElementId = operand.substring( 0, operand.indexOf( SEPARATOR ) );
         var categoryOptionComboId = operand.substring( operand.indexOf( SEPARATOR ) + 1, operand.length );
@@ -126,8 +126,6 @@
 
 function saveVal( dataElementId, optionComboId, fieldId )
 {
-	dataElementId = parseInt( dataElementId );
-	optionComboId = parseInt( optionComboId );
     fieldId = '#' + fieldId;
 	
     var dataElementName = getDataElementName( dataElementId );

=== modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/javascript/form.js'
--- dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/javascript/form.js	2013-01-02 22:05:25 +0000
+++ dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/javascript/form.js	2013-01-04 18:10:25 +0000
@@ -480,7 +480,7 @@
 
         multiOrganisationUnit = !!$('.formSection').data('multiorg');
 
-        if(!multiOrganisationUnit)
+        if ( !multiOrganisationUnit )
         {
             enableSectionFilter();
             insertDynamicOptions();
@@ -584,16 +584,17 @@
 
 function enableSectionFilter()
 {
-    var $sectionsHeaders = $( '.formSection .cent h3' );
+    var $sectionHeaders = $( '.formSection .cent h3' );
     clearSectionFilters();
 
-    if ( $sectionsHeaders.size() > 1)
+    if ( $sectionHeaders.size() > 1)
     {
         $( '#selectionBox' ).css( 'height', '123px' );
 
         $( '#filterDataSetSection' ).append( "<option value='all'>" + i18n_show_all_sections + "</option>" );
 
-        $sectionsHeaders.each(function(idx, value) {
+        $sectionHeaders.each( function( idx, value ) 
+        {
             $( '#filterDataSetSection' ).append( "<option value='" + idx + "'>" + value.innerHTML + "</option>" );
         } );
 
@@ -994,7 +995,7 @@
         }
         else
         {
-            var isMultiOrganisationUnitForm = !!$('#selectedDataSetId :selected').data('multiorg');
+            var isMultiOrganisationUnitForm = !!$( '#selectedDataSetId :selected' ).data( 'multiorg' );
             loadForm( dataSetId, isMultiOrganisationUnitForm );
         }
     }
@@ -1186,7 +1187,7 @@
 {
     addEventListeners();
 
-    if(!multiOrganisationUnit)
+    if ( !multiOrganisationUnit )
     {
         $( '#validationButton' ).removeAttr( 'disabled' );
         $( '#validateButton' ).removeAttr( 'disabled' );

=== modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/multiOrgSectionForm.vm'
--- dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/multiOrgSectionForm.vm	2012-11-13 13:37:08 +0000
+++ dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/multiOrgSectionForm.vm	2013-01-04 18:10:25 +0000
@@ -61,7 +61,7 @@
     #set( $count = 0 )
     #set( $mark = 0 )
     #set( $optionCombos = $orderedCategoryOptionCombos.get( $categoryComboId )  )
-    #foreach( $optionCombo in $optionCombos )<span id="${optionCombo.id}-optioncombo" class="hidden">${encoder.htmlEncode( $optionCombo.name )}</span>
+    #foreach( $optionCombo in $optionCombos )<span id="${optionCombo.uid}-optioncombo" class="hidden">${encoder.htmlEncode( $optionCombo.name )}</span>
     #end
 
     #foreach( $organisationUnit in $organisationUnits )
@@ -71,15 +71,15 @@
         #set( $mark = 1 )
         #end
         #set( $count = $count + 1 )
-        #set( $dataEntryId = "${organisationUnit.id}-${dataElement.id}-${optionCombo.id}-val" )
+        #set( $dataEntryId = "${organisationUnit.id}-${dataElement.uid}-${optionCombo.uid}-val" )
         <tr>
             <td #if( $mark == 1 )class="alt"#else class="reg"#end>${encoder.htmlEncode( $organisationUnit.name )}</td>
 
             #foreach( $dataElement in $section.dataElements )
                 #foreach( $optionCombo in $optionCombos )
-                #set( $dataEntryId = "${organisationUnit.id}-${dataElement.id}-${optionCombo.id}-val" )
+                #set( $dataEntryId = "${organisationUnit.id}-${dataElement.uid}-${optionCombo.uid}-val" )
                 #set( $greyedField = false )
-                #set( $greyedField = $greyedFields.get( "$dataElement.id:$optionCombo.id" ) )
+                #set( $greyedField = $greyedFields.get( "$dataElement.uid:$optionCombo.uid" ) )
                 #if( $dataElement.type == "bool" )
                 <td><select name="entryselect" id="$dataEntryId" tabindex="$tabIndex"#if( $greyedField || !$hasAccess ) disabled="disabled"#end>
                   <option value="">[$i18n.getString( "no_value" )]</option>

=== modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/responseDataValues.vm'
--- dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/responseDataValues.vm	2012-11-12 10:22:34 +0000
+++ dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/responseDataValues.vm	2013-01-04 18:10:25 +0000
@@ -4,9 +4,9 @@
   #foreach( $value in $dataValues )
   {
     #if( $multiOrganisationUnit )
-    "id":"${value.source.id}-${value.dataElement.id}-${value.optionCombo.id}",
+    "id":"${value.source.id}-${value.dataElement.uid}-${value.optionCombo.uid}",
     #else
-    "id":"${value.dataElement.id}-${value.optionCombo.id}",
+    "id":"${value.dataElement.uid}-${value.optionCombo.uid}",
     #end
     "val":"$!{value.value}"
   }#if( $velocityCount < $size1 ),#end
@@ -15,9 +15,9 @@
   #foreach( $element in $minMaxDataElements )
   {
     #if( $multiOrganisationUnit )
-    "id":"${element.source.id}-${element.dataElement.id}-${element.optionCombo.id}",
+    "id":"${element.source.id}-${element.dataElement.uid}-${element.optionCombo.uid}",
     #else
-    "id":"${element.dataElement.id}-${element.optionCombo.id}",
+    "id":"${element.dataElement.uid}-${element.optionCombo.uid}",
     #end
     "min":"${element.min}",
     "max":"${element.max}"
@@ -27,4 +27,4 @@
   "complete":${complete},
   "date":"$!format.formatDate( $date )",
   "storedBy":"$!{storedBy}"
- }
+}

=== modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/responseMetaData.vm'
--- dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/responseMetaData.vm	2012-09-27 03:57:57 +0000
+++ dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/responseMetaData.vm	2013-01-04 18:10:25 +0000
@@ -3,20 +3,20 @@
 "significantZeros": [
 #set( $size = $significantZeros.size() )
 #foreach( $dataElement in $significantZeros )
-${dataElement.id}#if( $velocityCount < $size ),#end
+${dataElement.uid}#if( $velocityCount < $size ),#end
 #end ],
 
 "dataElements": {
 #set( $size = $dataElements.size() )
 #foreach( $dataElement in $dataElements )
-"${dataElement.id}":"$encoder.jsonEncode( ${dataElement.getDetailedNumberType()} )" 
+"${dataElement.uid}":"$encoder.jsonEncode( ${dataElement.getDetailedNumberType()} )" 
 #if( $velocityCount < $size ),#end
 #end },
 
 "indicatorFormulas": {
 #set( $size = $indicators.size() )
 #foreach( $indicator in $indicators )
-"${indicator.id}":"($!{indicator.explodedNumerator})/($!{indicator.explodedDenominator})*($!{indicator.indicatorType.factor})"
+"${indicator.uid}":"($!{indicator.explodedNumerator})/($!{indicator.explodedDenominator})*($!{indicator.indicatorType.factor})"
 #if( $velocityCount < $size ),#end
 #end },
 

=== modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/sectionForm.vm'
--- dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/sectionForm.vm	2012-10-15 08:45:08 +0000
+++ dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/sectionForm.vm	2013-01-04 18:10:25 +0000
@@ -44,7 +44,7 @@
     #set( $count = 0 )
     #set( $mark = 0 )
     #set( $optionCombos = $orderedCategoryOptionCombos.get( $categoryComboId )  )
-    #foreach( $optionCombo in $optionCombos )<span id="${optionCombo.id}-optioncombo" class="hidden">${encoder.htmlEncode( $optionCombo.name )}</span>
+    #foreach( $optionCombo in $optionCombos )<span id="${optionCombo.uid}-optioncombo" class="hidden">${encoder.htmlEncode( $optionCombo.name )}</span>
     #end
     #foreach( $dataElement in $section.dataElements )
     #if( $mark == 1 )
@@ -54,11 +54,11 @@
     #end
     #set( $count = $count + 1 )
     <tr>
-    <td id="${dataElement.id}-cell" #if( $mark == 1 )class="alt"#else class="reg"#end><span id="${dataElement.id}-dataelement">${encoder.htmlEncode( $dataElement.getFormNameFallback() )}</span></td>
+    <td id="${dataElement.uid}-cell" #if( $mark == 1 )class="alt"#else class="reg"#end><span id="${dataElement.uid}-dataelement">${encoder.htmlEncode( $dataElement.getFormNameFallback() )}</span></td>
     #foreach( $optionCombo in $optionCombos )
-    #set( $dataEntryId = "${dataElement.id}-${optionCombo.id}-val" )
+    #set( $dataEntryId = "${dataElement.uid}-${optionCombo.uid}-val" )
     #set( $greyedField = false )
-    #set( $greyedField = $greyedFields.get( "$dataElement.id:$optionCombo.id" ) )        
+    #set( $greyedField = $greyedFields.get( "$dataElement.uid:$optionCombo.uid" ) )        
     #if( $dataElement.type == "bool" )
     <td><select name="entryselect" id="$dataEntryId" tabindex="$tabIndex"#if( $greyedField || !$hasAccess ) disabled="disabled"#end>
       <option value="">[$i18n.getString( "no_value" )]</option>

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/java/org/hisp/dhis/dd/action/dataelement/GetDataElementGroupMembersAction.java'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/java/org/hisp/dhis/dd/action/dataelement/GetDataElementGroupMembersAction.java	2012-01-20 10:38:11 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/java/org/hisp/dhis/dd/action/dataelement/GetDataElementGroupMembersAction.java	2013-01-04 18:10:25 +0000
@@ -118,15 +118,15 @@
             {
                 for ( DataElementCategoryOptionCombo optionCombo : optionCombos )
                 {
-                    DataElementOperand operand = new DataElementOperand( dataElement.getId(), optionCombo.getId(), dataElement.getName()
-                        + optionCombo.getName() );
+                    DataElementOperand operand = new DataElementOperand( dataElement.getUid(), 
+                        optionCombo.getUid(), dataElement.getName() + optionCombo.getName() );
                     operands.add( operand );
                 }
             }
             else
             {
-                DataElementOperand operand = new DataElementOperand( dataElement.getId(), optionCombos.iterator().next().getId(), dataElement
-                    .getName() );
+                DataElementOperand operand = new DataElementOperand( dataElement.getUid(), 
+                    optionCombos.iterator().next().getUid(), dataElement.getName() );
                 operands.add( operand );
             }
         }

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataset/src/main/webapp/dhis-web-maintenance-dataset/javascript/viewDataEntryForm.js'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataset/src/main/webapp/dhis-web-maintenance-dataset/javascript/viewDataEntryForm.js	2012-11-20 14:43:33 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataset/src/main/webapp/dhis-web-maintenance-dataset/javascript/viewDataEntryForm.js	2013-01-05 15:22:55 +0000
@@ -167,7 +167,7 @@
 		handler: function(item) {
 			var option = jQuery("<option />");
 			option.text( item.name );
-			option.data( "id", item.id );
+			option.data( "id", item.uid );
 			option.dblclick(insertTotal);
 
 			return option;
@@ -183,7 +183,7 @@
 		handler: function(item) {
 			var option = jQuery("<option />");
 			option.text( item.name );
-			option.data("id", item.id);
+			option.data("id", item.uid);
 			option.dblclick(insertIndicator);
 
 			return option;
@@ -423,9 +423,9 @@
 	
 	clearListById( "dynamicElementSelector" );
 	
-	var optionCombos = $.getJSON( "../dhis-web-commons-ajax-json/getCategoryOptionCombos.action?categoryComboId=" + categoryComboId, function( json ) {
+	var optionCombos = $.getJSON( "../dhis-web-commons-ajax-json/getCategoryOptionCombos.action?categoryComboUid=" + categoryComboId, function( json ) {
 		$.each( json.categoryOptionCombos, function( index, value ) {
-			addOptionById( "dynamicElementSelector", value.id, value.name );
+			addOptionById( "dynamicElementSelector", value.uid, value.name );
 		} );
 	} );	
 }

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataset/src/main/webapp/dhis-web-maintenance-dataset/viewDataEntryForm.vm'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataset/src/main/webapp/dhis-web-maintenance-dataset/viewDataEntryForm.vm	2012-11-20 14:43:33 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataset/src/main/webapp/dhis-web-maintenance-dataset/viewDataEntryForm.vm	2013-01-05 15:22:55 +0000
@@ -135,7 +135,7 @@
 						<div style="color:#666; margin-top:5px; margin-bottom:5px;">$i18n.getString( "select_category_combo_for_which_to_insert" )</div>
 						<select id="categoryComboSelect" style="width: 100%; margin-bottom: 10px;">
 							#foreach( $categoryCombo in $categoryCombos )
-							<option value="$categoryCombo.id">$encoder.htmlEncode( $categoryCombo.name )</option>
+							<option value="$categoryCombo.uid">$encoder.htmlEncode( $categoryCombo.name )</option>
 							#end
 						</select><br>
 						<button type="button" id="startButton">$i18n.getString( "start" )</button>

=== modified file 'resources/sql/copydata.sql'
--- resources/sql/copydata.sql	2012-02-09 18:15:43 +0000
+++ resources/sql/copydata.sql	2013-01-04 18:10:25 +0000
@@ -5,7 +5,7 @@
 
 -- Replace first periodid with current year, replace second periodid with last year, replace dataset.name with population dataset name, replace data level as required
 
-delete from datavalue where periodid=112482 and dataelementid in (
+delete from datavalue where periodid=234430 and dataelementid in (
   select dataelementid from datasetmembers
   join dataset using(datasetid)
   where dataset.name='Population estimates' )
@@ -15,9 +15,9 @@
   where os.level = 4);
 
 insert into datavalue(dataelementid,periodid,sourceid,categoryoptioncomboid,value,storedby,lastupdated,comment,followup)
-select dataelementid,112482 as periodid,sourceid,categoryoptioncomboid,ceil(cast(value as double precision)*1.029) as value,storedby,lastupdated,null,false
+select dataelementid,234430 as periodid,sourceid,categoryoptioncomboid,ceil(cast(value as double precision)*1.029) as value,storedby,lastupdated,null,false
 from datavalue
-where periodid=43668 and dataelementid in (
+where periodid=112482 and dataelementid in (
   select dataelementid from datasetmembers
   join dataset using(datasetid)
   where dataset.name='Population estimates' )