← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 21503: Merge sms branch. Introdeces SmsUtils. Autowiring. Code style.

 

Merge authors:
  Lars Helge Øverland (larshelge)
  Zubair (rajazubair-asghar)
------------------------------------------------------------
revno: 21503 [merge]
committer: Lars Helge Overland <larshelge@xxxxxxxxx>
branch nick: dhis2
timestamp: Mon 2015-12-21 17:44:02 +0100
message:
  Merge sms branch. Introdeces SmsUtils. Autowiring. Code style.
added:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/command/
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/command/code/
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/SmsConsumerThread.java
  dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/SmsUtils.java
renamed:
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/command/SMSCommand.java => dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/command/SMSCommand.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/command/SMSSpecialCharacter.java => dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/command/SMSSpecialCharacter.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/command/code/SMSCode.java => dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/command/code/SMSCode.java
modified:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/SmsConsumer.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/SmsServiceNotEnabledException.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/config/BulkSmsGatewayConfig.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/config/ModemGatewayConfig.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/config/SMSGatewayStatus.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/config/SmsConfigurable.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/config/SmsConfiguration.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/config/SmsConfigurationManager.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/incoming/IncomingSms.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/incoming/IncomingSmsListener.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/incoming/IncomingSmsService.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/incoming/IncomingSmsStore.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/outbound/OutboundSms.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/outbound/OutboundSmsService.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/outbound/OutboundSmsStore.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/outbound/OutboundSmsTransportService.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/parse/ParserType.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/message/DefaultMessageService.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/DatabaseSupportedInternalMemoryMessageQueue.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/DefaultSmsSender.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/SmsMessageSender.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/SmsPublisher.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/command/DefaultSMSCommandService.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/command/SMSCommandDeletionHandler.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/command/SMSCommandService.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/command/code/SMSCodesDeletionHandler.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/command/hibernate/HibernateSMSCommandStore.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/command/hibernate/SMSCommandStore.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/config/AdvanceHttpPostGateWay.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/config/DefaultSmsConfigurationManager.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/config/GateWayFactory.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/config/SimplisticHttpGetGateWay.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/hibernate/HibernateIncomingSmsStore.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/hibernate/HibernateOutboundSmsStore.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/incoming/DefaultIncomingSmsService.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/incoming/SMPPInboundNotification.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/listener/DHISMessageAlertListener.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/listener/DataValueSMSListener.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/listener/J2MEDataValueSMSListener.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/listener/ProgramStageDataEntrySMSListener.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/listener/TrackedEntityRegistrationSMSListener.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/listener/UnregisteredSMSListener.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/outbound/DefaultOutboundSmsTransportService.java
  dhis-2/dhis-services/dhis-service-core/src/main/resources/META-INF/dhis/beans.xml
  dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/sms/SmsController.java
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/java/org/hisp/dhis/mobile/action/SendSMSAction.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/command/SMSSpecialCharacter.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/command/code/SMSCode.java


--
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/sms/SmsConsumer.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/SmsConsumer.java	2015-01-17 07:41:26 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/SmsConsumer.java	2015-12-14 10:17:29 +0000
@@ -31,5 +31,6 @@
 public interface SmsConsumer
 {
     void start();
+
     void stop();
 }

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/SmsServiceNotEnabledException.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/SmsServiceNotEnabledException.java	2015-01-17 07:41:26 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/SmsServiceNotEnabledException.java	2015-12-14 10:17:29 +0000
@@ -33,7 +33,7 @@
 {
     private static final long serialVersionUID = -1484667419558937721L;
 
-    public SmsServiceNotEnabledException( )
+    public SmsServiceNotEnabledException()
     {
         super( "Sms service is not enabled" );
     }

=== added directory 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/command'
=== renamed file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/command/SMSCommand.java' => 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/command/SMSCommand.java'
=== renamed file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/command/SMSSpecialCharacter.java' => 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/command/SMSSpecialCharacter.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/command/SMSSpecialCharacter.java	2015-10-07 14:40:33 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/command/SMSSpecialCharacter.java	2015-12-14 10:17:29 +0000
@@ -1,32 +1,32 @@
 package org.hisp.dhis.sms.command;
 
- /*
- * Copyright (c) 2004-2015, 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.
- */
+/*
+* Copyright (c) 2004-2015, 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.
+*/
 
 /**
  * @author Nguyen Kim Lai
@@ -36,15 +36,15 @@
 public class SMSSpecialCharacter
 {
     private int id;
-    
+
     private String name;
-    
+
     private String value;
 
     public SMSSpecialCharacter()
     {
     }
-    
+
     public SMSSpecialCharacter( String name, String value )
     {
         this.name = name;

=== added directory 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/command/code'
=== renamed file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/command/code/SMSCode.java' => 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/command/code/SMSCode.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/command/code/SMSCode.java	2015-06-23 15:59:19 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/command/code/SMSCode.java	2015-12-14 10:17:29 +0000
@@ -38,11 +38,11 @@
     private String code;
 
     private DataElement dataElement;
-    
+
     private TrackedEntityAttribute trackedEntityAttribute;
 
     private int optionId;
-    
+
     private String formula;
 
     public SMSCode( String code, DataElement dataElement, int optionId )
@@ -51,8 +51,8 @@
         this.dataElement = dataElement;
         this.optionId = optionId;
     }
-    
-    public SMSCode( String code, TrackedEntityAttribute trackedEntityAttribute)
+
+    public SMSCode( String code, TrackedEntityAttribute trackedEntityAttribute )
     {
         this.code = code;
         this.trackedEntityAttribute = trackedEntityAttribute;

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/config/BulkSmsGatewayConfig.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/config/BulkSmsGatewayConfig.java	2015-10-07 14:40:33 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/config/BulkSmsGatewayConfig.java	2015-12-14 10:17:29 +0000
@@ -36,7 +36,7 @@
     private String username;
 
     private String password;
-    
+
     private String region;
 
     public String getUsername()
@@ -58,7 +58,7 @@
     {
         this.password = password;
     }
-    
+
     public String getRegion()
     {
         return region;

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/config/ModemGatewayConfig.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/config/ModemGatewayConfig.java	2015-01-17 07:41:26 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/config/ModemGatewayConfig.java	2015-12-14 10:17:29 +0000
@@ -44,7 +44,7 @@
     private String pin;
 
     private String simMemLocation;
-    
+
     private Integer pollingInterval;
 
     private boolean inbound;

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/config/SMSGatewayStatus.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/config/SMSGatewayStatus.java	2015-11-24 13:14:24 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/config/SMSGatewayStatus.java	2015-12-14 10:17:29 +0000
@@ -33,6 +33,6 @@
  */
 public enum SMSGatewayStatus
 {
-    STOPPED,STOPPING, STARTING, STARTED, UNDEFINED
+    STOPPED, STOPPING, STARTING, STARTED, UNDEFINED
 
 }

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/config/SmsConfigurable.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/config/SmsConfigurable.java	2015-10-07 14:40:33 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/config/SmsConfigurable.java	2015-12-14 10:17:29 +0000
@@ -36,8 +36,8 @@
 public interface SmsConfigurable
 {
     /**
-     * Initialize the service with the provided configuration. Services 
-     * implementing this interface are also expected to be able to reinitialize 
+     * Initialize the service with the provided configuration. Services
+     * implementing this interface are also expected to be able to reinitialize
      * based on these setting in a safe way when running.
      * 
      * @param smsConfiguration The SMS configuration

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/config/SmsConfiguration.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/config/SmsConfiguration.java	2015-10-07 14:40:33 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/config/SmsConfiguration.java	2015-12-14 10:17:29 +0000
@@ -97,7 +97,7 @@
     @XmlElements( { @XmlElement( name = "bulksms", type = BulkSmsGatewayConfig.class ),
         @XmlElement( name = "clickatell", type = ClickatellGatewayConfig.class ),
         @XmlElement( name = "http", type = GenericHttpGatewayConfig.class ),
-        @XmlElement( name = "modem", type = ModemGatewayConfig.class ) } )
+        @XmlElement( name = "modem", type = ModemGatewayConfig.class ) })
     public List<SmsGatewayConfig> getGateways()
     {
         return gateways;
@@ -117,17 +117,17 @@
     {
         this.pollingInterval = pollingInterval;
     }
-    
+
     public SmsGatewayConfig getDefaultGateway()
     {
         for ( SmsGatewayConfig gw : gateways )
-        {   
+        {
             if ( gw.isDefault() )
             {
                 return gw;
             }
         }
-        
+
         return null;
     }
 }

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/config/SmsConfigurationManager.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/config/SmsConfigurationManager.java	2015-11-24 13:14:24 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/config/SmsConfigurationManager.java	2015-12-14 10:17:29 +0000
@@ -36,14 +36,14 @@
     SmsConfiguration getSmsConfiguration();
 
     void updateSmsConfiguration( SmsConfiguration config );
-    
+
     SmsGatewayConfig checkInstanceOfGateway( Class<?> clazz );
-    
-    boolean setDefaultSMSGateway(String gatewayId);
-    
-    boolean gatewayExists (String gatewayId);
-    
-    boolean removeSMSGatewayById(String gatewayId);
-    
+
+    boolean setDefaultSMSGateway( String gatewayId );
+
+    boolean gatewayExists( String gatewayId );
+
+    boolean removeSMSGatewayById( String gatewayId );
+
     String addSMSGateway();
 }
\ No newline at end of file

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/incoming/IncomingSms.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/incoming/IncomingSms.java	2015-10-07 14:40:33 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/incoming/IncomingSms.java	2015-12-14 10:17:29 +0000
@@ -33,7 +33,7 @@
 
 public class IncomingSms
     implements Serializable
-{    
+{
     private static final long serialVersionUID = 3954710607630454226L;
 
     private Integer id;
@@ -61,7 +61,7 @@
     private SmsMessageStatus status = SmsMessageStatus.INCOMING;
 
     private String statusMessage;
-    
+
     private boolean parsed = false;
 
     /**
@@ -143,7 +143,7 @@
     {
         if ( bytes != null )
         {
-            throw new IllegalArgumentException("Text and bytes cannot both be set on incoming sms");
+            throw new IllegalArgumentException( "Text and bytes cannot both be set on incoming sms" );
         }
         this.text = text;
     }
@@ -157,7 +157,7 @@
     {
         if ( text != null )
         {
-            throw new IllegalArgumentException("Text and bytes cannot both be set on incoming sms");
+            throw new IllegalArgumentException( "Text and bytes cannot both be set on incoming sms" );
         }
         this.bytes = bytes;
     }

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/incoming/IncomingSmsListener.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/incoming/IncomingSmsListener.java	2015-10-07 14:40:33 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/incoming/IncomingSmsListener.java	2015-12-14 10:17:29 +0000
@@ -34,7 +34,7 @@
 {
     @Transactional
     boolean accept( IncomingSms sms );
-    
+
     @Transactional
     void receive( IncomingSms sms );
 }

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/incoming/IncomingSmsService.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/incoming/IncomingSmsService.java	2015-11-24 10:16:34 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/incoming/IncomingSmsService.java	2015-12-14 13:35:40 +0000
@@ -29,6 +29,7 @@
  */
 
 import java.util.List;
+import java.util.Date;
 
 import org.hisp.dhis.sms.MessageQueue;
 import org.smslib.InboundMessage;
@@ -61,9 +62,9 @@
 
     List<InboundMessage> getMsgList();
 
-    void save( IncomingSms sms );
+    int save( IncomingSms sms );
 
-    void save( String message, String originator, String gateway );
+    int save( String message, String originator, String gateway, Date receivedTime );
 
     void setIncomingSmsQueue( MessageQueue incomingSmsQueue );
 

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/incoming/IncomingSmsStore.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/incoming/IncomingSmsStore.java	2015-09-16 14:49:50 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/incoming/IncomingSmsStore.java	2015-12-14 10:17:29 +0000
@@ -30,21 +30,21 @@
 
 import java.util.List;
 
-/** 
+/**
  * Store for incoming SMS messages.
  */
 public interface IncomingSmsStore
 {
     String ID = IncomingSmsStore.class.getName();
-    
+
     int save( IncomingSms incomingSms );
-    
-    void update ( IncomingSms incomingSms );
+
+    void update( IncomingSms incomingSms );
 
     IncomingSms get( int id );
 
     List<IncomingSms> getSmsByStatus( SmsMessageStatus status, String keyword );
-    
+
     List<IncomingSms> getSmsByStatus( SmsMessageStatus status, String keyword, Integer min, Integer max );
 
     List<IncomingSms> getSmsByOriginator( String originator );
@@ -52,8 +52,8 @@
     long getSmsCount();
 
     List<IncomingSms> getAllSmses();
-    
-    void delete( IncomingSms incomingSms);
-    
+
+    void delete( IncomingSms incomingSms );
+
     List<IncomingSms> getAllUnparsedSmses();
 }

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/outbound/OutboundSms.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/outbound/OutboundSms.java	2015-10-07 14:40:33 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/outbound/OutboundSms.java	2015-12-14 10:17:29 +0000
@@ -35,13 +35,13 @@
 
 import org.hisp.dhis.common.BaseIdentifiableObject;
 
-public class OutboundSms 
+public class OutboundSms
     extends BaseIdentifiableObject
 {
     public static final String DHIS_SYSTEM_SENDER = "DHIS-System";
 
     private String sender;
-    
+
     private Set<String> recipients;
 
     private Date date;

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/outbound/OutboundSmsService.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/outbound/OutboundSmsService.java	2015-01-17 07:41:26 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/outbound/OutboundSmsService.java	2015-12-08 16:52:53 +0000
@@ -30,15 +30,12 @@
 
 import java.util.List;
 
-/**
- * OutboundSmsService provides support for sending SMSes.
- */
 public interface OutboundSmsService
 {
     String ID = OutboundSmsService.class.getName();
 
     List<OutboundSms> getAllOutboundSms();
-    
+
     List<OutboundSms> getAllOutboundSms( Integer min, Integer max );
 
     int saveOutboundSms( OutboundSms sms );
@@ -48,8 +45,8 @@
     void deleteById( Integer outboundSmsId );
 
     List<OutboundSms> getOutboundSms( OutboundSmsStatus status );
-    
+
     List<OutboundSms> getOutboundSms( OutboundSmsStatus status, Integer min, Integer max );
-    
+
     OutboundSms getOutboundSms( int id );
 }

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/outbound/OutboundSmsStore.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/outbound/OutboundSmsStore.java	2015-01-17 07:41:26 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/outbound/OutboundSmsStore.java	2015-12-08 16:52:53 +0000
@@ -33,18 +33,18 @@
 public interface OutboundSmsStore
 {
     int saveOutboundSms( OutboundSms sms );
-    
+
     List<OutboundSms> getAllOutboundSms();
-    
+
     List<OutboundSms> getAllOutboundSms( Integer min, Integer max );
 
     OutboundSms getOutboundSmsbyId( int id );
-    
+
     List<OutboundSms> get( OutboundSmsStatus status );
-    
+
     List<OutboundSms> get( OutboundSmsStatus status, Integer min, Integer max );
-    
+
     void updateOutboundSms( OutboundSms sms );
-    
+
     void deleteOutboundSms( OutboundSms sms );
 }

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/outbound/OutboundSmsTransportService.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/outbound/OutboundSmsTransportService.java	2015-11-24 13:14:24 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/outbound/OutboundSmsTransportService.java	2015-12-14 10:17:29 +0000
@@ -39,9 +39,9 @@
  * Marker interface for {@code OutboundSmsService outbound sms services}
  * providing actual SMS sending.
  */
-public interface OutboundSmsTransportService 
+public interface OutboundSmsTransportService
     extends SmsConfigurable
-{   
+{
     Map<String, String> getGatewayMap();
 
     void stopService();
@@ -56,9 +56,9 @@
     String getMessageStatus();
 
     String getDefaultGateway();
-    
+
     SMSServiceStatus getServiceStatusEnum();
-    
+
     SMSGatewayStatus getGatewayStatus();
 
     boolean isEnabled();

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/parse/ParserType.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/parse/ParserType.java	2015-01-17 07:41:26 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/parse/ParserType.java	2015-12-14 10:17:29 +0000
@@ -30,11 +30,5 @@
 
 public enum ParserType
 {
-    KEY_VALUE_PARSER,
-    J2ME_PARSER,
-    ALERT_PARSER,
-    UNREGISTERED_PARSER,
-    ANONYMOUS_PROGRAM_PARSER,
-    TRACKED_ENTITY_REGISTRATION_PARSER,
-    PROGRAM_STAGE_DATAENTRY_PARSER
+    KEY_VALUE_PARSER, J2ME_PARSER, ALERT_PARSER, UNREGISTERED_PARSER, ANONYMOUS_PROGRAM_PARSER, TRACKED_ENTITY_REGISTRATION_PARSER, PROGRAM_STAGE_DATAENTRY_PARSER
 }

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/message/DefaultMessageService.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/message/DefaultMessageService.java	2015-10-19 11:25:31 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/message/DefaultMessageService.java	2015-12-11 11:21:38 +0000
@@ -93,7 +93,7 @@
     }
 
     private EmailService emailService;
-    
+
     public void setEmailService( EmailService emailService )
     {
         this.emailService = emailService;
@@ -129,7 +129,7 @@
 
         log.info( "Found the following message senders: " + messageSenders );
     }
-    
+
     // -------------------------------------------------------------------------
     // MessageService implementation
     // -------------------------------------------------------------------------
@@ -141,8 +141,8 @@
     }
 
     @Override
-    public int sendMessage( String subject, String text, String metaData, Set<User> users_,
-        User sender, boolean includeFeedbackRecipients, boolean forceNotifications )
+    public int sendMessage( String subject, String text, String metaData, Set<User> users_, User sender,
+        boolean includeFeedbackRecipients, boolean forceNotifications )
     {
         Set<User> users = new HashSet<>( users_ );
 
@@ -163,7 +163,7 @@
         if ( sender == null )
         {
             sender = currentUserService.getCurrentUser();
-            
+
             if ( sender != null )
             {
                 users.add( sender );
@@ -205,12 +205,12 @@
     {
         return sendMessage( subject, text, metaData, new HashSet<User>(), null, true, false );
     }
-    
+
     @Override
     public int sendSystemNotification( String subject, String text )
     {
         emailService.sendSystemEmail( new Email( subject, text ) );
-        
+
         return sendFeedback( subject, text, null );
     }
 
@@ -225,7 +225,8 @@
 
         updateMessageConversation( conversation );
 
-        invokeMessageSenders( conversation.getSubject(), text, null, sender, new HashSet<>( conversation.getUsers() ), false );
+        invokeMessageSenders( conversation.getSubject(), text, null, sender, new HashSet<>( conversation.getUsers() ),
+            false );
     }
 
     @Override
@@ -273,8 +274,9 @@
         if ( !conversation.getUserMessages().isEmpty() )
         {
             int id = saveMessageConversation( conversation );
-            
-            invokeMessageSenders( COMPLETE_SUBJECT, text, null, sender, new HashSet<>( conversation.getUsers() ), false );
+
+            invokeMessageSenders( COMPLETE_SUBJECT, text, null, sender, new HashSet<>( conversation.getUsers() ),
+                false );
 
             return id;
         }
@@ -333,7 +335,8 @@
     @Override
     public List<MessageConversation> getMessageConversations()
     {
-        return messageConversationStore.getMessageConversations( currentUserService.getCurrentUser(), false, false, null, null );
+        return messageConversationStore.getMessageConversations( currentUserService.getCurrentUser(), false, false,
+            null, null );
     }
 
     @Override
@@ -354,7 +357,8 @@
     @Override
     public List<MessageConversation> getMessageConversations( User user, String[] messageConversationUids )
     {
-        List<MessageConversation> conversations = messageConversationStore.getMessageConversations( messageConversationUids );
+        List<MessageConversation> conversations = messageConversationStore
+            .getMessageConversations( messageConversationUids );
 
         // Set transient properties
 
@@ -370,7 +374,8 @@
     @Override
     public int getMessageConversationCount()
     {
-        return messageConversationStore.getMessageConversationCount( currentUserService.getCurrentUser(), false, false );
+        return messageConversationStore.getMessageConversationCount( currentUserService.getCurrentUser(), false,
+            false );
     }
 
     @Override
@@ -393,35 +398,40 @@
     {
         return messageConversationStore.getLastRecipients( currentUserService.getCurrentUser(), first, max );
     }
-    
+
     // -------------------------------------------------------------------------
     // Supportive methods
     // -------------------------------------------------------------------------
 
-    private void invokeMessageSenders( String subject, String text, String footer, User sender, Set<User> users, boolean forceSend )
+    private void invokeMessageSenders( String subject, String text, String footer, User sender, Set<User> users,
+        boolean forceSend )
     {
         for ( MessageSender messageSender : messageSenders )
         {
             log.debug( "Invoking message sender: " + messageSender.getClass().getSimpleName() );
-            
+
             messageSender.sendMessage( subject, text, footer, sender, new HashSet<>( users ), forceSend );
         }
     }
 
-    private String getMessageFooter( MessageConversation conversation ) {
+    private String getMessageFooter( MessageConversation conversation )
+    {
         HashMap<String, Object> values = new HashMap<>( 2 );
         String baseUrl = systemSettingManager.getInstanceBaseUrl();
 
         if ( baseUrl == null )
         {
-            return ""; // No base url is configured for this instance. Cannot create a reply link.
+            return ""; // No base url is configured for this instance. Cannot
+                       // create a reply link.
         }
 
-        values.put( "responseUrl", baseUrl + "/dhis-web-dashboard-integration/readMessage.action?id=" + conversation.getUid() );
+        values.put( "responseUrl",
+            baseUrl + "/dhis-web-dashboard-integration/readMessage.action?id=" + conversation.getUid() );
 
-        Locale locale = (Locale) userSettingService.getUserSetting( UserSettingService.KEY_UI_LOCALE, LocaleManager.DEFAULT_LOCALE, conversation.getUser() );
+        Locale locale = (Locale) userSettingService.getUserSetting( UserSettingService.KEY_UI_LOCALE,
+            LocaleManager.DEFAULT_LOCALE, conversation.getUser() );
         values.put( "i18n", i18nManager.getI18n( locale ) );
 
-        return new VelocityManager().render( values , MESSAGE_EMAIL_FOOTER_TEMPLATE );
+        return new VelocityManager().render( values, MESSAGE_EMAIL_FOOTER_TEMPLATE );
     }
 }

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/DatabaseSupportedInternalMemoryMessageQueue.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/DatabaseSupportedInternalMemoryMessageQueue.java	2015-10-07 14:40:33 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/DatabaseSupportedInternalMemoryMessageQueue.java	2015-12-14 13:35:40 +0000
@@ -34,6 +34,7 @@
 
 import org.hisp.dhis.sms.incoming.IncomingSms;
 import org.hisp.dhis.sms.incoming.IncomingSmsStore;
+import org.springframework.beans.factory.annotation.Autowired;
 
 public class DatabaseSupportedInternalMemoryMessageQueue
     implements MessageQueue
@@ -44,6 +45,7 @@
     // Dependencies
     // -------------------------------------------------------------------------
 
+    @Autowired
     private IncomingSmsStore smsStore;
 
     // -------------------------------------------------------------------------
@@ -63,7 +65,7 @@
         {
             return queue.get( 0 );
         }
-        
+
         return null;
     }
 
@@ -79,15 +81,10 @@
     public void initialize()
     {
         Collection<IncomingSms> messages = smsStore.getAllUnparsedSmses();
-        
+
         if ( messages != null )
         {
             queue.addAll( messages );
         }
     }
-
-    public void setSmsStore( IncomingSmsStore smsStore )
-    {
-        this.smsStore = smsStore;
-    }
 }

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/DefaultSmsSender.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/DefaultSmsSender.java	2015-10-07 14:40:33 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/DefaultSmsSender.java	2015-12-21 16:44:02 +0000
@@ -30,7 +30,6 @@
 
 import java.lang.Character.UnicodeBlock;
 import java.util.ArrayList;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
@@ -40,9 +39,9 @@
 import org.hisp.dhis.sms.outbound.OutboundSms;
 import org.hisp.dhis.sms.outbound.OutboundSmsService;
 import org.hisp.dhis.sms.outbound.OutboundSmsTransportService;
+import org.hisp.dhis.system.util.SmsUtils;
 import org.hisp.dhis.user.CurrentUserService;
 import org.hisp.dhis.user.User;
-import org.hisp.dhis.user.UserService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -57,27 +56,12 @@
     // Dependencies
     // -------------------------------------------------------------------------
 
+    @Autowired
     private CurrentUserService currentUserService;
 
-    public void setCurrentUserService( CurrentUserService currentUserService )
-    {
-        this.currentUserService = currentUserService;
-    }
-
-    private UserService userService;
-
-    public void setUserService( UserService userService )
-    {
-        this.userService = userService;
-    }
-
+    @Autowired
     private OutboundSmsService outboundSmsService;
 
-    public void setOutboundSmsService( OutboundSmsService outboundSmsService )
-    {
-        this.outboundSmsService = outboundSmsService;
-    }
-
     @Autowired
     private OutboundSmsTransportService transportService;
 
@@ -117,7 +101,7 @@
             throw new SmsServiceNotEnabledException();
         }
 
-        message = createMessage( null, message, currentUserService.getCurrentUser() );
+        message = SmsUtils.createMessage( null, message, currentUserService.getCurrentUser() );
         OutboundSms sms = new OutboundSms( message, phoneNumber );
         return sendMessage( sms );
     }
@@ -163,16 +147,17 @@
             }
 
             int maxChar = MAX_CHAR;
-            
+
             Set<String> phoneNumbers = null;
 
             if ( transportService != null && transportService.isEnabled() )
             {
-                phoneNumbers = getRecipientsPhoneNumber( toSendList );
-
-                text = createMessage( subject, text, sender );
-
-                // Bulk is limited in sending long SMS, need to cut into small pieces
+                phoneNumbers = SmsUtils.getRecipientsPhoneNumber( toSendList );
+
+                text = SmsUtils.createMessage( subject, text, sender );
+
+                // Bulk is limited in sending long SMS, need to cut into small
+                // pieces
                 if ( DefaultOutboundSmsTransportService.GATEWAY_MAP.get( "bulk_gw" ) != null
                     && DefaultOutboundSmsTransportService.GATEWAY_MAP.get( "bulk_gw" ).equals( gatewayId ) )
                 {
@@ -188,7 +173,7 @@
                     if ( text.length() > maxChar )
                     {
                         List<String> splitTextList = new ArrayList<>();
-                        splitTextList = splitLongUnicodeString( text, splitTextList );
+                        splitTextList = SmsUtils.splitLongUnicodeString( text, splitTextList );
                         for ( String each : splitTextList )
                         {
                             if ( !phoneNumbers.isEmpty() && phoneNumbers.size() > 0 )
@@ -222,47 +207,6 @@
     // Supportive methods
     // -------------------------------------------------------------------------
 
-    private String createMessage( String subject, String text, User sender )
-    {
-        String name = "DHIS";
-
-        if ( sender != null )
-        {
-            name = sender.getUsername();
-        }
-
-        if ( subject == null || subject.isEmpty() )
-        {
-            subject = "";
-        }
-        else
-        {
-            subject = " - " + subject;
-        }
-
-        text = name + subject + ": " + text;
-
-        int length = text.length(); // Simplistic cut off 160 characters
-
-        return (length > 160) ? text.substring( 0, 157 ) + "..." : text;
-    }
-
-    private Set<String> getRecipientsPhoneNumber( List<User> users )
-    {
-        Set<String> recipients = new HashSet<>();
-
-        for ( User user : users )
-        {
-            String phoneNumber = user.getPhoneNumber();
-
-            if ( phoneNumber != null && !phoneNumber.trim().isEmpty() )
-            {
-                recipients.add( phoneNumber );
-            }
-        }
-        return recipients;
-    }
-
     private String sendMessage( String text, Set<String> recipients, String gateWayId )
     {
         String message = null;
@@ -283,37 +227,10 @@
         return message;
     }
 
-    public List<String> splitLongUnicodeString( String message, List<String> result )
-    {
-        String firstTempString = null;
-        String secondTempString = null;
-        int indexToCut = 0;
-
-        firstTempString = message.substring( 0, MAX_CHAR );
-
-        indexToCut = firstTempString.lastIndexOf( " " );
-
-        firstTempString = firstTempString.substring( 0, indexToCut );
-
-        result.add( firstTempString );
-
-        secondTempString = message.substring( indexToCut + 1, message.length() );
-
-        if ( secondTempString.length() <= MAX_CHAR )
-        {
-            result.add( secondTempString );
-            return result;
-        }
-        else
-        {
-            return splitLongUnicodeString( secondTempString, result );
-        }
-    }
-
     public String isWastedSMS( OutboundSms sms )
     {
         List<OutboundSms> listOfRecentOutboundSms = outboundSmsService.getAllOutboundSms( 0, 10 );
-        
+
         for ( OutboundSms each : listOfRecentOutboundSms )
         {
             if ( each.getRecipients().equals( sms.getRecipients() )
@@ -322,17 +239,7 @@
                 return "system is trying to send out wasted SMS";
             }
         }
-        
+
         return null;
     }
-
-    public CurrentUserService getCurrentUserService()
-    {
-        return currentUserService;
-    }
-
-    public UserService getUserService()
-    {
-        return userService;
-    }
 }

=== added file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/SmsConsumerThread.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/SmsConsumerThread.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/SmsConsumerThread.java	2015-12-13 22:32:18 +0000
@@ -0,0 +1,72 @@
+package org.hisp.dhis.sms;
+
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hisp.dhis.sms.incoming.IncomingSms;
+import org.hisp.dhis.sms.incoming.IncomingSmsListener;
+import org.hisp.dhis.sms.incoming.SmsMessageStatus;
+import org.springframework.beans.factory.annotation.Autowired;
+
+public class SmsConsumerThread
+{
+    private static final Log log = LogFactory.getLog( SmsConsumerThread.class );
+
+    private List<IncomingSmsListener> listeners;
+
+    @Autowired
+    private MessageQueue messageQueue;
+
+    @Autowired
+    private SmsSender smsSender;
+
+    public SmsConsumerThread()
+    {
+    }
+
+    public void spawnSmsConsumer()
+    {
+        IncomingSms message = messageQueue.get();
+
+        while ( message != null )
+        {
+            log.info( "Received SMS: " + message.getText() );
+            try
+            {
+                for ( IncomingSmsListener listener : listeners )
+                {
+                    if ( listener.accept( message ) )
+                    {
+                        listener.receive( message );
+                        messageQueue.remove( message );
+                        return;
+                    }
+                }
+
+                smsSender.sendMessage( "No command found", message.getOriginator() );
+                message.setStatus( SmsMessageStatus.UNHANDLED );
+            }
+            catch ( Exception e )
+            {
+                log.error( e );
+                e.printStackTrace();
+                smsSender.sendMessage( e.getMessage(), message.getOriginator() );
+                message.setStatus( SmsMessageStatus.FAILED );
+            }
+            finally
+            {
+                messageQueue.remove( message );
+                message = messageQueue.get();
+            }
+        }
+    }
+
+    @Autowired
+    public void setListeners( List<IncomingSmsListener> listeners )
+    {
+        this.listeners = listeners;
+        log.info( "Listeners registered are " + listeners );
+    }
+
+}

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/SmsMessageSender.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/SmsMessageSender.java	2015-10-14 09:35:22 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/SmsMessageSender.java	2015-12-18 11:04:05 +0000
@@ -41,6 +41,7 @@
 import org.hisp.dhis.message.MessageSender;
 import org.hisp.dhis.sms.outbound.OutboundSms;
 import org.hisp.dhis.sms.outbound.OutboundSmsTransportService;
+import org.hisp.dhis.system.util.SmsUtils;
 import org.hisp.dhis.user.CurrentUserService;
 import org.hisp.dhis.user.User;
 import org.hisp.dhis.user.UserSettingService;
@@ -73,9 +74,9 @@
     @Autowired
     private OutboundSmsTransportService outboundSmsTransportService;
 
-    // @Async
     @Override
-    public String sendMessage( String subject, String text, String footer, User sender, Set<User> users, boolean forceSend )
+    public String sendMessage( String subject, String text, String footer, User sender, Set<User> users,
+        boolean forceSend )
     {
         String message = null;
 
@@ -83,11 +84,11 @@
         {
             return "No gateway";
         }
-        
+
         Map<String, String> gatewayMap = outboundSmsTransportService.getGatewayMap();
 
         String gatewayId = StringUtils.trimToNull( outboundSmsTransportService.getDefaultGateway() );
-        
+
         boolean gatewayEnabled = outboundSmsTransportService.isEnabled();
 
         if ( gatewayMap == null || gatewayId == null || !gatewayEnabled )
@@ -119,9 +120,9 @@
 
         Set<String> phoneNumbers = null;
 
-        phoneNumbers = getRecipientsPhoneNumber( toSendList );
+        phoneNumbers = SmsUtils.getRecipientsPhoneNumber( toSendList );
 
-        text = createMessage( subject, text, sender );
+        text = SmsUtils.createMessage( subject, text, sender );
 
         // Bulk is limited in sending long SMS, need to split in pieces
 
@@ -140,7 +141,7 @@
             if ( text.length() > MAX_CHAR )
             {
                 List<String> splitTextList = new ArrayList<>();
-                splitTextList = splitLongUnicodeString( text, splitTextList );
+                splitTextList = SmsUtils.splitLongUnicodeString( text, splitTextList );
 
                 for ( String each : splitTextList )
                 {
@@ -182,53 +183,13 @@
         else
         // Receiver is user
         {
-            Serializable userSetting = userSettingService.getUserSetting( UserSettingService.KEY_MESSAGE_SMS_NOTIFICATION, null, user );
+            Serializable userSetting = userSettingService
+                .getUserSetting( UserSettingService.KEY_MESSAGE_SMS_NOTIFICATION, null, user );
 
             return userSetting != null ? (Boolean) userSetting : false;
         }
     }
 
-    private String createMessage( String subject, String text, User sender )
-    {
-        String name = "DHIS";
-
-        if ( sender != null )
-        {
-            name = sender.getUsername();
-        }
-
-        if ( subject == null || subject.isEmpty() )
-        {
-            subject = "";
-        }
-        else
-        {
-            subject = " - " + subject;
-        }
-
-        text = name + subject + ": " + text;
-
-        int length = text.length(); // Simplistic cut off 160 characters
-
-        return (length > 160) ? text.substring( 0, 157 ) + "..." : text;
-    }
-
-    private Set<String> getRecipientsPhoneNumber( Set<User> users )
-    {
-        Set<String> recipients = new HashSet<>();
-
-        for ( User user : users )
-        {
-            String phoneNumber = user.getPhoneNumber();
-
-            if ( StringUtils.trimToNull( phoneNumber ) != null )
-            {
-                recipients.add( phoneNumber );
-            }
-        }
-        return recipients;
-    }
-
     private String sendMessage( String text, Set<String> recipients, String gateWayId )
     {
         String message = null;
@@ -250,32 +211,4 @@
 
         return message;
     }
-
-    public List<String> splitLongUnicodeString( String message, List<String> result )
-    {
-        String firstTempString = null;
-        String secondTempString = null;
-        int indexToCut = 0;
-
-        firstTempString = message.substring( 0, MAX_CHAR );
-
-        indexToCut = firstTempString.lastIndexOf( " " );
-
-        firstTempString = firstTempString.substring( 0, indexToCut );
-
-        result.add( firstTempString );
-
-        secondTempString = message.substring( indexToCut + 1, message.length() );
-
-        if ( secondTempString.length() <= MAX_CHAR )
-        {
-            result.add( secondTempString );
-
-            return result;
-        }
-        else
-        {
-            return splitLongUnicodeString( secondTempString, result );
-        }
-    }
 }

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/SmsPublisher.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/SmsPublisher.java	2015-10-07 14:40:33 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/SmsPublisher.java	2015-12-21 16:44:02 +0000
@@ -28,148 +28,54 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-import java.util.List;
-
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.hisp.dhis.sms.incoming.IncomingSms;
-import org.hisp.dhis.sms.incoming.IncomingSmsListener;
-import org.hisp.dhis.sms.incoming.SmsMessageStatus;
 import org.springframework.beans.factory.annotation.Autowired;
 
 public class SmsPublisher
 {
     private static final Log log = LogFactory.getLog( SmsPublisher.class );
 
-    private List<IncomingSmsListener> listeners;
-
+    @Autowired
     private MessageQueue messageQueue;
 
-    private SMSConsumerThread thread;
-
-    private SmsSender smsSender;
+    @Autowired
+    private SmsConsumerThread smsConsumer;
+
+    private Thread thread;
+
+    private boolean stop = false;
 
     public void start()
     {
         messageQueue.initialize();
 
-        if ( thread == null )
+        thread = new Thread()
         {
-            thread = new SMSConsumerThread();
-            thread.start();
-        }
+            public void run()
+            {
+                while ( !stop )
+                {
+                    smsConsumer.spawnSmsConsumer();
+                    
+                    try
+                    {
+                        Thread.sleep( 1000 );
+                    }
+                    catch ( Exception e )
+                    {
+                    }
+                }
+            }
+        };
+
+        thread.start();
+
+        log.info( "SMS Consumer Started" );
     }
 
     public void stop()
     {
-        if ( thread != null )
-        {
-            thread.stopFetching();
-        }
-
-        thread = null;
-    }
-
-    private class SMSConsumerThread
-        extends Thread
-    {
-        private boolean stop;
-
-        public SMSConsumerThread()
-        {
-        }
-
-        @Override
-        public void run()
-        {
-            while ( !stop )
-            {
-                try
-                {
-                    fetchAndParseSMS();
-                }
-                catch ( Exception ex )
-                {
-                    log.error( ex.getMessage() );
-                }
-
-                try
-                {
-                    Thread.sleep( 10000 );
-                }
-                catch ( InterruptedException e )
-                {
-                    e.printStackTrace();
-                }
-            }
-        }
-
-        private void fetchAndParseSMS()
-        {
-            IncomingSms message = messageQueue.get();
-            
-            while ( message != null )
-            {
-                log.info( "Received SMS: " + message.getText() );
-                try
-                {
-                    for ( IncomingSmsListener listener : listeners )
-                    {
-                        if ( listener.accept( message ) )
-                        {
-                            listener.receive( message );
-                            messageQueue.remove( message );
-                            return;
-                        }
-                    }
-                    
-                    smsSender.sendMessage( "No command found", message.getOriginator() );
-                    message.setStatus( SmsMessageStatus.UNHANDLED );
-                }
-                catch ( Exception e )
-                {
-                    log.error( e );
-                    e.printStackTrace();
-                    smsSender.sendMessage( e.getMessage(), message.getOriginator() );
-                    message.setStatus( SmsMessageStatus.FAILED );
-                }
-                finally
-                {
-                    messageQueue.remove( message );
-                    message = messageQueue.get();
-                }
-            }
-        }
-
-        public void stopFetching()
-        {
-            this.stop = true;
-        }
-    }
-
-    public void setMessageQueue( MessageQueue messageQueue )
-    {
-        this.messageQueue = messageQueue;
-    }
-
-    public List<IncomingSmsListener> getListeners()
-    {
-        return listeners;
-    }
-
-    @Autowired(required=false)
-    public void setListeners( List<IncomingSmsListener> listeners )
-    {
-        this.listeners = listeners;
-    }
-
-    public SmsSender getSmsSender()
-    {
-        return smsSender;
-    }
-
-    public void setSmsSender( SmsSender smsSender )
-    {
-        this.smsSender = smsSender;
+        this.stop = true;
     }
 }

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/command/DefaultSMSCommandService.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/command/DefaultSMSCommandService.java	2015-06-23 15:59:19 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/command/DefaultSMSCommandService.java	2015-12-14 10:17:29 +0000
@@ -75,7 +75,7 @@
     {
         return smsCommandStore.getSMSCommand( name );
     }
-    
+
     @Override
     public void save( Set<SMSCode> codes )
     {
@@ -109,18 +109,18 @@
     @Override
     public void deleteCodeSet( Set<SMSCode> codes )
     {
-        smsCommandStore.deleteCodeSet( codes );        
+        smsCommandStore.deleteCodeSet( codes );
     }
 
     @Override
     public int countDataSetSmsCommands( DataSet dataSet )
     {
-        return smsCommandStore.countDataSetSmsCommands(dataSet);
+        return smsCommandStore.countDataSetSmsCommands( dataSet );
     }
 
     @Override
     public void deleteSpecialCharacterSet( Set<SMSSpecialCharacter> specialCharacters )
     {
-        smsCommandStore.deleteSpecialCharacterSet( specialCharacters );        
+        smsCommandStore.deleteSpecialCharacterSet( specialCharacters );
     }
 }

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/command/SMSCommandDeletionHandler.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/command/SMSCommandDeletionHandler.java	2015-06-23 15:59:19 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/command/SMSCommandDeletionHandler.java	2015-12-14 10:17:29 +0000
@@ -35,7 +35,8 @@
 /**
  * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
  */
-public class SMSCommandDeletionHandler extends DeletionHandler
+public class SMSCommandDeletionHandler
+    extends DeletionHandler
 {
     @Autowired
     private SMSCommandService smsCommandService;

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/command/SMSCommandService.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/command/SMSCommandService.java	2015-06-23 15:59:19 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/command/SMSCommandService.java	2015-12-14 10:17:29 +0000
@@ -48,18 +48,18 @@
     void save( Set<SMSCode> codes );
 
     void delete( SMSCommand cmd );
-    
+
     List<SMSCommand> getJ2MESMSCommands();
-    
+
     SMSCommand getSMSCommand( String commandName, ParserType parserType );
-    
+
     void saveSpecialCharacterSet( Set<SMSSpecialCharacter> specialCharacters );
-    
+
     void deleteSpecialCharacterSet( Set<SMSSpecialCharacter> specialCharacters );
-    
+
     void deleteCodeSet( Set<SMSCode> codes );
 
     int countDataSetSmsCommands( DataSet dataSet );
-    
+
     SMSCommand getSMSCommand( String name );
 }

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/command/code/SMSCodesDeletionHandler.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/command/code/SMSCodesDeletionHandler.java	2015-06-23 15:59:19 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/command/code/SMSCodesDeletionHandler.java	2015-12-14 10:17:29 +0000
@@ -36,7 +36,8 @@
 /**
  * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
  */
-public class SMSCodesDeletionHandler extends DeletionHandler
+public class SMSCodesDeletionHandler
+    extends DeletionHandler
 {
     private JdbcTemplate jdbcTemplate;
 

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/command/hibernate/HibernateSMSCommandStore.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/command/hibernate/HibernateSMSCommandStore.java	2015-09-13 21:12:28 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/command/hibernate/HibernateSMSCommandStore.java	2015-12-10 17:19:22 +0000
@@ -56,7 +56,7 @@
         this.sessionFactory = sessionFactory;
     }
 
-    @SuppressWarnings("unchecked")
+    @SuppressWarnings( "unchecked" )
     @Override
     public List<SMSCommand> getSMSCommands()
     {
@@ -113,7 +113,7 @@
 
         return null;
     }
-    
+
     @Override
     @Transactional
     public void delete( SMSCommand cmd )
@@ -133,7 +133,7 @@
         session.delete( cmd );
     }
 
-    @SuppressWarnings("unchecked")
+    @SuppressWarnings( "unchecked" )
     @Override
     public List<SMSCommand> getJ2MESMSCommands()
     {
@@ -168,7 +168,6 @@
         }
     }
 
-
     @Override
     public void deleteCodeSet( Set<SMSCode> codes )
     {
@@ -185,8 +184,8 @@
     {
         Query query = getQuery( "select count(distinct c) from SMSCommand c where c.dataset=:dataSet", true );
         query.setEntity( "dataSet", dataSet );
-        //TODO rename dataset prop
-        
+        // TODO rename dataset prop
+
         return ((Long) query.uniqueResult()).intValue();
     }
 

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/command/hibernate/SMSCommandStore.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/command/hibernate/SMSCommandStore.java	2015-06-23 15:59:19 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/command/hibernate/SMSCommandStore.java	2015-12-14 10:17:29 +0000
@@ -48,15 +48,15 @@
     void delete( SMSCommand cmd );
 
     void save( Set<SMSCode> codes );
-    
+
     List<SMSCommand> getJ2MESMSCommands();
-    
+
     SMSCommand getSMSCommand( String commandName, ParserType parserType );
-    
+
     void saveSpecialCharacterSet( Set<SMSSpecialCharacter> specialCharacters );
-    
+
     void deleteSpecialCharacterSet( Set<SMSSpecialCharacter> specialCharacters );
-    
+
     void deleteCodeSet( Set<SMSCode> codes );
 
     int countDataSetSmsCommands( DataSet dataSet );

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/config/AdvanceHttpPostGateWay.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/config/AdvanceHttpPostGateWay.java	2015-10-07 14:40:33 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/config/AdvanceHttpPostGateWay.java	2015-12-14 10:17:29 +0000
@@ -51,7 +51,7 @@
     extends AGateway
 {
     private static final Log log = LogFactory.getLog( AdvanceHttpPostGateWay.class );
-    
+
     private static final String SENDER = "sender";
 
     private static final String RECIPIENT = "recipient";
@@ -74,22 +74,22 @@
         throws TimeoutException, GatewayException, IOException, InterruptedException
     {
         Map<String, String> requestParameters = new HashMap<>( parameters );
-        
+
         for ( OutboundMessage outboundMessage : outboundMessages )
         {
             requestParameters.put( RECIPIENT, outboundMessage.getRecipient() );
             requestParameters.put( MESSAGE, outboundMessage.getText() );
 
             String sender = outboundMessage.getFrom();
-            
+
             if ( sender != null )
             {
                 log.debug( "Adding sender " + sender + " " + getGatewayId() );
                 requestParameters.put( SENDER, sender );
             }
-            
+
             String urlString = urlTemplate;
-            
+
             for ( String key : requestParameters.keySet() )
             {
                 if ( requestParameters.get( key ) != null )
@@ -98,25 +98,25 @@
                         URLEncoder.encode( requestParameters.get( key ), "UTF-8" ) );
                 }
             }
-            
+
             log.info( "RequestURL: " + urlString + " " + getGatewayId() );
-                        
+
             String line, response = "";
             BufferedReader reader = null;
-            
+
             try
             {
-                URL requestURL = new URL( urlString );                
-                URLConnection conn = requestURL.openConnection();                
+                URL requestURL = new URL( urlString );
+                URLConnection conn = requestURL.openConnection();
                 reader = new BufferedReader( new InputStreamReader( conn.getInputStream() ) );
-                
+
                 while ( (line = reader.readLine()) != null )
                 {
                     response += line;
                 }
-                
+
                 HttpURLConnection httpConnection = (HttpURLConnection) conn;
-                
+
                 if ( httpConnection.getResponseCode() != HttpURLConnection.HTTP_OK )
                 {
                     log.warn( "Couldn't send message, got response " + response + " " + getGatewayId() );
@@ -135,7 +135,7 @@
 
             return 1;
         }
-        
+
         return super.sendMessages( outboundMessages );
     }
 

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/config/DefaultSmsConfigurationManager.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/config/DefaultSmsConfigurationManager.java	2015-12-08 19:33:06 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/config/DefaultSmsConfigurationManager.java	2015-12-14 10:17:29 +0000
@@ -121,7 +121,7 @@
             SmsConfiguration smsConfig = new SmsConfiguration( true );
             updateSmsConfiguration( smsConfig );
         }
-        
+
         for ( SmsGatewayConfig gateway : getSmsConfiguration().getGateways() )
         {
             if ( gateway.getClass().equals( clazz ) )
@@ -129,7 +129,7 @@
                 return gateway;
             }
         }
-        
+
         return null;
     }
 
@@ -137,15 +137,15 @@
     public boolean setDefaultSMSGateway( String gatewayId )
     {
         boolean result = false;
-        
+
         SmsConfiguration config = getSmsConfiguration();
-        
+
         if ( config == null )
         {
             return result;
         }
-        
-        List <SmsGatewayConfig> smsGatewayList = config.getGateways();
+
+        List<SmsGatewayConfig> smsGatewayList = config.getGateways();
 
         for ( SmsGatewayConfig gw : smsGatewayList )
         {
@@ -163,7 +163,7 @@
         }
 
         updateSmsConfiguration( config );
-        
+
         return result;
     }
 
@@ -172,7 +172,7 @@
     {
         SmsConfiguration config = getSmsConfiguration();
         List<SmsGatewayConfig> gatewayList = config.getGateways();
-        
+
         for ( SmsGatewayConfig gw : gatewayList )
         {
             if ( gw.getName().equals( gatewayId ) )
@@ -194,5 +194,5 @@
     public String addSMSGateway()
     {
         throw new NotImplementedException();
-    } 
+    }
 }

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/config/GateWayFactory.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/config/GateWayFactory.java	2015-10-07 14:40:33 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/config/GateWayFactory.java	2015-12-14 10:17:29 +0000
@@ -147,8 +147,8 @@
 
     public AGateway createSimplisticHttpGetGateway( GenericHttpGatewayConfig c )
     {
-        SimplisticHttpGetGateWay gateway = new SimplisticHttpGetGateWay( 
-            c.getName(), c.getUrlTemplate(), c.getParameters() );
+        SimplisticHttpGetGateWay gateway = new SimplisticHttpGetGateWay( c.getName(), c.getUrlTemplate(),
+            c.getParameters() );
         gateway.setOutbound( true );
         gateway.setInbound( false );
         return gateway;

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/config/SimplisticHttpGetGateWay.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/config/SimplisticHttpGetGateWay.java	2015-11-24 13:14:24 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/config/SimplisticHttpGetGateWay.java	2015-12-14 10:17:29 +0000
@@ -76,7 +76,7 @@
     extends AGateway
 {
     private static final Log log = LogFactory.getLog( SimplisticHttpGetGateWay.class );
-    
+
     private static final String SENDER = "sender";
 
     private static final String RECIPIENT = "recipient";
@@ -125,15 +125,15 @@
         requestParameters.put( MESSAGE, msg.getText() );
 
         String sender = msg.getFrom();
-        
+
         if ( sender != null )
         {
             log.debug( "Adding sender " + sender + " " + getGatewayId() );
             requestParameters.put( SENDER, sender );
         }
-        
+
         String urlString = urlTemplate;
-        
+
         for ( String key : requestParameters.keySet() )
         {
             if ( requestParameters.get( key ) != null )
@@ -142,25 +142,25 @@
                     URLEncoder.encode( requestParameters.get( key ), "UTF-8" ) );
             }
         }
-        
+
         log.info( "RequestURL: " + urlString + " " + getGatewayId() );
 
         String line, response = "";
         BufferedReader reader = null;
-        
+
         try
         {
             URL requestURL = new URL( urlString );
             URLConnection conn = requestURL.openConnection();
             reader = new BufferedReader( new InputStreamReader( conn.getInputStream() ) );
-            
+
             while ( (line = reader.readLine()) != null )
             {
                 response += line;
             }
 
             HttpURLConnection httpConnection = (HttpURLConnection) conn;
-            
+
             if ( httpConnection.getResponseCode() != HttpURLConnection.HTTP_OK )
             {
                 log.warn( "Couldn't send message, got response " + response + " " + getGatewayId() );

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/hibernate/HibernateIncomingSmsStore.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/hibernate/HibernateIncomingSmsStore.java	2015-10-07 14:40:33 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/hibernate/HibernateIncomingSmsStore.java	2015-12-14 10:17:29 +0000
@@ -63,7 +63,7 @@
     @Override
     public int save( IncomingSms sms )
     {
-        return (Integer) sessionFactory.getCurrentSession().save( sms );        
+        return (Integer) sessionFactory.getCurrentSession().save( sms );
     }
 
     @Override
@@ -105,7 +105,7 @@
     }
 
     @Override
-    public long getSmsCount()    
+    public long getSmsCount()
     {
         Session session = sessionFactory.getCurrentSession();
         Criteria criteria = session.createCriteria( IncomingSms.class );
@@ -141,18 +141,18 @@
     {
         Session session = sessionFactory.getCurrentSession();
         Criteria criteria = session.createCriteria( IncomingSms.class ).addOrder( Order.desc( "sentDate" ) );
-        
+
         if ( status != null )
         {
             criteria.add( Restrictions.eq( "status", status ) );
         }
         criteria.add( Restrictions.ilike( "originator", "%" + keyword + "%" ) );
-        
+
         if ( min != null && max != null )
         {
             criteria.setFirstResult( min ).setMaxResults( max );
         }
-        
+
         return criteria.list();
     }
 }

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/hibernate/HibernateOutboundSmsStore.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/hibernate/HibernateOutboundSmsStore.java	2015-01-17 07:41:26 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/hibernate/HibernateOutboundSmsStore.java	2015-12-14 10:17:29 +0000
@@ -85,9 +85,9 @@
     public List<OutboundSms> get( OutboundSmsStatus status )
     {
         Session session = sessionFactory.getCurrentSession();
-        
+
         Criteria criteria = session.createCriteria( OutboundSms.class ).addOrder( Order.desc( "date" ) );
-        
+
         if ( status != null )
         {
             criteria.add( Restrictions.eq( "status", status ) );
@@ -112,15 +112,15 @@
     public List<OutboundSms> get( OutboundSmsStatus status, Integer min, Integer max )
     {
         Session session = sessionFactory.getCurrentSession();
-        
+
         Criteria criteria = session.createCriteria( OutboundSms.class ).addOrder( Order.desc( "date" ) );
-        
+
         if ( status != null )
         {
             criteria.add( Restrictions.eq( "status", status ) );
         }
-        
-        if ( min != null && max != null)
+
+        if ( min != null && max != null )
         {
             criteria.setFirstResult( min ).setMaxResults( max );
         }
@@ -132,10 +132,10 @@
     public List<OutboundSms> getAllOutboundSms( Integer min, Integer max )
     {
         Session session = sessionFactory.getCurrentSession();
-        
+
         Criteria criteria = session.createCriteria( OutboundSms.class ).addOrder( Order.desc( "date" ) );
-        
-        if ( min != null && max != null)
+
+        if ( min != null && max != null )
         {
             criteria.setFirstResult( min ).setMaxResults( max );
         }

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/incoming/DefaultIncomingSmsService.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/incoming/DefaultIncomingSmsService.java	2015-11-24 13:14:24 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/incoming/DefaultIncomingSmsService.java	2015-12-21 16:44:02 +0000
@@ -52,7 +52,6 @@
 
     private MessageQueue incomingSmsQueue;
 
-    @Override
     public void setIncomingSmsQueue( MessageQueue incomingSmsQueue )
     {
         this.incomingSmsQueue = incomingSmsQueue;
@@ -124,25 +123,35 @@
     }
 
     @Override
-    public void save( IncomingSms incomingSms )
+    public int save( IncomingSms incomingSms )
     {
-        incomingSmsStore.save( incomingSms );
+        int smsId = incomingSmsStore.save( incomingSms );
         incomingSmsQueue.put( incomingSms );
+        return smsId;
     }
 
     @Override
-    public void save( String message, String originator, String gateway )
+    public int save( String message, String originator, String gateway, Date receivedTime )
     {
+
         IncomingSms sms = new IncomingSms();
         sms.setText( message );
         sms.setOriginator( originator );
         sms.setGatewayId( gateway );
-        sms.setSentDate( new Date() );
+
+        if ( receivedTime != null )
+        {
+            sms.setSentDate( receivedTime );
+        }
+        else
+        {
+            sms.setSentDate( new Date() );
+
+        }
         sms.setReceivedDate( new Date() );
         sms.setEncoding( SmsMessageEncoding.ENC7BIT );
         sms.setStatus( SmsMessageStatus.INCOMING );
-        save( sms );
-
+        return save( sms );
     }
 
     @Override
@@ -201,7 +210,6 @@
     public IncomingSms convertToIncomingSms( InboundMessage message )
     {
         IncomingSms incomingSms = new IncomingSms();
-
         incomingSms.setOriginator( message.getOriginator() );
         incomingSms.setEncoding( SmsMessageEncoding.ENC7BIT );
         incomingSms.setSentDate( message.getDate() );
@@ -210,7 +218,6 @@
         incomingSms.setGatewayId( message.getGatewayId() );
         incomingSms.setStatus( SmsMessageStatus.PROCESSED );
         incomingSms.setStatusMessage( "imported" );
-
         return incomingSms;
     }
 

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/incoming/SMPPInboundNotification.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/incoming/SMPPInboundNotification.java	2015-01-17 07:41:26 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/incoming/SMPPInboundNotification.java	2015-12-14 13:35:40 +0000
@@ -32,21 +32,18 @@
 import org.smslib.IInboundMessageNotification;
 import org.smslib.InboundMessage;
 import org.smslib.Message.MessageTypes;
+import org.springframework.beans.factory.annotation.Autowired;
 
 public class SMPPInboundNotification
     implements IInboundMessageNotification
-{    
+{
     // -------------------------------------------------------------------------
     // Dependencies
     // -------------------------------------------------------------------------
 
+    @Autowired
     private IncomingSmsService incomingSmsService;
 
-    public void setIncomingSmsService( IncomingSmsService incomingSmsService )
-    {
-        this.incomingSmsService = incomingSmsService;
-    }
-
     // -------------------------------------------------------------------------
     // Implementation
     // -------------------------------------------------------------------------
@@ -55,7 +52,7 @@
     public void process( AGateway gateway, MessageTypes msgType, InboundMessage message )
     {
         IncomingSms incomingSms = incomingSmsService.convertToIncomingSms( message );
-        
+
         incomingSmsService.save( incomingSms );
     }
 }

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/listener/DHISMessageAlertListener.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/listener/DHISMessageAlertListener.java	2015-11-23 16:24:04 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/listener/DHISMessageAlertListener.java	2015-12-11 11:21:38 +0000
@@ -44,68 +44,41 @@
 import org.hisp.dhis.sms.incoming.SmsMessageStatus;
 import org.hisp.dhis.sms.parse.ParserType;
 import org.hisp.dhis.sms.parse.SMSParserException;
+import org.hisp.dhis.system.util.SmsUtils;
 import org.hisp.dhis.user.User;
 import org.hisp.dhis.user.UserGroup;
 import org.hisp.dhis.user.UserService;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
 
 public class DHISMessageAlertListener
     implements IncomingSmsListener
 {
+
+    // -------------------------------------------------------------------------
+    // Dependencies
+    // -------------------------------------------------------------------------
+
+    @Autowired
     private SMSCommandService smsCommandService;
 
-    public void setSmsCommandService( SMSCommandService smsCommandService )
-    {
-        this.smsCommandService = smsCommandService;
-    }
-
+    @Autowired
     private UserService userService;
 
-    public void setUserService( UserService userService )
-    {
-        this.userService = userService;
-    }
-
+    @Autowired
     private MessageService messageService;
 
-    public void setMessageService( MessageService messageService )
-    {
-        this.messageService = messageService;
-    }
-
+    @Autowired
     private SmsMessageSender smsMessageSender;
 
-    public void setSmsMessageSender( SmsMessageSender smsMessageSender )
-    {
-        this.smsMessageSender = smsMessageSender;
-    }
-    
+    @Autowired
     private IncomingSmsService incomingSmsService;
 
-    public void setIncomingSmsService( IncomingSmsService incomingSmsService )
-    {
-        this.incomingSmsService = incomingSmsService;
-    }
-
     @Transactional
     @Override
     public boolean accept( IncomingSms sms )
     {
-        String message = sms.getText();
-        String commandString = null;
-
-        for ( int i = 0; i < message.length(); i++ )
-        {
-            String c = String.valueOf( message.charAt( i ) );
-            if ( c.matches( "\\W" ) )
-            {
-                commandString = message.substring( 0, i );
-                message = message.substring( commandString.length() + 1 );
-                break;
-            }
-        }
-
-        return smsCommandService.getSMSCommand( commandString, ParserType.ALERT_PARSER ) != null;
+        return smsCommandService.getSMSCommand( SmsUtils.getCommandString( sms ), ParserType.ALERT_PARSER ) != null;
     }
 
     @Transactional
@@ -113,20 +86,8 @@
     public void receive( IncomingSms sms )
     {
         String message = sms.getText();
-        String commandString = null;
-
-        for ( int i = 0; i < message.length(); i++ )
-        {
-            String c = String.valueOf( message.charAt( i ) );
-            if ( c.matches( "\\W" ) )
-            {
-                commandString = message.substring( 0, i );
-                message = message.substring( commandString.length() + 1 );
-                break;
-            }
-        }
-
-        SMSCommand smsCommand = smsCommandService.getSMSCommand( commandString, ParserType.ALERT_PARSER );
+        SMSCommand smsCommand = smsCommandService.getSMSCommand( SmsUtils.getCommandString( sms ),
+            ParserType.ALERT_PARSER );
         UserGroup userGroup = smsCommand.getUserGroup();
         String senderPhoneNumber = StringUtils.replace( sms.getOriginator(), "+", "" );
 
@@ -157,11 +118,8 @@
                 User sender = users.iterator().next();
 
                 Set<User> receivers = new HashSet<>( userGroup.getMembers() );
-
-                // forward to user group by SMS,Dhis2 message, Email
                 messageService.sendMessage( smsCommand.getName(), message, null, receivers, sender, false, false );
 
-                // confirm SMS was received and forwarded completely
                 Set<User> feedbackList = new HashSet<>();
                 feedbackList.add( sender );
 
@@ -185,4 +143,4 @@
             }
         }
     }
-}
+}
\ No newline at end of file

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/listener/DataValueSMSListener.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/listener/DataValueSMSListener.java	2015-10-07 14:40:33 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/listener/DataValueSMSListener.java	2015-12-11 11:21:38 +0000
@@ -30,7 +30,6 @@
 
 import org.apache.commons.lang3.StringUtils;
 import org.hisp.dhis.common.ValueType;
-import org.hisp.dhis.commons.util.TextUtils;
 import org.hisp.dhis.dataelement.DataElement;
 import org.hisp.dhis.dataelement.DataElementCategoryOptionCombo;
 import org.hisp.dhis.dataelement.DataElementCategoryService;
@@ -55,18 +54,16 @@
 import org.hisp.dhis.sms.incoming.SmsMessageStatus;
 import org.hisp.dhis.sms.parse.ParserType;
 import org.hisp.dhis.sms.parse.SMSParserException;
-import org.hisp.dhis.user.User;
+import org.hisp.dhis.system.util.SmsUtils;
 import org.hisp.dhis.user.UserService;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.text.SimpleDateFormat;
 import java.util.ArrayList;
-import java.util.Calendar;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Date;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -79,69 +76,37 @@
 {
     private static final String defaultPattern = "([a-zA-Z]+)\\s*(\\d+)";
 
+    // -------------------------------------------------------------------------
+    // Dependencies
+    // -------------------------------------------------------------------------
+
+    @Autowired
     private CompleteDataSetRegistrationService registrationService;
 
-    public void setRegistrationService( CompleteDataSetRegistrationService registrationService )
-    {
-        this.registrationService = registrationService;
-    }
-
+    @Autowired
     private DataValueService dataValueService;
 
-    public void setDataValueService( DataValueService dataValueService )
-    {
-        this.dataValueService = dataValueService;
-    }
-
+    @Autowired
     private SmsSender smsSender;
 
-    public void setSmsSender( SmsSender smsSender )
-    {
-        this.smsSender = smsSender;
-    }
-
+    @Autowired
     private DataElementCategoryService dataElementCategoryService;
 
-    public void setDataElementCategoryService( DataElementCategoryService dataElementCategoryService )
-    {
-        this.dataElementCategoryService = dataElementCategoryService;
-    }
-
+    @Autowired
     private SMSCommandService smsCommandService;
 
-    public void setSmsCommandService( SMSCommandService smsCommandService )
-    {
-        this.smsCommandService = smsCommandService;
-    }
-
+    @Autowired
     private UserService userService;
 
-    public void setUserService( UserService userService )
-    {
-        this.userService = userService;
-    }
-
+    @Autowired
     private DataSetService dataSetService;
 
-    public void setDataSetService( DataSetService dataSetService )
-    {
-        this.dataSetService = dataSetService;
-    }
-
+    @Autowired
     private IncomingSmsService incomingSmsService;
 
-    public void setIncomingSmsService( IncomingSmsService incomingSmsService )
-    {
-        this.incomingSmsService = incomingSmsService;
-    }
-
+    @Autowired
     private DataElementService dataElementService;
 
-    public void setDataElementService( DataElementService dataElementService )
-    {
-        this.dataElementService = dataElementService;
-    }
-
     // -------------------------------------------------------------------------
     // IncomingSmsListener implementation
     // -------------------------------------------------------------------------
@@ -150,22 +115,7 @@
     @Override
     public boolean accept( IncomingSms sms )
     {
-        String message = sms.getText();
-        String commandString = null;
-
-        for ( int i = 0; i < message.length(); i++ )
-        {
-            String c = String.valueOf( message.charAt( i ) );
-            
-            if ( c.matches( "\\W" ) )
-            {
-                commandString = message.substring( 0, i );
-                message = message.substring( commandString.length() + 1 );
-                break;
-            }
-        }
-
-        return smsCommandService.getSMSCommand( commandString, ParserType.KEY_VALUE_PARSER ) != null;
+        return smsCommandService.getSMSCommand( SmsUtils.getCommandString( sms ), ParserType.KEY_VALUE_PARSER ) != null;
     }
 
     @Transactional
@@ -173,25 +123,14 @@
     public void receive( IncomingSms sms )
     {
         String message = sms.getText();
-        String commandString = null;
-
-        for ( int i = 0; i < message.length(); i++ )
-        {
-            String c = String.valueOf( message.charAt( i ) );
-            if ( c.matches( "\\W" ) )
-            {
-                commandString = message.substring( 0, i );
-                message = message.substring( commandString.length() + 1 );
-                break;
-            }
-        }
-
-        SMSCommand smsCommand = smsCommandService.getSMSCommand( commandString, ParserType.KEY_VALUE_PARSER );
+        SMSCommand smsCommand = smsCommandService.getSMSCommand( SmsUtils.getCommandString( sms ),
+            ParserType.KEY_VALUE_PARSER );
         Map<String, String> parsedMessage = this.parse( message, smsCommand );
 
-        Date date = lookForDate( message );
+        Date date = SmsUtils.lookForDate( message );
         String senderPhoneNumber = StringUtils.replace( sms.getOriginator(), "+", "" );
-        Collection<OrganisationUnit> orgUnits = getOrganisationUnitsByPhoneNumber( senderPhoneNumber );
+        Collection<OrganisationUnit> orgUnits = SmsUtils.getOrganisationUnitsByPhoneNumber( senderPhoneNumber,
+            userService.getUsersByPhoneNumber( senderPhoneNumber ) );
 
         if ( orgUnits == null || orgUnits.size() == 0 )
         {
@@ -205,13 +144,13 @@
             }
         }
 
-        OrganisationUnit orgUnit = this.selectOrganisationUnit( orgUnits, parsedMessage, smsCommand );
+        OrganisationUnit orgUnit = SmsUtils.selectOrganisationUnit( orgUnits, parsedMessage, smsCommand );
         Period period = getPeriod( smsCommand, date );
 
         if ( dataSetService.isLocked( smsCommand.getDataset(), period, orgUnit, null, null ) )
         {
-            throw new SMSParserException( "Dataset is locked for the period " + period.getStartDate() + " - "
-                + period.getEndDate() );
+            throw new SMSParserException(
+                "Dataset is locked for the period " + period.getStartDate() + " - " + period.getEndDate() );
         }
 
         boolean valueStored = false;
@@ -263,13 +202,12 @@
 
         if ( !StringUtils.isBlank( smsCommand.getSeparator() ) )
         {
-            String x = "([^\\s|" + smsCommand.getSeparator().trim() + "]+)\\s*\\" + smsCommand.getSeparator().trim() + "\\s*([\\w ]+)\\s*(\\"
-                + smsCommand.getSeparator().trim() + "|$)*\\s*";
+            String x = "([^\\s|" + smsCommand.getSeparator().trim() + "]+)\\s*\\" + smsCommand.getSeparator().trim()
+                + "\\s*([\\w ]+)\\s*(\\" + smsCommand.getSeparator().trim() + "|$)*\\s*";
             pattern = Pattern.compile( x );
         }
 
         Matcher matcher = pattern.matcher( sms );
-
         while ( matcher.find() )
         {
             String key = matcher.group( 1 );
@@ -284,98 +222,6 @@
         return output;
     }
 
-    private Date lookForDate( String message )
-    {
-        if ( !message.contains( " " ) )
-        {
-            return null;
-        }
-
-        Date date = null;
-        String dateString = message.trim().split( " " )[0];
-        SimpleDateFormat format = new SimpleDateFormat( "ddMM" );
-
-        try
-        {
-            Calendar cal = Calendar.getInstance();
-            date = format.parse( dateString );
-            cal.setTime( date );
-            int year = Calendar.getInstance().get( Calendar.YEAR );
-            int month = Calendar.getInstance().get( Calendar.MONTH );
-            
-            if ( cal.get( Calendar.MONTH ) < month )
-            {
-                cal.set( Calendar.YEAR, year );
-            }
-            else
-            {
-                cal.set( Calendar.YEAR, year - 1 );
-            }
-            
-            date = cal.getTime();
-        }
-        catch ( Exception e )
-        {
-            // no date found
-        }
-
-        return date;
-    }
-
-    private Collection<OrganisationUnit> getOrganisationUnitsByPhoneNumber( String sender )
-    {
-        Collection<OrganisationUnit> orgUnits = new ArrayList<>();
-        Collection<User> users = userService.getUsersByPhoneNumber( sender );
-        for ( User u : users )
-        {
-            if ( u.getOrganisationUnits() != null )
-            {
-                orgUnits.addAll( u.getOrganisationUnits() );
-            }
-        }
-
-        return orgUnits;
-    }
-
-    private OrganisationUnit selectOrganisationUnit( Collection<OrganisationUnit> orgUnits,
-        Map<String, String> parsedMessage, SMSCommand smsCommand )
-    {
-        OrganisationUnit orgUnit = null;
-
-        for ( OrganisationUnit o : orgUnits )
-        {
-            if ( orgUnits.size() == 1 )
-            {
-                orgUnit = o;
-            }
-            if ( parsedMessage.containsKey( "ORG" ) && o.getCode().equals( parsedMessage.get( "ORG" ) ) )
-            {
-                orgUnit = o;
-                break;
-            }
-        }
-
-        if ( orgUnit == null && orgUnits.size() > 1 )
-        {
-            String messageListingOrgUnits = smsCommand.getMoreThanOneOrgUnitMessage();
-
-            for ( Iterator<OrganisationUnit> i = orgUnits.iterator(); i.hasNext(); )
-            {
-                OrganisationUnit o = i.next();
-                messageListingOrgUnits += TextUtils.SPACE + o.getName() + ":" + o.getCode();
-
-                if ( i.hasNext() )
-                {
-                    messageListingOrgUnits += ",";
-                }
-            }
-
-            throw new SMSParserException( messageListingOrgUnits );
-        }
-
-        return orgUnit;
-    }
-
     private Period getPeriod( SMSCommand command, Date date )
     {
         Period period = null;
@@ -404,15 +250,16 @@
     {
         String upperCaseCode = code.getCode().toUpperCase();
 
-        String storedBy = getUser( sender, command ).getUsername();
+        String storedBy = SmsUtils.getUser( sender, command, userService.getUsersByPhoneNumber( sender ) )
+            .getUsername();
 
         if ( StringUtils.isBlank( storedBy ) )
         {
             storedBy = "[unknown] from [" + sender + "]";
         }
 
-        DataElementCategoryOptionCombo optionCombo = dataElementCategoryService.getDataElementCategoryOptionCombo( code
-            .getOptionId() );
+        DataElementCategoryOptionCombo optionCombo = dataElementCategoryService
+            .getDataElementCategoryOptionCombo( code.getOptionId() );
 
         Period period = getPeriod( command, date );
 
@@ -434,7 +281,7 @@
         if ( !StringUtils.isEmpty( value ) )
         {
             boolean newDataValue = false;
-            
+
             if ( dv == null )
             {
                 dv = new DataValue();
@@ -492,8 +339,8 @@
                 String targetDataElementId = formula.substring( 1, formula.length() );
                 String operation = String.valueOf( formula.charAt( 0 ) );
 
-                DataElement targetDataElement = dataElementService.getDataElement( Integer
-                    .parseInt( targetDataElementId ) );
+                DataElement targetDataElement = dataElementService
+                    .getDataElement( Integer.parseInt( targetDataElementId ) );
 
                 if ( targetDataElement == null )
                 {
@@ -509,8 +356,8 @@
                 if ( targetDataValue == null )
                 {
                     targetDataValue = new DataValue();
-                    targetDataValue.setCategoryOptionCombo( dataElementCategoryService
-                        .getDefaultDataElementCategoryOptionCombo() );
+                    targetDataValue.setCategoryOptionCombo(
+                        dataElementCategoryService.getDefaultDataElementCategoryOptionCombo() );
                     targetDataValue.setSource( orgunit );
                     targetDataValue.setDataElement( targetDataElement );
                     targetDataValue.setPeriod( period );
@@ -531,7 +378,6 @@
                     targetValue = targetValue - Integer.parseInt( value );
                 }
 
-
                 targetDataValue.setValue( String.valueOf( targetValue ) );
                 targetDataValue.setLastUpdated( new java.util.Date() );
                 targetDataValue.setStoredBy( storedBy );
@@ -556,51 +402,6 @@
         return true;
     }
 
-    private User getUser( String sender, SMSCommand smsCommand )
-    {
-        OrganisationUnit orgunit = null;
-        User user = null;
-
-        // Need to be edited
-        for ( User u : userService.getUsersByPhoneNumber( sender ) )
-        {
-            OrganisationUnit ou = u.getOrganisationUnit();
-
-            if ( ou != null )
-            {
-                // Might be undefined if the user has more than one org units
-                if ( orgunit == null )
-                {
-                    orgunit = ou;
-                }
-                else if ( orgunit.getId() == ou.getId() )
-                {
-                    // Same org unit
-                }
-                else
-                {
-                    if ( StringUtils.isEmpty( smsCommand.getMoreThanOneOrgUnitMessage() ) )
-                    {
-                        throw new SMSParserException( SMSCommand.MORE_THAN_ONE_ORGUNIT_MESSAGE );
-                    }
-                    else
-                    {
-                        throw new SMSParserException( smsCommand.getMoreThanOneOrgUnitMessage() );
-                    }
-                }
-            }
-
-            user = u;
-        }
-
-        if ( user == null )
-        {
-            throw new SMSParserException( "User is not associated with any orgunit. Please contact your supervisor." );
-        }
-
-        return user;
-    }
-
     private void markCompleteDataSet( String sender, OrganisationUnit orgunit, Map<String, String> parsedMessage,
         SMSCommand command, Date date )
     {
@@ -643,7 +444,8 @@
         }
 
         // Go through the complete process
-        String storedBy = getUser( sender, command ).getUsername();
+        String storedBy = SmsUtils.getUser( sender, command, userService.getUsersByPhoneNumber( sender ) )
+            .getUsername();
 
         if ( StringUtils.isBlank( storedBy ) )
         {
@@ -655,8 +457,8 @@
         registerCompleteDataSet( command.getDataset(), period, orgunit, storedBy );
     }
 
-    protected void sendSuccessFeedback( String sender, SMSCommand command, Map<String, String> parsedMessage,
-        Date date, OrganisationUnit orgunit )
+    protected void sendSuccessFeedback( String sender, SMSCommand command, Map<String, String> parsedMessage, Date date,
+        OrganisationUnit orgunit )
     {
         String reportBack = "Thank you! Values entered: ";
         String notInReport = "Missing values for: ";
@@ -732,7 +534,8 @@
         DataElementCategoryOptionCombo optionCombo = dataElementCategoryService
             .getDefaultDataElementCategoryOptionCombo(); // TODO
 
-        if ( registrationService.getCompleteDataSetRegistration( dataSet, period, organisationUnit, optionCombo ) == null )
+        if ( registrationService.getCompleteDataSetRegistration( dataSet, period, organisationUnit,
+            optionCombo ) == null )
         {
             registration.setDataSet( dataSet );
             registration.setPeriod( period );
@@ -757,4 +560,4 @@
             registrationService.deleteCompleteDataSetRegistration( registration );
         }
     }
-}
+}
\ No newline at end of file

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/listener/J2MEDataValueSMSListener.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/listener/J2MEDataValueSMSListener.java	2015-10-07 14:40:33 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/listener/J2MEDataValueSMSListener.java	2015-12-11 11:21:38 +0000
@@ -30,7 +30,6 @@
 
 import org.apache.commons.lang3.StringUtils;
 import org.hisp.dhis.common.ValueType;
-import org.hisp.dhis.commons.util.TextUtils;
 import org.hisp.dhis.dataelement.DataElementCategoryOptionCombo;
 import org.hisp.dhis.dataelement.DataElementCategoryService;
 import org.hisp.dhis.dataset.CompleteDataSetRegistration;
@@ -54,67 +53,47 @@
 import org.hisp.dhis.sms.incoming.IncomingSmsListener;
 import org.hisp.dhis.sms.parse.ParserType;
 import org.hisp.dhis.sms.parse.SMSParserException;
+import org.hisp.dhis.system.util.SmsUtils;
 import org.hisp.dhis.system.util.ValidationUtils;
-import org.hisp.dhis.user.User;
 import org.hisp.dhis.user.UserService;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
-import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.Collection;
 import java.util.Date;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.Map;
 import java.util.regex.Pattern;
 
 public class J2MEDataValueSMSListener
     implements IncomingSmsListener
 {
+
+    // -------------------------------------------------------------------------
+    // Dependencies
+    // -------------------------------------------------------------------------
+
+    @Autowired
     private DataValueService dataValueService;
 
-    public void setDataValueService( DataValueService dataValueService )
-    {
-        this.dataValueService = dataValueService;
-    }
-
+    @Autowired
     private DataElementCategoryService dataElementCategoryService;
 
-    public void setDataElementCategoryService( DataElementCategoryService dataElementCategoryService )
-    {
-        this.dataElementCategoryService = dataElementCategoryService;
-    }
-
+    @Autowired
     private SMSCommandService smsCommandService;
 
-    public void setSmsCommandService( SMSCommandService smsCommandService )
-    {
-        this.smsCommandService = smsCommandService;
-    }
-
+    @Autowired
     private UserService userService;
 
-    public void setUserService( UserService userService )
-    {
-        this.userService = userService;
-    }
-
+    @Autowired
     private CompleteDataSetRegistrationService registrationService;
 
-    public void setRegistrationService( CompleteDataSetRegistrationService registrationService )
-    {
-        this.registrationService = registrationService;
-    }
-
+    @Autowired
     private SmsSender smsSender;
 
-    public void setSmsSender( SmsSender smsSender )
-    {
-        this.smsSender = smsSender;
-    }
-
     // -------------------------------------------------------------------------
     // IncomingSmsListener implementation
     // -------------------------------------------------------------------------
@@ -123,20 +102,7 @@
     @Override
     public boolean accept( IncomingSms sms )
     {
-        String message = sms.getText();
-        String commandString = null;
-
-        if ( message.indexOf( TextUtils.SPACE ) > 0 )
-        {
-            commandString = message.substring( 0, message.indexOf( " " ) );
-            message = message.substring( commandString.length() );
-        }
-        else
-        {
-            commandString = message;
-        }
-
-        return smsCommandService.getSMSCommand( commandString, ParserType.J2ME_PARSER ) != null;
+        return smsCommandService.getSMSCommand( SmsUtils.getCommandString( sms ), ParserType.J2ME_PARSER ) != null;
     }
 
     @Transactional
@@ -144,22 +110,16 @@
     public void receive( IncomingSms sms )
     {
         String message = sms.getText();
-        String commandString = null;
-        if ( message.indexOf( " " ) > 0 )
-        {
-            commandString = message.substring( 0, message.indexOf( " " ) );
-            message = message.substring( commandString.length() );
-        }
-        else
-        {
-            commandString = message;
-        }
-
-        SMSCommand smsCommand = smsCommandService.getSMSCommand( commandString, ParserType.J2ME_PARSER );
+
+        SMSCommand smsCommand = smsCommandService.getSMSCommand( SmsUtils.getCommandString( sms ),
+            ParserType.J2ME_PARSER );
+
         String token[] = message.split( "!" );
         Map<String, String> parsedMessage = this.parse( token[1], smsCommand );
+
         String senderPhoneNumber = StringUtils.replace( sms.getOriginator(), "+", "" );
-        Collection<OrganisationUnit> orgUnits = getOrganisationUnitsByPhoneNumber( senderPhoneNumber );
+        Collection<OrganisationUnit> orgUnits = SmsUtils.getOrganisationUnitsByPhoneNumber( senderPhoneNumber,
+            userService.getUsersByPhoneNumber( senderPhoneNumber ) );
 
         if ( orgUnits == null || orgUnits.size() == 0 )
         {
@@ -173,7 +133,7 @@
             }
         }
 
-        OrganisationUnit orgUnit = this.selectOrganisationUnit( orgUnits, parsedMessage, smsCommand );
+        OrganisationUnit orgUnit = SmsUtils.selectOrganisationUnit( orgUnits, parsedMessage, smsCommand );
         Period period = this.getPeriod( token[0].trim(), smsCommand.getDataset().getPeriodType() );
         boolean valueStored = false;
 
@@ -233,15 +193,16 @@
     {
         String upperCaseCode = code.getCode().toUpperCase();
 
-        String storedBy = getUser( sender, command ).getUsername();
+        String storedBy = SmsUtils.getUser( sender, command, userService.getUsersByPhoneNumber( sender ) )
+            .getUsername();
 
         if ( StringUtils.isBlank( storedBy ) )
         {
             storedBy = "[unknown] from [" + sender + "]";
         }
 
-        DataElementCategoryOptionCombo optionCombo = dataElementCategoryService.getDataElementCategoryOptionCombo( code
-            .getOptionId() );
+        DataElementCategoryOptionCombo optionCombo = dataElementCategoryService
+            .getDataElementCategoryOptionCombo( code.getOptionId() );
 
         DataValue dv = dataValueService.getDataValue( code.getDataElement(), period, orgUnit, optionCombo );
 
@@ -292,94 +253,6 @@
         }
     }
 
-    private OrganisationUnit selectOrganisationUnit( Collection<OrganisationUnit> orgUnits,
-        Map<String, String> parsedMessage, SMSCommand smsCommand )
-    {
-        OrganisationUnit orgUnit = null;
-
-        for ( OrganisationUnit o : orgUnits )
-        {
-            if ( orgUnits.size() == 1 )
-            {
-                orgUnit = o;
-            }
-            if ( parsedMessage.containsKey( "ORG" ) && o.getCode().equals( parsedMessage.get( "ORG" ) ) )
-            {
-                orgUnit = o;
-                break;
-            }
-        }
-
-        if ( orgUnit == null && orgUnits.size() > 1 )
-        {
-            String messageListingOrgUnits = smsCommand.getMoreThanOneOrgUnitMessage();
-
-            for ( Iterator<OrganisationUnit> i = orgUnits.iterator(); i.hasNext(); )
-            {
-                OrganisationUnit o = i.next();
-                messageListingOrgUnits += " " + o.getName() + ":" + o.getCode();
-                if ( i.hasNext() )
-                {
-                    messageListingOrgUnits += ",";
-                }
-            }
-            throw new SMSParserException( messageListingOrgUnits );
-        }
-
-        return orgUnit;
-    }
-
-    private Collection<OrganisationUnit> getOrganisationUnitsByPhoneNumber( String sender )
-    {
-        Collection<OrganisationUnit> orgUnits = new ArrayList<>();
-        Collection<User> users = userService.getUsersByPhoneNumber( sender );
-
-        for ( User u : users )
-        {
-            if ( u.getOrganisationUnits() != null )
-            {
-                orgUnits.addAll( u.getOrganisationUnits() );
-            }
-        }
-
-        return orgUnits;
-    }
-
-    private User getUser( String sender, SMSCommand smsCommand )
-    {
-        OrganisationUnit orgunit = null;
-        User user = null;
-
-        for ( User u : userService.getUsersByPhoneNumber( sender ) )
-        {
-            OrganisationUnit ou = u.getOrganisationUnit();
-
-            // Might be undefined if the user has more than one org.units
-            // "attached"
-            if ( orgunit == null )
-            {
-                orgunit = ou;
-            }
-            else if ( orgunit.getId() == ou.getId() )
-            {
-                // same orgunit, no problem...
-            }
-            else
-            {
-                if ( StringUtils.isEmpty( smsCommand.getMoreThanOneOrgUnitMessage() ) )
-                {
-                    throw new SMSParserException( SMSCommand.MORE_THAN_ONE_ORGUNIT_MESSAGE );
-                }
-                else
-                {
-                    throw new SMSParserException( smsCommand.getMoreThanOneOrgUnitMessage() );
-                }
-            }
-            user = u;
-        }
-        return user;
-    }
-
     private void registerCompleteDataSet( DataSet dataSet, Period period, OrganisationUnit organisationUnit,
         String storedBy )
     {
@@ -388,7 +261,8 @@
         DataElementCategoryOptionCombo optionCombo = dataElementCategoryService
             .getDefaultDataElementCategoryOptionCombo(); // TODO
 
-        if ( registrationService.getCompleteDataSetRegistration( dataSet, period, organisationUnit, optionCombo ) == null )
+        if ( registrationService.getCompleteDataSetRegistration( dataSet, period, organisationUnit,
+            optionCombo ) == null )
         {
             registration.setDataSet( dataSet );
             registration.setPeriod( period );
@@ -462,17 +336,17 @@
             String pattern = "yyyy-MM-dd";
             SimpleDateFormat formatter = new SimpleDateFormat( pattern );
             Date date = null;
-            
+
             try
             {
                 date = formatter.parse( periodName );
             }
             catch ( ParseException e )
             {
-                throw new IllegalArgumentException( "Couldn't make a period of type " + periodType.getName()
-                    + " and name " + periodName, e );
+                throw new IllegalArgumentException(
+                    "Couldn't make a period of type " + periodType.getName() + " and name " + periodName, e );
             }
-            
+
             return periodType.createPeriod( date );
         }
 
@@ -488,8 +362,8 @@
             }
             catch ( ParseException e )
             {
-                throw new IllegalArgumentException( "Couldn't make a period of type " + periodType.getName()
-                    + " and name " + periodName, e );
+                throw new IllegalArgumentException(
+                    "Couldn't make a period of type " + periodType.getName() + " and name " + periodName, e );
             }
 
             return periodType.createPeriod( date );
@@ -527,7 +401,7 @@
             Calendar cal = Calendar.getInstance();
 
             int month = 0;
-            
+
             if ( periodName.substring( 0, periodName.indexOf( " " ) ).equals( "Jan" ) )
             {
                 month = 1;
@@ -556,6 +430,7 @@
             }
         }
 
-        throw new IllegalArgumentException( "Couldn't make a period of type " + periodType.getName() + " and name " + periodName );
+        throw new IllegalArgumentException(
+            "Couldn't make a period of type " + periodType.getName() + " and name " + periodName );
     }
-}
+}
\ No newline at end of file

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/listener/ProgramStageDataEntrySMSListener.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/listener/ProgramStageDataEntrySMSListener.java	2015-10-11 18:48:57 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/listener/ProgramStageDataEntrySMSListener.java	2015-12-21 16:44:02 +0000
@@ -28,11 +28,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Calendar;
 import java.util.Collection;
-import java.util.Date;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.regex.Matcher;
@@ -46,28 +42,25 @@
 import org.hisp.dhis.sms.incoming.IncomingSmsListener;
 import org.hisp.dhis.sms.parse.ParserType;
 import org.hisp.dhis.sms.parse.SMSParserException;
-import org.hisp.dhis.user.User;
+import org.hisp.dhis.system.util.SmsUtils;
 import org.hisp.dhis.user.UserService;
+import org.springframework.beans.factory.annotation.Autowired;
 
-public class ProgramStageDataEntrySMSListener 
+public class ProgramStageDataEntrySMSListener
     implements IncomingSmsListener
-{    
+{
     private static final String defaultPattern = "([a-zA-Z]+)\\s*(\\d+)";
-    
+
+    // -------------------------------------------------------------------------
+    // Dependencies
+    // -------------------------------------------------------------------------
+
+    @Autowired
     private SMSCommandService smsCommandService;
 
-    public void setSmsCommandService( SMSCommandService smsCommandService )
-    {
-        this.smsCommandService = smsCommandService;
-    }
-
+    @Autowired
     private UserService userService;
 
-    public void setUserService( UserService userService )
-    {
-        this.userService = userService;
-    }
-    
     // -------------------------------------------------------------------------
     // IncomingSmsListener implementation
     // -------------------------------------------------------------------------
@@ -75,51 +68,24 @@
     @Override
     public boolean accept( IncomingSms sms )
     {
-        String message = sms.getText();
-        String commandString = null;
-
-        for ( int i = 0; i < message.length(); i++ )
-        {
-            String c = String.valueOf( message.charAt( i ) );
-            if ( c.matches( "\\W" ) )
-            {
-                commandString = message.substring( 0, i );
-                message = message.substring( commandString.length() + 1 );
-                break;
-            }
-        }
-
-        return smsCommandService.getSMSCommand( commandString, ParserType.PROGRAM_STAGE_DATAENTRY_PARSER ) != null;
+        return smsCommandService.getSMSCommand( SmsUtils.getCommandString( sms ),
+            ParserType.PROGRAM_STAGE_DATAENTRY_PARSER ) != null;
     }
 
     @Override
     public void receive( IncomingSms sms )
     {
         String message = sms.getText();
-        String commandString = null;
-
-        for ( int i = 0; i < message.length(); i++ )
-        {
-            String c = String.valueOf( message.charAt( i ) );
-            if ( c.matches( "\\W" ) )
-            {
-                commandString = message.substring( 0, i );
-                message = message.substring( commandString.length() + 1 );
-                break;
-            }
-        }
-
-        SMSCommand smsCommand = smsCommandService.getSMSCommand( commandString,
+        SMSCommand smsCommand = smsCommandService.getSMSCommand( SmsUtils.getCommandString( sms ),
             ParserType.TRACKED_ENTITY_REGISTRATION_PARSER );
-        
+
         this.parse( message, smsCommand );
 
-        lookForDate( message );
-        
-        //TODO what to do with the above?
-        
+        SmsUtils.lookForDate( message );
+
         String senderPhoneNumber = StringUtils.replace( sms.getOriginator(), "+", "" );
-        Collection<OrganisationUnit> orgUnits = getOrganisationUnitsByPhoneNumber( senderPhoneNumber );
+        Collection<OrganisationUnit> orgUnits = SmsUtils.getOrganisationUnitsByPhoneNumber( senderPhoneNumber,
+            userService.getUsersByPhoneNumber( senderPhoneNumber ) );
 
         if ( orgUnits == null || orgUnits.size() == 0 )
         {
@@ -133,18 +99,21 @@
             }
         }
     }
-    
+
     private Map<String, String> parse( String message, SMSCommand smsCommand )
     {
         HashMap<String, String> output = new HashMap<>();
         Pattern pattern = Pattern.compile( defaultPattern );
+        
         if ( !StringUtils.isBlank( smsCommand.getSeparator() ) )
         {
             String x = "(\\w+)\\s*\\" + smsCommand.getSeparator().trim() + "\\s*([\\w ]+)\\s*(\\"
                 + smsCommand.getSeparator().trim() + "|$)*\\s*";
             pattern = Pattern.compile( x );
         }
+        
         Matcher matcher = pattern.matcher( message );
+        
         while ( matcher.find() )
         {
             String key = matcher.group( 1 );
@@ -158,58 +127,4 @@
 
         return output;
     }
-    
-    private Date lookForDate( String message )
-    {
-        if ( !message.contains( " " ) )
-        {
-            return null;
-        }
-
-        Date date = null;
-        String dateString = message.trim().split( " " )[0];
-        SimpleDateFormat format = new SimpleDateFormat( "ddMM" );
-
-        try
-        {
-            Calendar cal = Calendar.getInstance();
-            date = format.parse( dateString );
-            cal.setTime( date );
-            int year = Calendar.getInstance().get( Calendar.YEAR );
-            int month = Calendar.getInstance().get( Calendar.MONTH );
-            
-            if ( cal.get( Calendar.MONTH ) < month )
-            {
-                cal.set( Calendar.YEAR, year );
-            }
-            else
-            {
-                cal.set( Calendar.YEAR, year - 1 );
-            }
-            
-            date = cal.getTime();
-        }
-        catch ( Exception e )
-        {
-            // no date found
-        }
-
-        return date;
-    }
-    
-    private Collection<OrganisationUnit> getOrganisationUnitsByPhoneNumber( String sender )
-    {
-        Collection<OrganisationUnit> orgUnits = new ArrayList<>();
-        Collection<User> users = userService.getUsersByPhoneNumber( sender );
-        
-        for ( User u : users )
-        {
-            if ( u.getOrganisationUnits() != null )
-            {
-                orgUnits.addAll( u.getOrganisationUnits() );
-            }
-        }
-
-        return orgUnits;
-    }
 }

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/listener/TrackedEntityRegistrationSMSListener.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/listener/TrackedEntityRegistrationSMSListener.java	2015-10-07 14:40:33 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/listener/TrackedEntityRegistrationSMSListener.java	2015-12-11 11:21:38 +0000
@@ -28,14 +28,10 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Calendar;
 import java.util.Collection;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Iterator;
 import java.util.Map;
 import java.util.Set;
 import java.util.regex.Matcher;
@@ -52,61 +48,43 @@
 import org.hisp.dhis.sms.incoming.IncomingSmsListener;
 import org.hisp.dhis.sms.parse.ParserType;
 import org.hisp.dhis.sms.parse.SMSParserException;
+import org.hisp.dhis.system.util.SmsUtils;
 import org.hisp.dhis.trackedentity.TrackedEntityAttribute;
 import org.hisp.dhis.trackedentity.TrackedEntityInstance;
 import org.hisp.dhis.trackedentity.TrackedEntityInstanceService;
 import org.hisp.dhis.trackedentity.TrackedEntityService;
 import org.hisp.dhis.trackedentityattributevalue.TrackedEntityAttributeValue;
-import org.hisp.dhis.user.User;
 import org.hisp.dhis.user.UserService;
+import org.springframework.beans.factory.annotation.Autowired;
 
 public class TrackedEntityRegistrationSMSListener
     implements IncomingSmsListener
 {
+
     private static final String defaultPattern = "([a-zA-Z]+)\\s*(\\d+)";
-    
+
+    // -------------------------------------------------------------------------
+    // Dependencies
+    // -------------------------------------------------------------------------
+
+    @Autowired
     private SMSCommandService smsCommandService;
 
-    public void setSmsCommandService( SMSCommandService smsCommandService )
-    {
-        this.smsCommandService = smsCommandService;
-    }
-
+    @Autowired
     private UserService userService;
 
-    public void setUserService( UserService userService )
-    {
-        this.userService = userService;
-    }
-
+    @Autowired
     private TrackedEntityService trackedEntityService;
 
-    public void setTrackedEntityService( TrackedEntityService trackedEntityService )
-    {
-        this.trackedEntityService = trackedEntityService;
-    }
-
+    @Autowired
     private TrackedEntityInstanceService trackedEntityInstanceService;
 
-    public void setTrackedEntityInstanceService( TrackedEntityInstanceService trackedEntityInstanceService )
-    {
-        this.trackedEntityInstanceService = trackedEntityInstanceService;
-    }
-
+    @Autowired
     private ProgramInstanceService programInstanceService;
 
-    public void setProgramInstanceService( ProgramInstanceService programInstanceService )
-    {
-        this.programInstanceService = programInstanceService;
-    }
-
+    @Autowired
     private SmsSender smsSender;
-    
-    public void setSmsSender( SmsSender smsSender )
-    {
-        this.smsSender = smsSender;
-    }
-    
+
     // -------------------------------------------------------------------------
     // IncomingSmsListener implementation
     // -------------------------------------------------------------------------
@@ -114,48 +92,23 @@
     @Override
     public boolean accept( IncomingSms sms )
     {
-        String message = sms.getText();
-        String commandString = null;
-
-        for ( int i = 0; i < message.length(); i++ )
-        {
-            String c = String.valueOf( message.charAt( i ) );
-            if ( c.matches( "\\W" ) )
-            {
-                commandString = message.substring( 0, i );
-                message = message.substring( commandString.length() + 1 );
-                break;
-            }
-        }
-
-        return smsCommandService.getSMSCommand( commandString, ParserType.TRACKED_ENTITY_REGISTRATION_PARSER ) != null;
+        return smsCommandService.getSMSCommand( SmsUtils.getCommandString( sms ),
+            ParserType.TRACKED_ENTITY_REGISTRATION_PARSER ) != null;
     }
 
     @Override
     public void receive( IncomingSms sms )
     {
         String message = sms.getText();
-        String commandString = null;
-
-        for ( int i = 0; i < message.length(); i++ )
-        {
-            String c = String.valueOf( message.charAt( i ) );
-            if ( c.matches( "\\W" ) )
-            {
-                commandString = message.substring( 0, i );
-                message = message.substring( commandString.length() + 1 );
-                break;
-            }
-        }
-
-        SMSCommand smsCommand = smsCommandService.getSMSCommand( commandString,
+        SMSCommand smsCommand = smsCommandService.getSMSCommand( SmsUtils.getCommandString( sms ),
             ParserType.TRACKED_ENTITY_REGISTRATION_PARSER );
-        
+
         Map<String, String> parsedMessage = this.parse( message, smsCommand );
 
-        Date date = lookForDate( message );
+        Date date = SmsUtils.lookForDate( message );
         String senderPhoneNumber = StringUtils.replace( sms.getOriginator(), "+", "" );
-        Collection<OrganisationUnit> orgUnits = getOrganisationUnitsByPhoneNumber( senderPhoneNumber );
+        Collection<OrganisationUnit> orgUnits = SmsUtils.getOrganisationUnitsByPhoneNumber( senderPhoneNumber,
+            userService.getUsersByPhoneNumber( senderPhoneNumber ) );
 
         if ( orgUnits == null || orgUnits.size() == 0 )
         {
@@ -169,7 +122,7 @@
             }
         }
 
-        OrganisationUnit orgUnit = this.selectOrganisationUnit( orgUnits, parsedMessage, smsCommand );
+        OrganisationUnit orgUnit = SmsUtils.selectOrganisationUnit( orgUnits, parsedMessage, smsCommand );
 
         TrackedEntityInstance trackedEntityInstance = new TrackedEntityInstance();
         trackedEntityInstance.setOrganisationUnit( orgUnit );
@@ -180,12 +133,11 @@
         {
             if ( parsedMessage.containsKey( code.getCode().toUpperCase() ) )
             {
-                TrackedEntityAttributeValue trackedEntityAttributeValue = this.createTrackedEntityAttributeValue(
-                    parsedMessage, code, smsCommand, trackedEntityInstance );
+                TrackedEntityAttributeValue trackedEntityAttributeValue = this
+                    .createTrackedEntityAttributeValue( parsedMessage, code, smsCommand, trackedEntityInstance );
                 patientAttributeValues.add( trackedEntityAttributeValue );
             }
         }
-        
 
         int trackedEntityInstanceId = 0;
         if ( patientAttributeValues.size() > 0 )
@@ -194,9 +146,11 @@
                 null, null, patientAttributeValues );
         }
 
-        programInstanceService.enrollTrackedEntityInstance( trackedEntityInstanceService.getTrackedEntityInstance( trackedEntityInstanceId ), smsCommand.getProgram(), new Date(), date, orgUnit );
+        programInstanceService.enrollTrackedEntityInstance(
+            trackedEntityInstanceService.getTrackedEntityInstance( trackedEntityInstanceId ), smsCommand.getProgram(),
+            new Date(), date, orgUnit );
         smsSender.sendMessage( "Register new User successfully", senderPhoneNumber );
-        
+
     }
 
     private TrackedEntityAttributeValue createTrackedEntityAttributeValue( Map<String, String> parsedMessage,
@@ -212,111 +166,20 @@
         return trackedEntityAttributeValue;
     }
 
-    private OrganisationUnit selectOrganisationUnit( Collection<OrganisationUnit> orgUnits,
-        Map<String, String> parsedMessage, SMSCommand smsCommand )
-    {
-        OrganisationUnit orgUnit = null;
-
-        for ( OrganisationUnit o : orgUnits )
-        {
-            if ( orgUnits.size() == 1 )
-            {
-                orgUnit = o;
-            }
-            if ( parsedMessage.containsKey( "ORG" ) && o.getCode().equals( parsedMessage.get( "ORG" ) ) )
-            {
-                orgUnit = o;
-                break;
-            }
-        }
-
-        if ( orgUnit == null && orgUnits.size() > 1 )
-        {
-            String messageListingOrgUnits = smsCommand.getMoreThanOneOrgUnitMessage();
-            
-            for ( Iterator<OrganisationUnit> i = orgUnits.iterator(); i.hasNext(); )
-            {
-                OrganisationUnit o = i.next();
-                messageListingOrgUnits += " " + o.getName() + ":" + o.getCode();
-                if ( i.hasNext() )
-                {
-                    messageListingOrgUnits += ",";
-                }
-            }
-            
-            throw new SMSParserException( messageListingOrgUnits );
-        }
-
-        return orgUnit;
-    }
-
-    private Collection<OrganisationUnit> getOrganisationUnitsByPhoneNumber( String sender )
-    {
-        Collection<OrganisationUnit> orgUnits = new ArrayList<>();
-        Collection<User> users = userService.getUsersByPhoneNumber( sender );
-        for ( User u : users )
-        {
-            if ( u.getOrganisationUnits() != null )
-            {
-                orgUnits.addAll( u.getOrganisationUnits() );
-            }
-        }
-
-        return orgUnits;
-    }
-
-    private Date lookForDate( String message )
-    {
-        if ( !message.contains( " " ) )
-        {
-            return null;
-        }
-
-        Date date = null;
-        String dateString = message.trim().split( " " )[0];
-        SimpleDateFormat format = new SimpleDateFormat( "ddMM" );
-
-        try
-        {
-            Calendar cal = Calendar.getInstance();
-            date = format.parse( dateString );
-            cal.setTime( date );
-            int year = Calendar.getInstance().get( Calendar.YEAR );
-            int month = Calendar.getInstance().get( Calendar.MONTH );
-            
-            if ( cal.get( Calendar.MONTH ) < month )
-            {
-                cal.set( Calendar.YEAR, year );
-            }
-            else
-            {
-                cal.set( Calendar.YEAR, year - 1 );
-            }
-            
-            date = cal.getTime();
-        }
-        catch ( Exception e )
-        {
-            // no date found
-        }
-
-        return date;
-    }
-
     private Map<String, String> parse( String message, SMSCommand smsCommand )
     {
         HashMap<String, String> output = new HashMap<>();
         Pattern pattern = Pattern.compile( defaultPattern );
-        
+
         if ( !StringUtils.isBlank( smsCommand.getSeparator() ) )
         {
             String x = "(\\w+)\\s*\\" + smsCommand.getSeparator().trim() + "\\s*([\\w ]+)\\s*(\\"
                 + smsCommand.getSeparator().trim() + "|$)*\\s*";
             pattern = Pattern.compile( x );
         }
-        
+
         Matcher matcher = pattern.matcher( message );
-        
+
         while ( matcher.find() )
         {
             String key = matcher.group( 1 );

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/listener/UnregisteredSMSListener.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/listener/UnregisteredSMSListener.java	2015-10-07 14:40:33 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/listener/UnregisteredSMSListener.java	2015-12-11 11:21:38 +0000
@@ -44,52 +44,39 @@
 import org.hisp.dhis.sms.incoming.SmsMessageStatus;
 import org.hisp.dhis.sms.parse.ParserType;
 import org.hisp.dhis.sms.parse.SMSParserException;
+import org.hisp.dhis.system.util.SmsUtils;
 import org.hisp.dhis.user.User;
 import org.hisp.dhis.user.UserCredentials;
 import org.hisp.dhis.user.UserGroup;
 import org.hisp.dhis.user.UserService;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
 
 public class UnregisteredSMSListener
     implements IncomingSmsListener
 {
+
+    public static final String USER_NAME = "anonymous";
+
+    // -------------------------------------------------------------------------
+    // Dependencies
+    // -------------------------------------------------------------------------
+
+    @Autowired
     private SMSCommandService smsCommandService;
 
-    public void setSmsCommandService( SMSCommandService smsCommandService )
-    {
-        this.smsCommandService = smsCommandService;
-    }
-
+    @Autowired
     private UserService userService;
 
-    public void setUserService( UserService userService )
-    {
-        this.userService = userService;
-    }
-
+    @Autowired
     private MessageService messageService;
 
-    public void setMessageService( MessageService messageService )
-    {
-        this.messageService = messageService;
-    }
-
+    @Autowired
     private SmsMessageSender smsMessageSender;
 
-    public void setSmsMessageSender( SmsMessageSender smsMessageSender )
-    {
-        this.smsMessageSender = smsMessageSender;
-    }
-
+    @Autowired
     private IncomingSmsService incomingSmsService;
 
-    public void setIncomingSmsService( IncomingSmsService incomingSmsService )
-    {
-        this.incomingSmsService = incomingSmsService;
-    }
-
-    public static final String USER_NAME = "anonymous";
-
     // -------------------------------------------------------------------------
     // IncomingSmsListener implementation
     // -------------------------------------------------------------------------
@@ -98,22 +85,8 @@
     @Override
     public boolean accept( IncomingSms sms )
     {
-        String message = sms.getText();
-        String commandString = null;
-
-        for ( int i = 0; i < message.length(); i++ )
-        {
-            String c = String.valueOf( message.charAt( i ) );
-            
-            if ( c.matches( "\\W" ) )
-            {
-                commandString = message.substring( 0, i );
-                message = message.substring( commandString.length() + 1 );
-                break;
-            }
-        }
-
-        return smsCommandService.getSMSCommand( commandString, ParserType.UNREGISTERED_PARSER ) != null;
+        return smsCommandService.getSMSCommand( SmsUtils.getCommandString( sms ),
+            ParserType.UNREGISTERED_PARSER ) != null;
     }
 
     @Transactional
@@ -121,20 +94,8 @@
     public void receive( IncomingSms sms )
     {
         String message = sms.getText();
-        String commandString = null;
-
-        for ( int i = 0; i < message.length(); i++ )
-        {
-            String c = String.valueOf( message.charAt( i ) );
-            if ( c.matches( "\\W" ) )
-            {
-                commandString = message.substring( 0, i );
-                message = message.substring( commandString.length() + 1 );
-                break;
-            }
-        }
-
-        SMSCommand smsCommand = smsCommandService.getSMSCommand( commandString, ParserType.UNREGISTERED_PARSER );
+        SMSCommand smsCommand = smsCommandService.getSMSCommand( SmsUtils.getCommandString( sms ),
+            ParserType.UNREGISTERED_PARSER );
 
         UserGroup userGroup = smsCommand.getUserGroup();
 
@@ -151,13 +112,13 @@
                 {
                     User user = iterator.next();
                     messageError += user.getName();
-                    
+
                     if ( iterator.hasNext() )
                     {
                         messageError += ", ";
                     }
                 }
-                
+
                 throw new SMSParserException( messageError );
             }
             else
@@ -191,8 +152,8 @@
                 User sender = new User();
                 sender.setPhoneNumber( senderPhoneNumber );
                 feedbackList.add( sender );
-                smsMessageSender.sendMessage( smsCommand.getName(), smsCommand.getReceivedMessage(), null,
-                    null, feedbackList, true );
+                smsMessageSender.sendMessage( smsCommand.getName(), smsCommand.getReceivedMessage(), null, null,
+                    feedbackList, true );
 
                 // update the status of the sms after process
                 sms.setStatus( SmsMessageStatus.PROCESSED );

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/outbound/DefaultOutboundSmsTransportService.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/outbound/DefaultOutboundSmsTransportService.java	2015-12-07 12:46:19 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/sms/outbound/DefaultOutboundSmsTransportService.java	2015-12-21 16:44:02 +0000
@@ -102,7 +102,7 @@
     {
         this.smsPublisher = smsPublisher;
     }
-
+    
     // -------------------------------------------------------------------------
     // OutboundSmsTransportService implementation
     // -------------------------------------------------------------------------
@@ -472,7 +472,7 @@
             if ( recipients.size() > 1 )
             {
                 removeGroup( recipient );
-            }            
+            }
         }
 
         if ( outboundMessage.getMessageStatus() == MessageStatuses.SENT )

=== 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	2015-12-09 17:24:33 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/resources/META-INF/dhis/beans.xml	2015-12-21 16:44:02 +0000
@@ -1095,14 +1095,9 @@
 
   <!-- SMS Services -->
 
-  <bean id="org.hisp.dhis.sms.MessageQueue" class="org.hisp.dhis.sms.DatabaseSupportedInternalMemoryMessageQueue">
-    <property name="smsStore" ref="org.hisp.dhis.sms.hibernate.IncomingSmsStore" />
-  </bean>
+  <bean id="org.hisp.dhis.sms.MessageQueue" class="org.hisp.dhis.sms.DatabaseSupportedInternalMemoryMessageQueue" />
 
-  <bean id="org.hisp.dhis.sms.SmsPublisher" class="org.hisp.dhis.sms.SmsPublisher">
-    <property name="messageQueue" ref="org.hisp.dhis.sms.MessageQueue" />
-    <property name="smsSender" ref="org.hisp.dhis.sms.SmsSender" />
-  </bean>
+  <bean id="org.hisp.dhis.sms.SmsPublisher" class="org.hisp.dhis.sms.SmsPublisher" />
 
   <bean id="org.hisp.dhis.sms.config.SmsConfigurationManager" class="org.hisp.dhis.sms.config.DefaultSmsConfigurationManager" />
 
@@ -1111,9 +1106,7 @@
     <property name="incomingSmsQueue" ref="org.hisp.dhis.sms.MessageQueue" />
   </bean>
 
-  <bean id="org.smslib.IInboundMessageNotification" class="org.hisp.dhis.sms.incoming.SMPPInboundNotification">
-    <property name="incomingSmsService" ref="org.hisp.dhis.sms.incoming.IncomingSmsService" />
-  </bean>
+  <bean id="org.smslib.IInboundMessageNotification" class="org.hisp.dhis.sms.incoming.SMPPInboundNotification" />
 
   <bean id="org.hisp.dhis.sms.outbound.OutboundSmsService" class="org.hisp.dhis.sms.outbound.DefaultOutboundSmsService">
     <property name="outboundSmsStore" ref="org.hisp.dhis.sms.hibernate.OutboundSmsStore" />
@@ -1125,15 +1118,13 @@
     <property name="smsPublisher" ref="org.hisp.dhis.sms.SmsPublisher" />
   </bean>
 
-  <bean id="org.hisp.dhis.sms.SmsSender" class="org.hisp.dhis.sms.DefaultSmsSender">
-    <property name="currentUserService" ref="org.hisp.dhis.user.CurrentUserService" />
-    <property name="userService" ref="org.hisp.dhis.user.UserService" />
-    <property name="outboundSmsService" ref="org.hisp.dhis.sms.outbound.OutboundSmsService" />
-  </bean>
+  <bean id="org.hisp.dhis.sms.SmsSender" class="org.hisp.dhis.sms.DefaultSmsSender" />
 
   <bean id="org.hisp.dhis.sms.SmsMessageSender" class="org.hisp.dhis.sms.SmsMessageSender" />
 
   <bean id="org.hisp.dhis.sms.task.SendSmsTask" class="org.hisp.dhis.sms.task.SendSmsTask" scope="prototype" />
+  
+  <bean id="org.hisp.dhis.sms.SmsConsumerThread" class="org.hisp.dhis.sms.SmsConsumerThread" />
 
   <!-- I18nService -->
 
@@ -1307,55 +1298,19 @@
     <property name="smsCommandStore" ref="org.hisp.dhis.sms.command.hibernate.SMSCommandStore" />
   </bean>
 
-  <bean id="org.hisp.dhis.sms.listener.DataValueSMSListener" class="org.hisp.dhis.sms.listener.DataValueSMSListener">
-    <property name="registrationService" ref="org.hisp.dhis.dataset.CompleteDataSetRegistrationService" />
-    <property name="dataValueService" ref="org.hisp.dhis.datavalue.DataValueService" />
-    <property name="smsSender" ref="org.hisp.dhis.sms.SmsSender" />
-    <property name="dataElementCategoryService" ref="org.hisp.dhis.dataelement.DataElementCategoryService" />
-    <property name="smsCommandService" ref="org.hisp.dhis.sms.command.SMSCommandService" />
-    <property name="userService" ref="org.hisp.dhis.user.UserService" />
-    <property name="dataSetService" ref="org.hisp.dhis.dataset.DataSetService" />
-    <property name="incomingSmsService" ref="org.hisp.dhis.sms.incoming.IncomingSmsService" />
-    <property name="dataElementService" ref="org.hisp.dhis.dataelement.DataElementService" />
-  </bean>
+  <bean id="org.hisp.dhis.sms.listener.DataValueSMSListener" class="org.hisp.dhis.sms.listener.DataValueSMSListener" />
 
   <bean id="org.hisp.dhis.sms.listener.J2MEDataValueSMSListener"
-    class="org.hisp.dhis.sms.listener.J2MEDataValueSMSListener">
-    <property name="registrationService" ref="org.hisp.dhis.dataset.CompleteDataSetRegistrationService" />
-    <property name="dataValueService" ref="org.hisp.dhis.datavalue.DataValueService" />
-    <property name="smsSender" ref="org.hisp.dhis.sms.SmsSender" />
-    <property name="dataElementCategoryService" ref="org.hisp.dhis.dataelement.DataElementCategoryService" />
-    <property name="smsCommandService" ref="org.hisp.dhis.sms.command.SMSCommandService" />
-    <property name="userService" ref="org.hisp.dhis.user.UserService" />
-  </bean>
+    class="org.hisp.dhis.sms.listener.J2MEDataValueSMSListener" />
 
   <bean id="org.hisp.dhis.sms.listener.UnregisteredSMSListener"
-    class="org.hisp.dhis.sms.listener.UnregisteredSMSListener">
-    <property name="smsCommandService" ref="org.hisp.dhis.sms.command.SMSCommandService" />
-    <property name="messageService" ref="org.hisp.dhis.message.MessageService" />
-    <property name="smsMessageSender" ref="org.hisp.dhis.sms.SmsMessageSender" />
-    <property name="userService" ref="org.hisp.dhis.user.UserService" />
-    <property name="incomingSmsService" ref="org.hisp.dhis.sms.incoming.IncomingSmsService" />
-  </bean>
+    class="org.hisp.dhis.sms.listener.UnregisteredSMSListener" />
 
   <bean id="org.hisp.dhis.sms.listener.DHISMessageAlertListener"
-    class="org.hisp.dhis.sms.listener.DHISMessageAlertListener">
-    <property name="smsCommandService" ref="org.hisp.dhis.sms.command.SMSCommandService" />
-    <property name="messageService" ref="org.hisp.dhis.message.MessageService" />
-    <property name="smsMessageSender" ref="org.hisp.dhis.sms.SmsMessageSender" />
-    <property name="userService" ref="org.hisp.dhis.user.UserService" />
-    <property name="incomingSmsService" ref="org.hisp.dhis.sms.incoming.IncomingSmsService" />
-  </bean>
+    class="org.hisp.dhis.sms.listener.DHISMessageAlertListener" />
 
   <bean id="org.hisp.dhis.sms.listener.TrackedEntityRegistrationSMSListener"
-    class="org.hisp.dhis.sms.listener.TrackedEntityRegistrationSMSListener">
-    <property name="smsCommandService" ref="org.hisp.dhis.sms.command.SMSCommandService" />
-    <property name="userService" ref="org.hisp.dhis.user.UserService" />
-    <property name="trackedEntityService" ref="org.hisp.dhis.trackedentity.TrackedEntityService" />
-    <property name="trackedEntityInstanceService" ref="org.hisp.dhis.trackedentity.TrackedEntityInstanceService" />
-    <property name="programInstanceService" ref="org.hisp.dhis.program.ProgramInstanceService" />
-    <property name="smsSender" ref="org.hisp.dhis.sms.SmsSender" />
-  </bean>
+    class="org.hisp.dhis.sms.listener.TrackedEntityRegistrationSMSListener" />
 
   <!-- I18n UI -->
 

=== added file 'dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/SmsUtils.java'
--- dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/SmsUtils.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/SmsUtils.java	2015-12-18 11:04:05 +0000
@@ -0,0 +1,281 @@
+package org.hisp.dhis.system.util;
+
+/*
+* Copyright (c) 2004-2015, 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.ArrayList;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.text.SimpleDateFormat;
+
+import org.apache.commons.lang3.StringUtils;
+
+import org.hisp.dhis.commons.util.TextUtils;
+import org.hisp.dhis.organisationunit.OrganisationUnit;
+import org.hisp.dhis.sms.incoming.IncomingSms;
+import org.hisp.dhis.sms.parse.SMSParserException;
+import org.hisp.dhis.user.User;
+import org.hisp.dhis.sms.command.SMSCommand;
+
+/**
+ * @author Zubair <rajazubair.asghar@xxxxxxxxx>
+ */
+public class SmsUtils
+{
+    private static int MAX_CHAR = 160;
+
+    public static String getCommandString( IncomingSms sms )
+    {
+        String message = sms.getText();
+        String commandString = null;
+
+        for ( int i = 0; i < message.length(); i++ )
+        {
+            String c = String.valueOf( message.charAt( i ) );
+
+            if ( c.matches( "\\W" ) )
+            {
+                commandString = message.substring( 0, i );
+                message = message.substring( commandString.length() + 1 );
+                break;
+            }
+        }
+
+        return commandString;
+    }
+
+    public static Collection<OrganisationUnit> getOrganisationUnitsByPhoneNumber( String sender,
+        Collection<User> users )
+    {
+        Collection<OrganisationUnit> orgUnits = new ArrayList<>();
+        for ( User u : users )
+        {
+            if ( u.getOrganisationUnits() != null )
+            {
+                orgUnits.addAll( u.getOrganisationUnits() );
+            }
+        }
+
+        return orgUnits;
+    }
+
+    public static Date lookForDate( String message )
+    {
+        if ( !message.contains( " " ) )
+        {
+            return null;
+        }
+
+        Date date = null;
+        String dateString = message.trim().split( " " )[0];
+        SimpleDateFormat format = new SimpleDateFormat( "ddMM" );
+
+        try
+        {
+            Calendar cal = Calendar.getInstance();
+            date = format.parse( dateString );
+            cal.setTime( date );
+            int year = Calendar.getInstance().get( Calendar.YEAR );
+            int month = Calendar.getInstance().get( Calendar.MONTH );
+
+            if ( cal.get( Calendar.MONTH ) < month )
+            {
+                cal.set( Calendar.YEAR, year );
+            }
+            else
+            {
+                cal.set( Calendar.YEAR, year - 1 );
+            }
+
+            date = cal.getTime();
+        }
+        catch ( Exception e )
+        {
+            // no date found
+        }
+
+        return date;
+    }
+
+    public static User getUser( String sender, SMSCommand smsCommand, List<User> userList )
+    {
+        OrganisationUnit orgunit = null;
+        User user = null;
+
+        // Need to be edited
+        for ( User u : userList )
+        {
+            OrganisationUnit ou = u.getOrganisationUnit();
+
+            if ( ou != null )
+            {
+                // Might be undefined if the user has more than one org units
+                if ( orgunit == null )
+                {
+                    orgunit = ou;
+                }
+                else if ( orgunit.getId() == ou.getId() )
+                {
+                    // Same org unit
+                }
+                else
+                {
+                    if ( StringUtils.isEmpty( smsCommand.getMoreThanOneOrgUnitMessage() ) )
+                    {
+                        throw new SMSParserException( SMSCommand.MORE_THAN_ONE_ORGUNIT_MESSAGE );
+                    }
+                    else
+                    {
+                        throw new SMSParserException( smsCommand.getMoreThanOneOrgUnitMessage() );
+                    }
+                }
+            }
+
+            user = u;
+        }
+
+        if ( user == null )
+        {
+            throw new SMSParserException( "User is not associated with any orgunit. Please contact your supervisor." );
+        }
+
+        return user;
+    }
+
+    public static List<String> splitLongUnicodeString( String message, List<String> result )
+    {
+        String firstTempString = null;
+        String secondTempString = null;
+        int indexToCut = 0;
+
+        firstTempString = message.substring( 0, MAX_CHAR );
+
+        indexToCut = firstTempString.lastIndexOf( " " );
+
+        firstTempString = firstTempString.substring( 0, indexToCut );
+
+        result.add( firstTempString );
+
+        secondTempString = message.substring( indexToCut + 1, message.length() );
+
+        if ( secondTempString.length() <= MAX_CHAR )
+        {
+            result.add( secondTempString );
+            return result;
+        }
+        else
+        {
+            return splitLongUnicodeString( secondTempString, result );
+        }
+    }
+
+    public static String createMessage( String subject, String text, User sender )
+    {
+        String name = "DHIS";
+
+        if ( sender != null )
+        {
+            name = sender.getUsername();
+        }
+
+        if ( subject == null || subject.isEmpty() )
+        {
+            subject = "";
+        }
+        else
+        {
+            subject = " - " + subject;
+        }
+
+        text = name + subject + ": " + text;
+
+        int length = text.length(); // Simplistic cut off 160 characters
+
+        return (length > 160) ? text.substring( 0, 157 ) + "..." : text;
+    }
+
+    public static Set<String> getRecipientsPhoneNumber( Collection<User> users )
+    {
+        Set<String> recipients = new HashSet<>();
+
+        for ( User user : users )
+        {
+            String phoneNumber = user.getPhoneNumber();
+
+            if ( StringUtils.trimToNull( phoneNumber ) != null )
+            {
+                recipients.add( phoneNumber );
+            }
+        }
+        return recipients;
+    }
+
+    public static OrganisationUnit selectOrganisationUnit( Collection<OrganisationUnit> orgUnits,
+        Map<String, String> parsedMessage, SMSCommand smsCommand )
+    {
+        OrganisationUnit orgUnit = null;
+
+        for ( OrganisationUnit o : orgUnits )
+        {
+            if ( orgUnits.size() == 1 )
+            {
+                orgUnit = o;
+            }
+            if ( parsedMessage.containsKey( "ORG" ) && o.getCode().equals( parsedMessage.get( "ORG" ) ) )
+            {
+                orgUnit = o;
+                break;
+            }
+        }
+
+        if ( orgUnit == null && orgUnits.size() > 1 )
+        {
+            String messageListingOrgUnits = smsCommand.getMoreThanOneOrgUnitMessage();
+
+            for ( Iterator<OrganisationUnit> i = orgUnits.iterator(); i.hasNext(); )
+            {
+                OrganisationUnit o = i.next();
+                messageListingOrgUnits += TextUtils.SPACE + o.getName() + ":" + o.getCode();
+
+                if ( i.hasNext() )
+                {
+                    messageListingOrgUnits += ",";
+                }
+            }
+
+            throw new SMSParserException( messageListingOrgUnits );
+        }
+
+        return orgUnit;
+    }
+}

=== modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/sms/SmsController.java'
--- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/sms/SmsController.java	2015-11-24 16:58:49 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/sms/SmsController.java	2015-12-14 13:35:40 +0000
@@ -28,9 +28,8 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/**
- * Zubair <rajazubair.asghar@xxxxxxxxx>
- */
+import java.text.ParseException;
+import java.util.Date;
 import java.util.Map;
 
 import javax.servlet.http.HttpServletRequest;
@@ -41,7 +40,6 @@
 import org.hisp.dhis.sms.incoming.IncomingSmsService;
 import org.hisp.dhis.webapi.service.WebMessageService;
 import org.hisp.dhis.webapi.utils.WebMessageUtils;
-
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.RequestBody;
@@ -50,6 +48,9 @@
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
+/**
+ * Zubair <rajazubair.asghar@xxxxxxxxx>
+ */
 @RestController
 @RequestMapping( value = "/sms" )
 public class SmsController
@@ -125,11 +126,10 @@
 
     @RequestMapping( value = "/inbound", method = RequestMethod.POST )
     @PreAuthorize( "hasRole('ALL') or hasRole('F_MOBILE_SETTINGS')" )
-    public void receiveSMSMessage( @RequestParam String originator,
-        @RequestParam( required = false ) String received_time, @RequestParam String message,
-        @RequestParam( defaultValue = "Unknown", required = false ) String gateway, HttpServletRequest request,
-        HttpServletResponse response)
-            throws WebMessageException
+    public void receiveSMSMessage( @RequestParam String originator, @RequestParam( required = false ) Date receivedTime,
+        @RequestParam String message, @RequestParam( defaultValue = "Unknown", required = false ) String gateway,
+        HttpServletRequest request, HttpServletResponse response)
+            throws WebMessageException, ParseException
     {
         if ( originator == null || originator.length() <= 0 )
         {
@@ -141,25 +141,28 @@
             throw new WebMessageException( WebMessageUtils.conflict( "Message must be specified" ) );
         }
 
-        incomingSMSService.save( message, originator, gateway );
-
-        webMessageService.send( WebMessageUtils.ok( "Received" ), response, request );
+        int smsId = incomingSMSService.save( message, originator, gateway, receivedTime );
+
+        webMessageService.send( WebMessageUtils.ok( "Received: SMS ID " + smsId ), response, request );
+
     }
 
     @RequestMapping( value = "/inbound", method = RequestMethod.POST, consumes = "application/json" )
     @PreAuthorize( "hasRole('ALL') or hasRole('F_MOBILE_SETTINGS')" )
     public void receiveSMSMessage( @RequestBody Map<String, Object> jsonMassage, HttpServletRequest request,
         HttpServletResponse response )
-            throws WebMessageException
+            throws WebMessageException, ParseException
     {
         if ( jsonMassage == null )
         {
             throw new WebMessageException( WebMessageUtils.conflict( "RequestBody must not be empty" ) );
         }
 
-        incomingSMSService.save( jsonMassage.get( "message" ).toString(), jsonMassage.get( "originator" ).toString(),
-            jsonMassage.get( "gateway" ).toString() );
-
-        webMessageService.send( WebMessageUtils.ok( "Received" ), response, request );
+        int smsId = incomingSMSService.save( jsonMassage.get( "message" ).toString(),
+            jsonMassage.get( "originator" ).toString(), jsonMassage.get( "gateway" ).toString(),
+            (Date) jsonMassage.get( "receivedTime" ) );
+
+        webMessageService.send( WebMessageUtils.ok( "Received: SMS ID " + smsId ), response, request );
+
     }
 }

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/java/org/hisp/dhis/mobile/action/SendSMSAction.java'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/java/org/hisp/dhis/mobile/action/SendSMSAction.java	2015-01-17 07:41:26 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/java/org/hisp/dhis/mobile/action/SendSMSAction.java	2015-12-07 18:09:30 +0000
@@ -98,8 +98,6 @@
             try
             {
                 smsSender.sendMessage( new OutboundSms( msg, recipient ), null );
-                // outboundSmsService.sendMessage( new OutboundSms( msg,
-                // recipient ), null );
                 this.message = "Sent message to " + recipient;
             }
             catch ( SmsServiceException e )