← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 10898: replace SmsMessageSender by SmsSender, Send DHIS message to DHIS group from SMS, fix SMS notifica...

 

------------------------------------------------------------
revno: 10898
committer: Lai <lai.hispvietnam@xxxxxxxxx>
branch nick: dhis2
timestamp: Mon 2013-05-20 16:32:19 +0700
message:
  replace SmsMessageSender by SmsSender, Send DHIS message to DHIS group from SMS, fix SMS notifications bugs, edit code style
removed:
  dhis-2/dhis-services/dhis-service-sms/src/main/java/org/hisp/dhis/sms/outbound/SmsMessageSender.java
  dhis-2/dhis-services/dhis-service-sms/src/test/java/org/hisp/dhis/sms/outbound/SmsMessageSenderTest.java
modified:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/message/MessageSender.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/parse/ParserType.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/smscommand/SMSCommand.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/message/EmailMessageSender.java
  dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/smscommand/SMSCommand.hbm.xml
  dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/message/MockMessageSender.java
  dhis-2/dhis-services/dhis-service-sms/src/main/java/org/hisp/dhis/sms/outbound/SmsSender.java
  dhis-2/dhis-services/dhis-service-sms/src/main/java/org/hisp/dhis/sms/parse/DefaultParserManager.java
  dhis-2/dhis-services/dhis-service-sms/src/main/resources/META-INF/dhis/beans.xml
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/java/org/hisp/dhis/mobile/action/smscommand/CreateSMSCommandForm.java
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/java/org/hisp/dhis/mobile/action/smscommand/SMSCommandAction.java
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/resources/META-INF/dhis/beans.xml
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/resources/org/hisp/dhis/mobile/i18n_module.properties
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/resources/struts.xml
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/webapp/dhis-web-maintenance-mobile/javascript/gateway.js
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/webapp/dhis-web-maintenance-mobile/smscommand/new-sms-command.vm
  dhis-2/dhis-web/dhis-web-sms/src/main/java/org/hisp/dhis/sms/outcoming/ProcessingSendSMSAction.java
  dhis-2/dhis-web/dhis-web-sms/src/main/resources/META-INF/dhis/beans.xml
  dhis-2/dhis-web/dhis-web-sms/src/main/webapp/dhis-web-sms/smserror.vm
  dhis-2/dhis-web/dhis-web-sms/src/main/webapp/dhis-web-sms/smssuccess.vm


--
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/message/MessageSender.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/message/MessageSender.java	2012-11-14 13:11:10 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/message/MessageSender.java	2013-05-20 09:32:19 +0000
@@ -44,5 +44,5 @@
      * @param users the users to send the message to.
      * @param forceSend force sending the message despite potential user settings.
      */
-    void sendMessage( String subject, String text, User sender, Set<User> users, boolean forceSend );
+    String sendMessage( String subject, String text, User sender, Set<User> users, boolean forceSend );
 }

=== 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	2013-03-09 02:24:46 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/sms/parse/ParserType.java	2013-05-20 09:32:19 +0000
@@ -3,5 +3,6 @@
 public enum ParserType
 {
     KEY_VALUE_PARSER,
-    J2ME_PARSER;
+    J2ME_PARSER,
+    ALERT_PARSER;
 }

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/smscommand/SMSCommand.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/smscommand/SMSCommand.java	2013-03-09 14:35:08 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/smscommand/SMSCommand.java	2013-05-20 09:32:19 +0000
@@ -31,6 +31,7 @@
 
 import org.hisp.dhis.dataset.DataSet;
 import org.hisp.dhis.sms.parse.ParserType;
+import org.hisp.dhis.user.UserGroup;
 
 public class SMSCommand
 {
@@ -51,11 +52,28 @@
     private String codeSeparator;
 
     private String defaultMessage;
+    
+    private UserGroup userGroup;
 
     private boolean currentPeriodUsedForReporting = false; // default is prev
 
     public SMSCommand( String name, String parser, ParserType parserType, String separator, DataSet dataset,
-        Set<SMSCode> codes, String codeSeparator, String defaultMessage )
+        Set<SMSCode> codes, String codeSeparator, String defaultMessage, UserGroup userGroup )
+    {
+        super();
+        this.name = name;
+        this.parser = parser;
+        this.parserType = parserType;
+        this.separator = separator;
+        this.dataset = dataset;
+        this.codes = codes;
+        this.codeSeparator = codeSeparator;
+        this.defaultMessage = defaultMessage;
+        this.userGroup = userGroup;
+    }
+    
+    public SMSCommand( String name, String parser, ParserType parserType, String separator, DataSet dataset,
+        Set<SMSCode> codes, String codeSeparator, String defaultMessage)
     {
         super();
         this.name = name;
@@ -224,4 +242,14 @@
             this.currentPeriodUsedForReporting = currentPeriodUsedForReporting;
         }
     }
+
+    public UserGroup getUserGroup()
+    {
+        return userGroup;
+    }
+
+    public void setUserGroup( UserGroup userGroup )
+    {
+        this.userGroup = userGroup;
+    }
 }

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/message/EmailMessageSender.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/message/EmailMessageSender.java	2013-04-25 09:07:24 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/message/EmailMessageSender.java	2013-05-20 09:32:19 +0000
@@ -84,7 +84,7 @@
      */
     @Async
     @Override
-    public void sendMessage( String subject, String text, User sender, Set<User> users, boolean forceSend )
+    public String sendMessage( String subject, String text, User sender, Set<User> users, boolean forceSend )
     {        
         String hostName = systemSettingManager.getEmailHostName();
         int port = systemSettingManager.getEmailPort();
@@ -94,7 +94,7 @@
 
         if ( hostName == null )
         {
-            return;
+            return null;
         }
 
         text = sender == null ? text : ( text + LB + LB + 
@@ -140,6 +140,7 @@
         {
             log.warn( "Could not send email: " + ex.getMessage() );
         }
+        return null;
     }
 
     private Email getEmail( String hostName, int port, String username, String password, boolean tls )

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/smscommand/SMSCommand.hbm.xml'
--- dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/smscommand/SMSCommand.hbm.xml	2013-03-05 17:06:26 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/smscommand/SMSCommand.hbm.xml	2013-05-20 09:32:19 +0000
@@ -35,6 +35,8 @@
       <key column="id" />
       <many-to-many class="org.hisp.dhis.smscommand.SMSCode" column="codeid" unique="true" />
     </set>
+    
+    <many-to-one name="userGroup" class="org.hisp.dhis.user.UserGroup" column="usergroupid" foreign-key="fk_smscommand_usergroup"/>
 
   </class>
 

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/message/MockMessageSender.java'
--- dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/message/MockMessageSender.java	2012-11-14 13:11:10 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/message/MockMessageSender.java	2013-05-20 09:32:19 +0000
@@ -35,8 +35,9 @@
     implements MessageSender
 {
     @Override
-    public void sendMessage( String subject, String text, User sender, Set<User> users, boolean forceSend )
+    public String sendMessage( String subject, String text, User sender, Set<User> users, boolean forceSend )
     {
         // Do nothing
+        return null;
     }
 }

=== removed file 'dhis-2/dhis-services/dhis-service-sms/src/main/java/org/hisp/dhis/sms/outbound/SmsMessageSender.java'
--- dhis-2/dhis-services/dhis-service-sms/src/main/java/org/hisp/dhis/sms/outbound/SmsMessageSender.java	2013-05-15 04:10:55 +0000
+++ dhis-2/dhis-services/dhis-service-sms/src/main/java/org/hisp/dhis/sms/outbound/SmsMessageSender.java	1970-01-01 00:00:00 +0000
@@ -1,164 +0,0 @@
-package org.hisp.dhis.sms.outbound;
-
-/*
- * Copyright (c) 2004-2012, University of Oslo
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright notice, this
- *   list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice,
- *   this list of conditions and the following disclaimer in the documentation
- *   and/or other materials provided with the distribution.
- * * Neither the name of the HISP project nor the names of its contributors may
- *   be used to endorse or promote products derived from this software without
- *   specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-import java.util.HashSet;
-import java.util.Set;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.hisp.dhis.sms.MessageSender;
-import org.hisp.dhis.sms.SmsServiceException;
-import org.hisp.dhis.user.User;
-import org.springframework.scheduling.annotation.Async;
-
-public class SmsMessageSender
-    implements MessageSender
-{
-    private static final Log log = LogFactory.getLog( SmsMessageSender.class );
-
-    // -------------------------------------------------------------------------
-    // Dependencies
-    // -------------------------------------------------------------------------
-
-    private OutboundSmsService outboundSmsService;
-
-    public void setOutboundSmsService( OutboundSmsService outboundSmsService )
-    {
-        this.outboundSmsService = outboundSmsService;
-    }
-
-    // -------------------------------------------------------------------------
-    // MessageSender implementation
-    // -------------------------------------------------------------------------
-
-    /**
-     * Note this methods is invoked asynchronously.
-     */
-    //@Async
-    @SuppressWarnings( "unchecked" )
-    public String sendMessage( String subject, String text, User sender, boolean isPhone, Set<?> recipients,
-        String gatewayId )
-    {
-        String message = null;
-
-        if ( outboundSmsService == null || !outboundSmsService.isEnabled() )
-        {
-            return "outboundsmsservice_is_null_or_unable";
-        }
-
-        text = createMessage( subject, text, sender );
-
-        Set<String> phones = null;
-
-        if ( isPhone )
-        {
-            phones = (Set<String>) recipients;
-        }
-        else
-        {
-            phones = getRecipientsWithoutNotification( (Set<User>) recipients );
-        }
-
-        if ( !phones.isEmpty() && phones.size() > 0 )
-        {
-            message = sendMessage( text, phones, gatewayId );
-        }
-        else
-        {
-            message = "no_recipient";
-        }
-
-        return message;
-    }
-
-    private Set<String> getRecipientsWithoutNotification( Set<User> users )
-    {
-        Set<String> recipients = new HashSet<String>();
-
-        for ( User user : users )
-        {
-            String phoneNumber = user.getPhoneNumber();
-
-            if ( phoneNumber != null && !phoneNumber.trim().isEmpty() )
-            {
-                recipients.add( phoneNumber );
-            }
-        }
-
-        return recipients;
-    }
-
-    private String createMessage( String subject, String text, User sender )
-    {
-        String name = "unknown";
-
-        if ( sender != null )
-        {
-            name = sender.getUsername();
-        }
-
-        if ( subject == null || subject.isEmpty() )
-        {
-            subject = "";
-        }
-        else
-        {
-            subject = " - " + subject;
-        }
-
-        text = "From " + name + subject + ": " + text;
-
-        // Simplistic cutoff 160 characters..
-        int length = text.length();
-
-        return (length > 160) ? text.substring( 0, 157 ) + "..." : text;
-    }
-
-    private String sendMessage( String text, Set<String> recipients, String id )
-    {
-        String message = null;
-        OutboundSms sms = new OutboundSms();
-        sms.setMessage( text );
-        sms.setRecipients( recipients );
-
-        try
-        {
-            message = outboundSmsService.sendMessage( sms, id );
-        }
-        catch ( SmsServiceException e )
-        {
-            message = "Unable to send message through sms: " + sms + e.getCause().getMessage();
-
-            log.warn( "Unable to send message through sms: " + sms, e );
-        }
-
-        return message;
-    }
-
-}

=== modified file 'dhis-2/dhis-services/dhis-service-sms/src/main/java/org/hisp/dhis/sms/outbound/SmsSender.java'
--- dhis-2/dhis-services/dhis-service-sms/src/main/java/org/hisp/dhis/sms/outbound/SmsSender.java	2013-05-15 04:10:55 +0000
+++ dhis-2/dhis-services/dhis-service-sms/src/main/java/org/hisp/dhis/sms/outbound/SmsSender.java	2013-05-20 09:32:19 +0000
@@ -50,38 +50,44 @@
     implements MessageSender
 {
     private static final Log log = LogFactory.getLog( SmsSender.class );
-    
+
     // -------------------------------------------------------------------------
     // Dependencies
     // -------------------------------------------------------------------------
-    
+
     private CurrentUserService currentUserService;
 
     public void setCurrentUserService( CurrentUserService currentUserService )
     {
         this.currentUserService = currentUserService;
     }
-    
+
     private UserService userService;
-    
+
     public void setUserService( UserService userService )
     {
         this.userService = userService;
     }
-    
+
     private OutboundSmsService outboundSmsService;
 
     public void setOutboundSmsService( OutboundSmsService outboundSmsService )
     {
         this.outboundSmsService = outboundSmsService;
     }
-    
+
     @Autowired
     private OutboundSmsTransportService transportService;
-    
+
+    /**
+     * Note this methods is invoked asynchronously.
+     */
+    // @Async
     @Override
-    public void sendMessage( String subject, String text, User sender, Set<User> users, boolean forceSend )
+    public String sendMessage( String subject, String text, User sender, Set<User> users, boolean forceSend )
     {
+        String message = null;
+
         Set<User> toSendUserList = new HashSet<User>();
 
         String gatewayId = transportService.getDefaultGateway();
@@ -91,42 +97,52 @@
             boolean sendSMSNotification = false;
             for ( User user : users )
             {
-                if ( currentUserService.getCurrentUser() != user )
+                if ( !currentUserService.getCurrentUser().equals( user ) )
                 {
-                    UserSetting userSetting = userService.getUserSetting( user, UserSettingService.KEY_MESSAGE_SMS_NOTIFICATION );
-                    if ( userSetting != null )
-                    {
-                        sendSMSNotification = (Boolean) userSetting.getValue();
-                        if ( sendSMSNotification == true )
+                    // check if receiver is raw number or not
+                    if ( user.getFirstName() == null )
+                    {
+                        toSendUserList.add( user );
+                    }
+                    else
+                    {
+                        UserSetting userSetting = userService.getUserSetting( user,
+                            UserSettingService.KEY_MESSAGE_SMS_NOTIFICATION );
+                        if ( userSetting != null )
                         {
-                            toSendUserList.add( user );
-                            sendSMSNotification = false;
+                            sendSMSNotification = (Boolean) userSetting.getValue();
+                            if ( sendSMSNotification == true )
+                            {
+                                toSendUserList.add( user );
+                                sendSMSNotification = false;
+                            }
                         }
                     }
                 }
             }
-            
+
             Set<String> phoneNumbers = null;
 
             if ( outboundSmsService != null || outboundSmsService.isEnabled() )
             {
                 text = createMessage( subject, text, sender );
-                
+
                 phoneNumbers = getRecipientsPhoneNumber( toSendUserList );
-                
+
                 if ( !phoneNumbers.isEmpty() && phoneNumbers.size() > 0 )
                 {
-                    sendMessage( text, phoneNumbers, gatewayId );
+                    message = sendMessage( text, phoneNumbers, gatewayId );
                 }
 
             }
         }
+        return message;
     }
-    
+
     // -------------------------------------------------------------------------
     // Supportive methods
     // -------------------------------------------------------------------------
-    
+
     private String createMessage( String subject, String text, User sender )
     {
         String name = "unknown";
@@ -152,7 +168,7 @@
 
         return (length > 160) ? text.substring( 0, 157 ) + "..." : text;
     }
-    
+
     private Set<String> getRecipientsPhoneNumber( Set<User> users )
     {
         Set<String> recipients = new HashSet<String>();
@@ -169,20 +185,24 @@
 
         return recipients;
     }
-    
-    private void sendMessage( String text, Set<String> recipients, String gateWayId )
+
+    private String sendMessage( String text, Set<String> recipients, String gateWayId )
     {
+        String message = null;
         OutboundSms sms = new OutboundSms();
         sms.setMessage( text );
         sms.setRecipients( recipients );
 
         try
         {
-            outboundSmsService.sendMessage( sms, gateWayId );
+            message = outboundSmsService.sendMessage( sms, gateWayId );
         }
         catch ( SmsServiceException e )
         {
+            message = "Unable to send message through sms: " + sms + e.getCause().getMessage();
+
             log.warn( "Unable to send message through sms: " + sms, e );
         }
+        return message;
     }
 }

=== modified file 'dhis-2/dhis-services/dhis-service-sms/src/main/java/org/hisp/dhis/sms/parse/DefaultParserManager.java'
--- dhis-2/dhis-services/dhis-service-sms/src/main/java/org/hisp/dhis/sms/parse/DefaultParserManager.java	2013-05-09 17:21:51 +0000
+++ dhis-2/dhis-services/dhis-service-sms/src/main/java/org/hisp/dhis/sms/parse/DefaultParserManager.java	2013-05-20 09:32:19 +0000
@@ -34,9 +34,11 @@
 import java.util.Collection;
 import java.util.Collections;
 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.util.TreeMap;
 
 import org.apache.commons.lang.StringUtils;
@@ -51,6 +53,10 @@
 import org.hisp.dhis.dataset.DataSetService;
 import org.hisp.dhis.datavalue.DataValue;
 import org.hisp.dhis.datavalue.DataValueService;
+import org.hisp.dhis.message.Message;
+import org.hisp.dhis.message.MessageConversation;
+import org.hisp.dhis.message.MessageConversationStore;
+import org.hisp.dhis.message.UserMessage;
 import org.hisp.dhis.organisationunit.OrganisationUnit;
 import org.hisp.dhis.period.CalendarPeriodType;
 import org.hisp.dhis.period.DailyPeriodType;
@@ -69,6 +75,7 @@
 import org.hisp.dhis.smscommand.SMSCommandService;
 import org.hisp.dhis.system.util.ValidationUtils;
 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.beans.factory.annotation.Required;
@@ -101,6 +108,13 @@
 
     @Autowired
     private DataSetService dataSetService;
+    
+    private MessageConversationStore messageConversationStore;
+
+    public void setMessageConversationStore( MessageConversationStore messageConversationStore )
+    {
+        this.messageConversationStore = messageConversationStore;
+    }
 
     @Transactional
     public void parse( IncomingSms sms )
@@ -172,11 +186,16 @@
                     runKeyValueParser( sender, message, orgUnits, command );
                     break;
                 }
-                else
+                else if ( ParserType.J2ME_PARSER.equals( command.getParserType() ) )
                 {
                     runJ2MEParser( sender, message, orgUnits, command );
                     break;
                 }
+                else if ( ParserType.ALERT_PARSER.equals( command.getParserType() ) )
+                {
+                    runDhisMessageAlertParser( sender, message, command );
+                    break;
+                }
             }
         }
         if ( !foundCommand )
@@ -249,7 +268,64 @@
 
         markCompleteDataSet( sender, orgUnit, parsedMessage, command, date );
         sendSuccessFeedback( sender, command, parsedMessage, date, orgUnit );
-
+    }
+
+    private void runDhisMessageAlertParser( String senderNumber, String message, SMSCommand command )
+    {
+        /*
+         * IParser parser = new DhisMessageAlertParser();
+         * 
+         * if ( !StringUtils.isBlank( command.getSeparator() ) ) {
+         * parser.setSeparator( command.getSeparator() ); }
+         * 
+         * message = message.trim();
+         * 
+         * Map<String, String> parsedMessage = parser.parse( message );
+         */
+
+        UserGroup userGroup = command.getUserGroup();
+
+        if ( userGroup != null )
+        {
+            Collection users = userService.getUsersByPhoneNumber( senderNumber );
+            if ( users != null && users.size() > 1 )
+            {
+                String messageMoreThanOneUser = "System only accepts sender's number assigned for one user, but found more than one user for this number: ";
+                for ( Iterator<User> i = users.iterator(); i.hasNext(); )
+                {
+                    User user = i.next();
+                    messageMoreThanOneUser += " " + user.getName();
+                    if ( i.hasNext() )
+                    {
+                        messageMoreThanOneUser += ",";
+                    }
+                }
+                throw new SMSParserException( messageMoreThanOneUser );
+            }
+            else if ( users != null && users.size() == 1 )
+            {
+                User sender = (User) users.iterator().next();
+                
+                Set<User> receivers = new HashSet<User>( userGroup.getMembers() );
+                
+                if ( sender != null )
+                {
+                    receivers.add( sender );
+                }
+                
+                MessageConversation conversation = new MessageConversation( command.getName(), sender );
+                
+                conversation.addMessage( new Message( message, null, sender ) );
+                
+                for ( User receiver : receivers )
+                {
+                    boolean read = receiver != null && receiver.equals( sender );
+
+                    conversation.addUserMessage( new UserMessage( receiver, read ) );
+                }
+                messageConversationStore.save( conversation );
+            }
+        }
     }
 
     protected OrganisationUnit selectOrganisationUnit( Collection<OrganisationUnit> orgUnits,
@@ -272,7 +348,7 @@
 
         if ( orgUnit == null && orgUnits.size() > 1 )
         {
-            String messageListingOrgUnits = "Found more then one org unit for this number. Please specify one of the following:";
+            String messageListingOrgUnits = "Found more than one org unit for this number. Please specify one of the following:";
             for ( Iterator<OrganisationUnit> i = orgUnits.iterator(); i.hasNext(); )
             {
                 OrganisationUnit o = i.next();
@@ -597,7 +673,6 @@
     }
 
     // Run the J2ME parser for mobile
-
     private void runJ2MEParser( String sender, String message, Collection<OrganisationUnit> orgUnits, SMSCommand command )
     {
         J2MEDataEntryParser j2meParser = new J2MEDataEntryParser();
@@ -639,7 +714,6 @@
         registerCompleteDataSet( command.getDataset(), period, orgUnit, "mobile" );
 
         sendSuccessFeedback( sender, command, parsedMessage, period, orgUnit );
-
     }
 
     private void sendSuccessFeedback( String sender, SMSCommand command, Map<String, String> parsedMessage,

=== modified file 'dhis-2/dhis-services/dhis-service-sms/src/main/resources/META-INF/dhis/beans.xml'
--- dhis-2/dhis-services/dhis-service-sms/src/main/resources/META-INF/dhis/beans.xml	2013-04-17 09:03:38 +0000
+++ dhis-2/dhis-services/dhis-service-sms/src/main/resources/META-INF/dhis/beans.xml	2013-05-20 09:32:19 +0000
@@ -35,10 +35,6 @@
     <property name="incomingSmsService" ref="org.hisp.dhis.sms.incoming.IncomingSmsService" />
   </bean>
   <!-- SMS Message sender -->
-
-  <bean id="org.hisp.dhis.sms.outbound.SmsMessageSender" class="org.hisp.dhis.sms.outbound.SmsMessageSender">
-    <property name="outboundSmsService" ref="org.hisp.dhis.sms.outbound.OutboundSmsService" />
-  </bean>
   
   <bean id="org.hisp.dhis.sms.outbound.SmsSender" class="org.hisp.dhis.sms.outbound.SmsSender">
     <property name="currentUserService" ref="org.hisp.dhis.user.CurrentUserService" />
@@ -64,6 +60,7 @@
     <property name="dataValueService" ref="org.hisp.dhis.datavalue.DataValueService" />
     <property name="outboundSmsService" ref="org.hisp.dhis.sms.outbound.OutboundSmsService" />  
     <property name="registrationService" ref="org.hisp.dhis.dataset.CompleteDataSetRegistrationService" />
+    <property name="messageConversationStore" ref="org.hisp.dhis.message.MessageConversationStore" />
   </bean>
   
 </beans>

=== removed file 'dhis-2/dhis-services/dhis-service-sms/src/test/java/org/hisp/dhis/sms/outbound/SmsMessageSenderTest.java'
--- dhis-2/dhis-services/dhis-service-sms/src/test/java/org/hisp/dhis/sms/outbound/SmsMessageSenderTest.java	2013-03-13 14:14:24 +0000
+++ dhis-2/dhis-services/dhis-service-sms/src/test/java/org/hisp/dhis/sms/outbound/SmsMessageSenderTest.java	1970-01-01 00:00:00 +0000
@@ -1,57 +0,0 @@
-package org.hisp.dhis.sms.outbound;
-
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.refEq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import java.util.HashSet;
-
-import org.hisp.dhis.user.User;
-import org.junit.Test;
-
-@SuppressWarnings( "serial" )
-public class SmsMessageSenderTest
-{
-    @Test
-    public void testMessageSender()
-    {
-        final User user = getUser();
-
-        SmsMessageSender smsMessageSender = new SmsMessageSender();
-
-        OutboundSmsService outboundSmsService = mock( OutboundSmsService.class );
-        when( outboundSmsService.isEnabled() ).thenReturn( true );
-
-        smsMessageSender.setOutboundSmsService( outboundSmsService );
-        smsMessageSender.sendMessage( "Hello", "hello", user, false, getUserSet( user ), null );
-
-        verify( outboundSmsService ).isEnabled();
-        //verify( userService ).getUserSettings( KEY_MESSAGE_SMS_NOTIFICATION, false );
-        verify( outboundSmsService ).sendMessage( refEq(getSms()), anyString() );
-    }
-
-    private OutboundSms getSms()
-    {
-        OutboundSms sms = new OutboundSms();
-        sms.setMessage( "From null - Hello: hello" );
-        sms.setRecipients( new HashSet<String>() {{ add("222222");}} );
-        return sms;
-    }
-
-    private HashSet<User> getUserSet( final User user )
-    {
-        return new HashSet<User>() {{ add( user ); }};
-    }
-
-    private User getUser()
-    {
-        final User user = new User();
-        user.setId( 1 );
-        user.setPhoneNumber( "222222" );
-        user.setFirstName( "firstName" );
-        user.setSurname( "surname" );
-        return user;
-    }
-}

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/java/org/hisp/dhis/mobile/action/smscommand/CreateSMSCommandForm.java'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/java/org/hisp/dhis/mobile/action/smscommand/CreateSMSCommandForm.java	2013-03-13 10:11:52 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/java/org/hisp/dhis/mobile/action/smscommand/CreateSMSCommandForm.java	2013-05-20 09:32:19 +0000
@@ -32,96 +32,96 @@
 import org.hisp.dhis.sms.parse.ParserType;
 import org.hisp.dhis.smscommand.SMSCommand;
 import org.hisp.dhis.smscommand.SMSCommandService;
+import org.hisp.dhis.user.UserGroup;
+import org.hisp.dhis.user.UserGroupService;
 
 import com.opensymphony.xwork2.Action;
 
 public class CreateSMSCommandForm
     implements Action
 {
+    // -------------------------------------------------------------------------
+    // Dependencies
+    // -------------------------------------------------------------------------
+
     private SMSCommandService smsCommandService;
 
+    public void setSmsCommandService( SMSCommandService smsCommandService )
+    {
+        this.smsCommandService = smsCommandService;
+    }
+
     private DataSetService dataSetService;
 
+    public void setDataSetService( DataSetService dataSetService )
+    {
+        this.dataSetService = dataSetService;
+    }
+
+    private UserGroupService userGroupService;
+
+    public void setUserGroupService( UserGroupService userGroupService )
+    {
+        this.userGroupService = userGroupService;
+    }
+
+    // -------------------------------------------------------------------------
+    // Input && Output
+    // -------------------------------------------------------------------------
+
     private String name;
 
-    private String parser;
+    public void setName( String name )
+    {
+        this.name = name;
+    }
 
     private ParserType parserType;
-    
-    private int selectedDataSetID; 
-    
+
+    public void setParserType( ParserType parserType )
+    {
+        this.parserType = parserType;
+    }
+
+    private Integer selectedDataSetID;
+
+    public void setSelectedDataSetID( Integer selectedDataSetID )
+    {
+        this.selectedDataSetID = selectedDataSetID;
+    }
+
+    private Integer userGroupID;
+
+    public void setUserGroupID( Integer userGroupID )
+    {
+        this.userGroupID = userGroupID;
+    }
+
+    // -------------------------------------------------------------------------
+    // Action implementation
+    // -------------------------------------------------------------------------
+
     @Override
     public String execute()
         throws Exception
     {
-        DataSet dataset = getDataSetService().getDataSet( getSelectedDataSetID() );
-        
+
         SMSCommand command = new SMSCommand();
         command.setName( name );
-        command.setDataset( dataset );
         command.setParserType( parserType );
-        
+        if ( parserType.equals( ParserType.KEY_VALUE_PARSER ) || parserType.equals( ParserType.J2ME_PARSER ) )
+        {
+            DataSet dataset = dataSetService.getDataSet( selectedDataSetID );
+            command.setDataset( dataset );
+        }
+        else if ( parserType.equals( ParserType.ALERT_PARSER ) )
+        {
+            UserGroup userGroup = new UserGroup();
+            userGroup = userGroupService.getUserGroup( userGroupID );
+            command.setUserGroup( userGroup );
+        }
+
         smsCommandService.save( command );
         return SUCCESS;
     }
-
-    public SMSCommandService getSmsCommandService()
-    {
-        return smsCommandService;
-    }
-
-    public void setSmsCommandService( SMSCommandService smsCommandService )
-    {
-        this.smsCommandService = smsCommandService;
-    }
-
-    public String getName()
-    {
-        return name;
-    }
-
-    public void setName( String name )
-    {
-        this.name = name;
-    }
-
-    public String getParser()
-    {
-        return parser;
-    }
-
-    public void setParser( String parser )
-    {
-        this.parser = parser;
-    }
-
-    public int getSelectedDataSetID()
-    {
-        return selectedDataSetID;
-    }
-
-    public void setSelectedDataSetID( int selectedDataSetID )
-    {
-        this.selectedDataSetID = selectedDataSetID;
-    }
-
-    public DataSetService getDataSetService()
-    {
-        return dataSetService;
-    }
-
-    public void setDataSetService( DataSetService dataSetService )
-    {
-        this.dataSetService = dataSetService;
-    }
-
-    public ParserType getParserType()
-    {
-        return parserType;
-    }
-
-    public void setParserType( ParserType parserType )
-    {
-        this.parserType = parserType;
-    }
 }

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/java/org/hisp/dhis/mobile/action/smscommand/SMSCommandAction.java'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/java/org/hisp/dhis/mobile/action/smscommand/SMSCommandAction.java	2013-03-13 10:11:52 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/java/org/hisp/dhis/mobile/action/smscommand/SMSCommandAction.java	2013-05-20 09:32:19 +0000
@@ -42,19 +42,81 @@
 import org.hisp.dhis.smscommand.SMSCode;
 import org.hisp.dhis.smscommand.SMSCommand;
 import org.hisp.dhis.smscommand.SMSCommandService;
+import org.hisp.dhis.user.UserGroup;
+import org.hisp.dhis.user.UserGroupService;
 
 import com.opensymphony.xwork2.Action;
 
 public class SMSCommandAction
     implements Action
 {
+    
+    // -------------------------------------------------------------------------
+    // Dependencies
+    // -------------------------------------------------------------------------
+    
     private SMSCommandService smsCommandService;
+    
+    public void setSmsCommandService( SMSCommandService smsCommandService )
+    {
+        this.smsCommandService = smsCommandService;
+    }
 
     private DataSetService dataSetService;
+    
+    public void setDataSetService( DataSetService dataSetService )
+    {
+        this.dataSetService = dataSetService;
+    }
+    
+    private UserGroupService userGroupService;
+    
+
+    public void setUserGroupService( UserGroupService userGroupService )
+    {
+        this.userGroupService = userGroupService;
+    }
+    
+    // -------------------------------------------------------------------------
+    // Input & Output
+    // -------------------------------------------------------------------------
+    
+    private List<UserGroup> userGroupList;
+
+    public List<UserGroup> getUserGroupList()
+    {
+        return userGroupList;
+    }
 
     private int selectedCommandID = -1;
+    
+
+    public int getSelectedCommandID()
+    {
+        return selectedCommandID;
+    }
+
+    public void setSelectedCommandID( int selectedCommandID )
+    {
+        this.selectedCommandID = selectedCommandID;
+    }
 
     private Map<String, String> codes = new HashMap<String, String>();
+    
+
+    public Map<String, String> getCodes()
+    {
+        return codes;
+    }
+
+    public void setCodes( Map<String, String> codes )
+    {
+        this.codes = codes;
+    }
+    
+    public ParserType[] getParserType(){       
+        return ParserType.values();
+    }
 
     // -------------------------------------------------------------------------
     // Action implementation
@@ -70,9 +132,16 @@
                 codes.put( "" + x.getDataElement().getId() + x.getOptionId(), x.getCode() );
             }
         }
+        
+        userGroupList = new ArrayList<UserGroup>(userGroupService.getAllUserGroups());
+        
         return SUCCESS;
     }
 
+    // -------------------------------------------------------------------------
+    // Supporting methods
+    // -------------------------------------------------------------------------
+    
     public List<DataElement> getDataSetElements()
     {
         if ( getSMSCommand() != null )
@@ -91,7 +160,7 @@
 
     public Collection<DataSet> getDataSets()
     {
-        return getDataSetService().getAllDataSets();
+        return dataSetService.getAllDataSets();
     }
 
     public Collection<SMSCommand> getSMSCommands()
@@ -110,48 +179,4 @@
             return null;
         }
     }
-
-    public SMSCommandService getSmsCommandService()
-    {
-        return smsCommandService;
-    }
-
-    public void setSmsCommandService( SMSCommandService smsCommandService )
-    {
-        this.smsCommandService = smsCommandService;
-    }
-
-    public int getSelectedCommandID()
-    {
-        return selectedCommandID;
-    }
-
-    public void setSelectedCommandID( int selectedCommandID )
-    {
-        this.selectedCommandID = selectedCommandID;
-    }
-
-    public DataSetService getDataSetService()
-    {
-        return dataSetService;
-    }
-
-    public void setDataSetService( DataSetService dataSetService )
-    {
-        this.dataSetService = dataSetService;
-    }
-
-    public Map<String, String> getCodes()
-    {
-        return codes;
-    }
-
-    public void setCodes( Map<String, String> codes )
-    {
-        this.codes = codes;
-    }
-    
-    public ParserType[] getParserType(){       
-        return ParserType.values();
-    }
 }

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/resources/META-INF/dhis/beans.xml'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/resources/META-INF/dhis/beans.xml	2013-03-12 05:40:42 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/resources/META-INF/dhis/beans.xml	2013-05-20 09:32:19 +0000
@@ -141,6 +141,8 @@
 		<property name="smsCommandService" ref="smsCommandService" />
 		<property name="dataSetService"
 			ref="org.hisp.dhis.dataset.DataSetService" />
+		<property name="userGroupService"
+			ref="org.hisp.dhis.user.UserGroupService" />	
 
 	</bean>
 
@@ -162,6 +164,8 @@
 		<property name="smsCommandService" ref="smsCommandService" />
 		<property name="dataSetService"
 			ref="org.hisp.dhis.dataset.DataSetService" />
+		<property name="userGroupService"
+			ref="org.hisp.dhis.user.UserGroupService" />
 	</bean>
 
 	<bean

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/resources/org/hisp/dhis/mobile/i18n_module.properties'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/resources/org/hisp/dhis/mobile/i18n_module.properties	2013-03-12 05:40:42 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/resources/org/hisp/dhis/mobile/i18n_module.properties	2013-05-20 09:32:19 +0000
@@ -111,8 +111,10 @@
 sms_command_validation_alert=Fix validation problems before you save
 command_management=Command management
 code=Code
-name=Name 
-dataset=Dataset
+name=Name:
+dataset=Dataset:
+parser=Parser:
+userGroup= User Group:
 selected_dataset=Selected dataset
 code_value_separator=Code and value Separator
 no_codes_message=Reply message if no codes are sent (only the command):

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/resources/struts.xml'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/resources/struts.xml	2013-04-09 07:45:22 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/resources/struts.xml	2013-05-20 09:32:19 +0000
@@ -163,7 +163,7 @@
       <result name="success" type="velocity">/main.vm</result>
       <param name="page">/dhis-web-maintenance-mobile/smscommand/new-sms-command.vm</param>
       <param name="menu">/dhis-web-maintenance-mobile/menu.vm</param>
-      <param name="javascripts">../dhis-web-commons/oust/oust.js,javascript/sendSMS.js</param>
+      <param name="javascripts">../dhis-web-commons/oust/oust.js,javascript/command.js</param>
       <param name="requiredAuthorities">F_MOBILE_SENDSMS</param>  
     </action>
     

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/webapp/dhis-web-maintenance-mobile/javascript/gateway.js'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/webapp/dhis-web-maintenance-mobile/javascript/gateway.js	2012-09-19 07:48:54 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/webapp/dhis-web-maintenance-mobile/javascript/gateway.js	2013-05-20 09:32:19 +0000
@@ -1,5 +1,4 @@
 currentType = '';
-
 function changeValueType( value )
 {
 	hideAll();

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/webapp/dhis-web-maintenance-mobile/smscommand/new-sms-command.vm'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/webapp/dhis-web-maintenance-mobile/smscommand/new-sms-command.vm	2013-02-03 10:13:17 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-mobile/src/main/webapp/dhis-web-maintenance-mobile/smscommand/new-sms-command.vm	2013-05-20 09:32:19 +0000
@@ -1,5 +1,10 @@
 #parse("/dhis-web-maintenance-mobile/smscommand/validate_javascript.vm")
-
+<script type="text/javascript">
+	jQuery(document).ready(function() {
+		
+		changeParserType( getFieldValue( 'parserType' ) );
+	});
+</script>
 <h3>Add command</h3>
 <form id="newSMSCommand" name="updateSMSCommand" action="createSMSCommandForm.action" method="post">
    
@@ -7,43 +12,50 @@
 	 <col/> ## Labels
     <col/> ## Input
     <thead>
-      <tr>
-        <th colspan="2">$i18n.getString( "command_details" )</th>
-      </tr>
+		<tr><th colspan="2">$i18n.getString( "command_details" )</th></tr>
     </thead>
 		<tr>
-			<td>
-				$i18n.getString( "name" )
-			</td>
+			<td>$i18n.getString( "name" )</td>
 			<td>
 				<input type="text" value="" id="name" name="name" style="width:20em" class="validate"/>
 			</td>
 		</tr>
-		      <tr>
-		      <td>
-		      $i18n.getString( "parser" )
-		      </td>
+		<tr>
+			<td>$i18n.getString( "parser" )</td>
             <td>
-	   <select name="parserType" >
-                #foreach( $x in $parserType )
-                    <option value="$x">$x</option>
-                #end
-        </select> 	  
-                    </td>
+				<select id="parserType" name="parserType" style="width:100%;" onchange="changeParserType( this.value )">
+				#foreach( $type in $parserType )
+					<option value="$type">$type</option>
+				#end
+				</select>	  
+            </td>
         </tr>
-		</tr>
-		<tr>
-			<td>
-			$i18n.getString( "dataset" )
-			</td>
-			<td>
-				<select name="selectedDataSetID" >
-				#foreach( $dataSet in $dataSets )
-			        <option value="$dataSet.id" #if ($SMSCommand.dataset.id == $dataSet.id) selected #end >$dataSet.displayName</option>
-				#end
-				</select> 
-			</td>
-		</tr>
+		<tbody id="dataSetParser">
+			<tr>
+				<td>$i18n.getString( "dataset" )</td>
+				<td>
+					<select name="selectedDataSetID" >
+					#foreach( $dataSet in $dataSets )
+						<option value="$dataSet.id" #if ($SMSCommand.dataset.id == $dataSet.id) selected #end >$dataSet.displayName</option>
+					#end
+					</select> 
+				</td>
+			</tr>
+		</tbody>
+		
+		<tbody id="alertParser">
+			<tr>
+				<td>$i18n.getString( "userGroup" )</td>
+				<td>
+					<select name="userGroupID" >
+					#foreach( $userGroup in $userGroupList )
+						<option value="$userGroup.id">$userGroup.name</option>
+					#end
+					</select>
+				</td>
+			</tr>
+		</tbody>
+		
 		<tr>
 			<td colspan="2">
 			     <input id="save" type="submit"  style="width: 100px" value="$i18n.getString( "save" )" />

=== modified file 'dhis-2/dhis-web/dhis-web-sms/src/main/java/org/hisp/dhis/sms/outcoming/ProcessingSendSMSAction.java'
--- dhis-2/dhis-web/dhis-web-sms/src/main/java/org/hisp/dhis/sms/outcoming/ProcessingSendSMSAction.java	2013-05-15 04:10:55 +0000
+++ dhis-2/dhis-web/dhis-web-sms/src/main/java/org/hisp/dhis/sms/outcoming/ProcessingSendSMSAction.java	2013-05-20 09:32:19 +0000
@@ -39,11 +39,12 @@
 import org.codehaus.jackson.map.JsonMappingException;
 import org.codehaus.jackson.map.ObjectMapper;
 import org.hisp.dhis.i18n.I18n;
+import org.hisp.dhis.message.MessageSender;
 import org.hisp.dhis.organisationunit.OrganisationUnit;
 import org.hisp.dhis.oust.manager.SelectionTreeManager;
 import org.hisp.dhis.patient.Patient;
 import org.hisp.dhis.patient.PatientService;
-import org.hisp.dhis.sms.MessageSender;
+
 import org.hisp.dhis.sms.outbound.OutboundSmsTransportService;
 import org.hisp.dhis.user.CurrentUserService;
 import org.hisp.dhis.user.User;
@@ -77,11 +78,15 @@
     private UserGroupService userGroupService;
 
     @Autowired
+    private OutboundSmsTransportService transportService;
+
     private MessageSender messageSender;
 
-    @Autowired
-    private OutboundSmsTransportService transportService;
-
+    public void setMessageSender( MessageSender messageSender )
+    {
+        this.messageSender = messageSender;
+    }
+    
     // -------------------------------------------------------------------------
     // Input & Output
     // -------------------------------------------------------------------------
@@ -170,15 +175,23 @@
         }
 
         User currentUser = currentUserService.getCurrentUser();
-
+        
+        Set<User> recipientsList = new HashSet<User>();
+        
         if ( sendTarget != null && sendTarget.equals( "phone" ) )
         {
             try
             {
                 ObjectMapper mapper = new ObjectMapper().setVisibility( JsonMethod.FIELD, Visibility.ANY );
                 mapper.configure( DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false );
-
                 recipients = mapper.readValue( recipients.iterator().next(), Set.class );
+                
+                for( String each: recipients )
+                {
+                    User user = new User();
+                    user.setPhoneNumber( each );
+                    recipientsList.add( user );
+                }
             }
             catch ( JsonParseException e )
             {
@@ -192,7 +205,9 @@
             {
                 e.printStackTrace();
             }
-            message = messageSender.sendMessage( smsSubject, smsMessage, currentUser, true, recipients, gatewayId );
+            //message = messageSender.sendMessage( smsSubject, smsMessage, currentUser, true, recipients, gatewayId );
+            message = messageSender.sendMessage( smsSubject, smsMessage, currentUser, recipientsList, false );
+            
         }
         else if ( sendTarget.equals( "userGroup" ) )
         {
@@ -212,8 +227,8 @@
                 return ERROR;
             }
 
-            message = messageSender.sendMessage( smsSubject, smsMessage, currentUser, false, group.getMembers(),
-                gatewayId );
+            //message = messageSender.sendMessage( smsSubject, smsMessage, currentUser, false, group.getMembers(), gatewayId );
+            message = messageSender.sendMessage( smsSubject, smsMessage, currentUser, group.getMembers(), false );
         }
         else if ( sendTarget.equals( "user" ) )
         {
@@ -221,21 +236,24 @@
 
             if ( units != null && !units.isEmpty() )
             {
-                Set<User> users = new HashSet<User>();
+                //Set<User> users = new HashSet<User>();
 
                 for ( OrganisationUnit unit : units )
                 {
-                    users.addAll( unit.getUsers() );
+                    //users.addAll( unit.getUsers() );
+                    recipientsList.addAll( unit.getUsers() );
                 }
 
-                if ( users.isEmpty() )
+                //if ( users.isEmpty() )
+                if ( recipientsList.isEmpty() )
                 {
                     message = i18n.getString( "there_is_no_user_assigned_to_selected_units" );
 
                     return ERROR;
                 }
 
-                message = messageSender.sendMessage( smsSubject, smsMessage, currentUser, false, users, gatewayId );
+                //message = messageSender.sendMessage( smsSubject, smsMessage, currentUser, false, users, gatewayId );
+                message = messageSender.sendMessage( smsSubject, smsMessage, currentUser, recipientsList, false );
             }
         }
         else if ( sendTarget.equals( "unit" ) )
@@ -244,23 +262,27 @@
             {
                 if ( unit.getPhoneNumber() != null && !unit.getPhoneNumber().isEmpty() )
                 {
-                    recipients.add( unit.getPhoneNumber() );
+                    //recipients.add( unit.getPhoneNumber() );
+                    User user = new User();
+                    user.setPhoneNumber( unit.getPhoneNumber() );
+                    recipientsList.add( user );
                 }
             }
 
-            if ( recipients.isEmpty() )
+            if ( recipientsList.isEmpty() )
             {
                 message = i18n.getString( "selected_units_have_no_phone_number" );
 
                 return ERROR;
             }
 
-            message = messageSender.sendMessage( smsSubject, smsMessage, currentUser, true, recipients, gatewayId );
+            //message = messageSender.sendMessage( smsSubject, smsMessage, currentUser, true, recipients, gatewayId );
+            message = messageSender.sendMessage( smsSubject, smsMessage, currentUser, recipientsList, false);
         }
         else
         {
             Patient patient = null;
-            Set<String> phones = new HashSet<String>();
+            //Set<String> phones = new HashSet<String>();
 
             try
             {
@@ -288,18 +310,22 @@
 
                 if ( patient != null && patient.getPhoneNumber() != null && !patient.getPhoneNumber().isEmpty() )
                 {
-                    phones.add( patient.getPhoneNumber() );
+                    //phones.add( patient.getPhoneNumber() );
+                    User user = new User();
+                    user.setPhoneNumber( patient.getPhoneNumber() );
+                    recipientsList.add( user );
                 }
             }
 
-            if ( phones.isEmpty() )
+            if ( recipientsList.isEmpty() )
             {
                 message = i18n.getString( "selected_persons_have_no_phone_number" );
 
                 return ERROR;
             }
 
-            message = messageSender.sendMessage( smsSubject, smsMessage, currentUser, true, phones, gatewayId );
+            //message = messageSender.sendMessage( smsSubject, smsMessage, currentUser, true, phones, gatewayId );
+            message = messageSender.sendMessage( smsSubject, smsMessage, currentUser, recipientsList, false);
         }
 
         if ( message != null && !message.equals( "success" ) )

=== modified file 'dhis-2/dhis-web/dhis-web-sms/src/main/resources/META-INF/dhis/beans.xml'
--- dhis-2/dhis-web/dhis-web-sms/src/main/resources/META-INF/dhis/beans.xml	2013-03-12 05:40:42 +0000
+++ dhis-2/dhis-web/dhis-web-sms/src/main/resources/META-INF/dhis/beans.xml	2013-05-20 09:32:19 +0000
@@ -1,27 +1,26 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <beans xmlns="http://www.springframework.org/schema/beans";
-  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
-  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd";>
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd";>
 
 	<bean id="org.hisp.dhis.sms.input.SMSInput" class="org.hisp.dhis.sms.input.SMSInput">
-		<property name="incomingSmsService" ref="org.hisp.dhis.sms.incoming.IncomingSmsService" />
-	</bean>
+		<property name="incomingSmsService"
+			ref="org.hisp.dhis.sms.incoming.IncomingSmsService" />
+	</bean>
 
-	<bean id="org.hisp.dhis.sms.outcoming.ShowSendSMSFormAction"
-		class="org.hisp.dhis.sms.outcoming.ShowSendSMSFormAction"
-		scope="prototype" />
-		
-	<bean
-		id="org.hisp.dhis.sms.outcoming.ShowSendSMSBeneficiaryFormAction"
+	<bean id="org.hisp.dhis.sms.outcoming.ShowSendSMSFormAction"
+		class="org.hisp.dhis.sms.outcoming.ShowSendSMSFormAction" scope="prototype" />
+
+	<bean id="org.hisp.dhis.sms.outcoming.ShowSendSMSBeneficiaryFormAction"
 		class="org.hisp.dhis.sms.outcoming.ShowSendSMSBeneficiaryFormAction"
 		scope="prototype" />
 
 	<bean id="org.hisp.dhis.sms.outcoming.ProcessingSendSMSAction"
-		class="org.hisp.dhis.sms.outcoming.ProcessingSendSMSAction"
-		scope="prototype" />
+		class="org.hisp.dhis.sms.outcoming.ProcessingSendSMSAction" scope="prototype">
+		<property name="messageSender" ref="org.hisp.dhis.sms.outbound.SmsSender" />
+	</bean>
 
-	<bean id="org.hisp.dhis.sms.outcoming.SearchPatientAction"
-		class="org.hisp.dhis.sms.outcoming.SearchPatientAction"
-		scope="prototype" />
-		
+	<bean id="org.hisp.dhis.sms.outcoming.SearchPatientAction" class="org.hisp.dhis.sms.outcoming.SearchPatientAction"
+		scope="prototype" />
+
 </beans>

=== modified file 'dhis-2/dhis-web/dhis-web-sms/src/main/webapp/dhis-web-sms/smserror.vm'
--- dhis-2/dhis-web/dhis-web-sms/src/main/webapp/dhis-web-sms/smserror.vm	2012-06-18 06:14:19 +0000
+++ dhis-2/dhis-web/dhis-web-sms/src/main/webapp/dhis-web-sms/smserror.vm	2013-05-20 09:32:19 +0000
@@ -1,6 +1,6 @@
 <h2 style="color:red;">SMS error!</h2>
 
-<br/><br/><a href="./testsms.action">Back to SMS Test page</a>
+<br/><br/><a href="./testSMS.action">Back to SMS Test page</a>
 
 <div id="footer">
 <h2>$i18n.getString( "navigate_to" )</h2>

=== modified file 'dhis-2/dhis-web/dhis-web-sms/src/main/webapp/dhis-web-sms/smssuccess.vm'
--- dhis-2/dhis-web/dhis-web-sms/src/main/webapp/dhis-web-sms/smssuccess.vm	2012-06-18 06:14:19 +0000
+++ dhis-2/dhis-web/dhis-web-sms/src/main/webapp/dhis-web-sms/smssuccess.vm	2013-05-20 09:32:19 +0000
@@ -1,6 +1,6 @@
 <h2 style="color:green;">SMS success!</h2>
 
-<br/><br/><a href="./testsms.action">Back to SMS Test page</a>
+<br/><br/><a href="./testSMS.action">Back to SMS Test page</a>
 <div id="footer">
 <h2>$i18n.getString( "navigate_to" )</h2>
 <ul>