Code

Updated table summary
[gosa.git] / gosa-plugins / mail / personal / mail / class_mailAccount.inc
index 3c2393106a411c9159383bce5213cf6011bda43d..5be08f55851775a09c7fd643d8aca6760119ac26 100644 (file)
@@ -1,27 +1,61 @@
 <?php
 <?php
-/*! \brief   mail plugin
-  \author  Cajus Pollmeier <pollmeier@gonicus.de>
-  \version 2.00
-  \date    24.07.2003
+/*! 
+  \brief   mail plugin
+  \author  Fabian Hicker  <Fabian.Hickert@GONICUS.de>
+  \version 2.6.2
+  \date    03.12.2007
 
   This class provides the functionality to read and write all attributes
 
   This class provides the functionality to read and write all attributes
-  relevant for gosaMailAccounts from/to the LDAP. It does syntax checking
-  and displays the formulars required.
+  relevant for gosaMailAccounts from/to the LDAP. 
+  It does syntax checking and displays the formulars required.
+  Special handling like sieve or imap actions will be implemented 
+  by the mailMethods.
+
+
+Functions :
+
+ - mailAccount (&$config, $dn= NULL)
+ - execute()
+ - save_object()
+ - get_vacation_templates()
+ - addForwarder($address)
+ - delForwarder($addresses)
+ - addAlternate($address)
+ - delAlternate($addresses)
+ - prepare_vacation_template($contents)
+ - remove_from_parent()
+ - save()
+ - check()
+ - adapt_from_template($dn, $skip= array())
+ - getCopyDialog()
+ - saveCopyDialog()
+ - PrepareForCopyPaste($source)
+ - get_multi_edit_values()
+ - multiple_check()
+ - set_multi_edit_values($values)
+ - init_multiple_support($attrs,$all)
+ - get_multi_init_values()
+ - multiple_execute()
+ - multiple_save_object()
+ - make_name($attrs)
+ - plInfo()
+
+
  */
 
 class mailAccount extends plugin
 {
   /* Definitions */
  */
 
 class mailAccount extends plugin
 {
   /* Definitions */
-  var $plHeadline         = "Mail";
-  var $plDescription      = "This does something";
-  var $method             = "mailMethod";
+  var $plHeadline     = "Mail";
+  var $plDescription  = "This does something";
+  var $view_logged    = FALSE;
+  var $is_account     = FALSE;
+  var $initially_was_account = FALSE;
 
 
-  var $gosaVacationStart                  = 0;
-  var $gosaVacationStop                   = 0;
-  var $view_logged = FALSE;
-
-  /* plugin specific values */
+  /* GOsa mail attributes */
   var $mail                               = "";
   var $mail                               = "";
+  var $gosaVacationStart                  = "";
+  var $gosaVacationStop                   = "";
   var $gosaMailAlternateAddress           = array();
   var $gosaMailForwardingAddress          = array();
   var $gosaMailDeliveryMode               = "[L        ]";
   var $gosaMailAlternateAddress           = array();
   var $gosaMailForwardingAddress          = array();
   var $gosaMailDeliveryMode               = "[L        ]";
@@ -32,200 +66,147 @@ class mailAccount extends plugin
   var $gosaSpamSortLevel                  = "";
   var $gosaSpamMailbox                    = "";
 
   var $gosaSpamSortLevel                  = "";
   var $gosaSpamMailbox                    = "";
 
-  var $quotaUsage                         = 0;
-  var $forward_dialog                     = FALSE;
-  var $folder_prefix                      = "";
-  var $mailboxList                        = array("INBOX");
-  var $default_permissions                = "none";
-  var $member_permissions                 = "post";
-  var $members                            = array();
-  var $admins                             = array();
-  var $vacations                          = array();
-  var $perms                              = array(  "lrs"       => "read", 
-                                                    "lrsp"      => "post", 
-                                                    "lrsip"     => "append",
-                                                    "lrswipcd"  => "write", 
-                                                    "lrswipcda" => "all" );
-
-  /* attribute list for save action */
-  var $attributes= array("mail", "gosaMailServer", "gosaMailQuota", "gosaMailMaxSize","gosaMailForwardingAddress",
-      "gosaMailDeliveryMode", "gosaSpamSortLevel", "gosaSpamMailbox","gosaMailAlternateAddress","gosaVacationStart","gosaVacationStop",
-      "gosaVacationMessage", "gosaMailAlternateAddress", "gosaMailForwardingAddress");
-  var $objectclasses= array("gosaMailAccount");
-  var $uid              = "";
+  /* The methods defaults */
+  var $quotaUsage     = -1; // Means unknown
 
 
+  var $mailMethod      = NULL;
+  var $MailDomain      = "";
+  var $sieveManagementUsed = FALSE;
+  var $vacationTemplates = array();
   var $sieve_management = NULL;
   var $sieve_management = NULL;
-  var $multiple_support = TRUE;
-
-  /* constructor, if 'dn' is set, the node loads the given
-     'dn' from LDAP */
-  function mailAccount (&$config, $dn= NULL)
-  {
-    global $class_mapping;
-
-    $this->gosaVacationStart = time();
-    $this->gosaVacationStop = time();
+  var $mailAddressSelect = FALSE;
+  var $initial_uid    = "";
+  var $mailDomainPart = "";
+  var $mailDomainParts = array();
+  var $MailBoxes = array("INBOX");
+
+  /* Used LDAP attributes && classes */
+  var $attributes= array(
+      "mail", "gosaMailServer","gosaMailQuota", "gosaMailMaxSize","gosaMailForwardingAddress",
+      "gosaMailDeliveryMode", "gosaSpamSortLevel", "gosaSpamMailbox","gosaMailAlternateAddress",
+      "gosaVacationStart","gosaVacationStop", "gosaVacationMessage", "gosaMailAlternateAddress", 
+      "gosaMailForwardingAddress");
+  var $objectclasses= array("gosaMailAccount");
 
 
-    /* Load bases attributes */
-    plugin::plugin($config, $dn);
+  var $multiple_support = TRUE;
 
 
-    /* Set uid */
-    if(isset($this->attrs['uid'])){
-      $this->uid = $this->attrs['uid'][0];
-    }
-    if(is_array($this->gosaMailServer) && isset($this->gosaMailServer[0])){
-      $this->gosaMailServer = $this->gosaMailServer[0];
-    }
+  var $uid = "";
+  var $cn  = "";
 
 
-    /* Save initial account state */
-    $this->initially_was_account= $this->is_account;
 
 
-    /*  Set mailMethod to the one defined in gosa.conf */
-    if (isset($this->config->current['MAILMETHOD'])){
-      $method= $this->config->current['MAILMETHOD'];
+  /*! \brief  Initialize the mailAccount 
+   */
+  function __construct (&$config, $dn= NULL)
+  {
+    plugin::plugin($config,$dn); 
 
 
-      $cls = get_correct_class_name("mailMethod$method");
-      if ($cls && class_exists($cls)){
-        $this->method= $cls;
-      } else {
-        msg_dialog::display(_("Configuration error"), sprintf(_("Mail method '%s' is unknown!"), $method), ERROR_DIALOG);
+    /* Get attributes from parent object 
+     */
+    foreach(array("uid","cn") as $attr){
+      if(isset($this->parent->by_object['group']) && isset($this->parent->by_object['group']->$attr)){
+        $this->$attr = &$this->parent->by_object['group']->$attr;
+      }elseif(isset($this->attrs[$attr])){
+        $this->$attr = $this->attrs[$attr][0];
       }
     }
 
       }
     }
 
-    
-    /* Create the account prefix  user. user/ 
-       Preset folder prefix. Will change it later to respect
-       altnamespace. */
-    if (isset($this->config->current['CYRUSUNIXSTYLE']) && $this->config->current['CYRUSUNIXSTYLE'] == "true"){
-      $this->folder_prefix= "user/";
-    }elseif (isset($this->config->data['MAIN']['CYRUSUNIXSTYLE']) && $this->config->data['MAIN']['CYRUSUNIXSTYLE'] == "true"){
-      $this->folder_prefix= "user/";
-    } else {
-      $this->folder_prefix= "user.";
-    }
-    
-    /* This is not a new account, parse additional attributes */
-    if (($dn !== NULL) && ($dn != "new") && $this->is_account){
+    /* Intialize the used mailMethod
+     */
+    $tmp = new mailMethod($config,$this);
+    $this->mailMethod       = $tmp->get_method();
+    $this->mailMethod->fixAttributesOnLoad();
+    $this->mailDomainParts  = $this->mailMethod->getMailDomains();
+    $this->SpamLevels = $this->mailMethod->getSpamLevels();
 
 
-      /* Load attributes containing arrays */
-      foreach (array("gosaMailAlternateAddress", "gosaMailForwardingAddress") as $val){
-        $this->$val= array();
-        if (isset($this->attrs["$val"]["count"])){
-          for ($i= 0; $i<$this->attrs["$val"]["count"]; $i++){
-            array_push($this->$val, $this->attrs["$val"][$i]);
-          }
-        }
-      }
+    /* Remember account status 
+     */
+    $this->initially_was_account = $this->is_account;
 
 
+    /* Initialize vacation settings, if enabled.
+     */   
+    if(empty($this->gosaVacationStart) && $this->mailMethod->vacationRangeEnabled()){
+      $this->gosaVacationStart = time();
+      $this->gosaVacationStop = time();
+    }
 
 
-      /* Only do IMAP actions if gosaMailServer attribute is set */
-      if (isset ($this->attrs["gosaMailServer"][0])){
+    /* Read vacation templates 
+     */
+    $this->vacationTemplates = $this->get_vacation_templates();
 
 
-        $method = new $this->method($this->config);
-        $id     = $method->uattrib;
+    /* Initialize configured values 
+     */ 
+    if($this->is_account){
 
 
-        /* Adapt attributes if needed */
-        $method->fixAttributesOnLoad($this);
+      if($this->mailMethod->connect() && $this->mailMethod->account_exists()){
 
 
-        /* FixAttributesOnLoad possibly creates an array out of gosaMailServer.
-            If the mail tab wasn't opened once before saving, the account can't be saved */
-        if(is_array($this->gosaMailServer)){
-          $this->gosaMailServer = $this->gosaMailServer[0];
+        /* Read quota */
+        $this->gosaMailQuota = $this->mailMethod->getQuota($this->gosaMailQuota);
+        $this->quotaUsage    = $this->mailMethod->getQuotaUsage($this->quotaUsage);
+        if($this->mailMethod->is_error()){
+          msg_dialog::display(_("Mail error"), sprintf(_("Cannot read quota settings: %s"), 
+                $this->mailMethod->get_error()), ERROR_DIALOG);
+        }
+        
+        /* Read mailboxes */
+        $this->MailBoxes = $this->mailMethod->getMailboxList($this->MailBoxes);
+        if($this->mailMethod->is_error()){
+          msg_dialog::display(_("Mail error"), sprintf(_("Cannot get list of mailboxes: %s"), 
+                $this->mailMethod->get_error()), ERROR_DIALOG);
         }
         }
-
-        if ($method->connect($this->attrs["gosaMailServer"][0])){
-
-          /* Update quota values */
-          $quota= $method->getQuota($this->folder_prefix.$this->$id);
-         
-          if($quota){
-            if ($quota['gosaMailQuota'] == 2147483647){
-              $this->quotaUsage     = "";
-              $this->gosaMailQuota  = "";
-            } else {
-              $this->quotaUsage     = $quota['quotaUsage'];
-              $this->gosaMailQuota  = $quota['gosaMailQuota'];
-            }
-          }else{
-            $this->quotaUsage     = "";
-            $this->gosaMailQuota  = "";
-          }
-
-          /* Get mailboxes / folder like INBOX ..*/
-          $this->mailboxList= $method->getMailboxList($this->folder_prefix.$this->$id,$this->$id);
           
           
-          $method->disconnect();
-        }else{
-          /* Could not connect to ldap.
-           */
-          if (isset($this->attrs['gosaMailQuota'][0])){
-            $this->gosaMailQuota = $this->attrs['gosaMailQuota'][0];
+      }elseif(!$this->mailMethod->is_connected()){
+        msg_dialog::display(_("Mail error"), sprintf(_("Mail method cannot connect: %s"), 
+              $this->mailMethod->get_error()), ERROR_DIALOG);
+      }elseif(!$this->mailMethod->account_exists()){
+        msg_dialog::display(_("Mail error"), sprintf(_("Mailbox '%s' doesn't exists on mail server: %s"), 
+              $this->mailMethod->get_account_id(),$this->gosaMailServer), ERROR_DIALOG);
+      }
+
+      /* If the doamin part is selectable, we have to split the mail address
+       */
+      if(!(!$this->mailMethod->isModifyableMail() && $this->is_account)){
+        if($this->mailMethod->domainSelectionEnabled()){
+          $this->mailDomainPart = preg_replace("/^[^@]*+@/","",$this->mail);
+          $this->mail = preg_replace("/@.*$/","\\1",$this->mail);
+          if(!in_array($this->mailDomainPart,$this->mailDomainParts)){
+            $this->mailDomainParts[] = $this->mailDomainPart;
           }
         }
       }
           }
         }
       }
-    }
 
 
-    /* Fill vacation array */
-    $this->vacation= array();
-    if (isset($this->config->current['VACATIONDIR'])){
-      $dir= $this->config->current['VACATIONDIR'];
-      if (is_dir($dir) && is_readable($dir)){
-
-        /* Look for files and build the vacation array */
-        $dh= opendir($dir);
-        while ($file = readdir($dh)){
-          $description= $this->parse_vacation("$dir/$file");
-          if ($description != ""){
-            $this->vacation["$dir/$file"]= $description;
+      /* Load attributes containing arrays */
+      foreach (array("gosaMailAlternateAddress", "gosaMailForwardingAddress") as $val){
+        $this->$val= array();
+        if (isset($this->attrs["$val"]["count"])){
+          for ($i= 0; $i<$this->attrs["$val"]["count"]; $i++){
+            array_push($this->$val, $this->attrs["$val"][$i]);
           }
         }
           }
         }
-        closedir($dh);
       }
     }
 
       }
     }
 
-    /* Create sieve management class */
-    $method = new $this->method($this->config);
-    $id     = $method->uattrib;
-    $this->sieve_management = new sieveManagement($this->config,$this->dn,$this,$id);
-
-    /* Get global filter config */
-    if (!session::is_set("mailfilter")){
-      $ui= get_userinfo();
-      $base= get_base_from_people($ui->dn);
-      $mailfilter= array( "depselect"       => $base,
-          "muser"            => "",
-          "regex"           => "*");
-      session::set("mailfilter", $mailfilter);
+    /* Intialize sieveManagement if necessary */
+    if($this->mailMethod->allowSieveManagement()){
+      $this->mailboxList = &$this->MailBoxes;
+      $this->sieve_management = new sieveManagement($this->config,$this->dn,$this,$this->mailMethod->getUAttrib());
     }
     }
-  }
-
-
-  function parse_vacation($file)
-  {
-    $desc= "";
-
-    if (is_file($file)){
-      $fh = fopen($file, "r");
-      $line= fgets($fh, 256);
 
 
-      if (!preg_match('/^DESC:/', $line)){
-        msg_dialog::display(_("Configuration error"), sprintf(_("No DESC tag in vacation template '%s'!"), $file), ERROR_DIALOG);
-        return $desc;
-      }
-      fclose ($fh);
-
-      $desc= trim(preg_replace('/^DESC:\s*/', '', $line));
-    }
+    /* Disconnect mailMethod. Connect on demand later. 
+     */
+    $this->mailMethod->disconnect();
 
 
-    return $desc;
+    /* Convert start/stop dates */
+    #TODO: use date format
+    $this->gosaVacationStart= date('d.m.Y', $this->gosaVacationStart);
+    $this->gosaVacationStop= date('d.m.Y', $this->gosaVacationStop);
   }
 
 
   function execute()
   {
   }
 
 
   function execute()
   {
+
     /* Call parent execute */
     /* Call parent execute */
-    plugin::execute();
+    $display = plugin::execute();
 
     /* Log view */
     if($this->is_account && !$this->view_logged){
 
     /* Log view */
     if($this->is_account && !$this->view_logged){
@@ -233,122 +214,112 @@ class mailAccount extends plugin
       new log("view","users/".get_class($this),$this->dn);
     }
 
       new log("view","users/".get_class($this),$this->dn);
     }
 
-    /* Initialise vars */
-
-    /* Load templating engine */
-    $smarty= get_smarty();
-    $display= "";
-
-    /* Get available mailserver */
-    $mailserver= array();
-    foreach ($this->config->data['SERVERS']['IMAP'] as $key => $val){
-      $mailserver[]= $key;
-    }
-
-    /* 
-     * Sieve Management 
-     */
-    if(isset($_POST['sieveManagement']) 
-        && preg_match("/C/",$this->gosaMailDeliveryMode)
-        && $this->acl_is_writeable("sieveManagement")) {
-
-      $this->dialog = $this->sieve_management;
-    }
-   
-    /* Cancel sieve edit */
-    if(isset($_POST['sieve_cancel'])){
-      $this->dialog = FALSE;
-    }
-    /* Save sieve changes */
-    if(isset($_POST['sieve_finish'])){
-      $this->sieve_management = $this->dialog;
-      $this->dialog = FALSE;
-    }
-    if(is_object($this->dialog)){
-      $this->dialog->save_object();
-      return($this->dialog->execute());
-    } 
 
 
+    /****************
+      Account status
+     ****************/
 
 
-    /* Handle account state */
-    /* Do we need to flip is_account state? */
     if(isset($_POST['modify_state'])){
     if(isset($_POST['modify_state'])){
-      if($this->is_account && $this->acl_is_removeable()){
+      if($this->is_account && $this->acl_is_removeable() && $this->mailMethod->accountRemoveAble()){
         $this->is_account= FALSE;
         $this->is_account= FALSE;
-      }elseif(!$this->is_account && $this->acl_is_createable()){
+      }elseif(!$this->is_account && $this->acl_is_createable() && $this->mailMethod->accountCreateable()){
         $this->is_account= TRUE;
       }
     }
         $this->is_account= TRUE;
       }
     }
-
-    /* Do we represent a valid account? */
     if(!$this->multiple_support_active){
       if (!$this->is_account && $this->parent === NULL){
     if(!$this->multiple_support_active){
       if (!$this->is_account && $this->parent === NULL){
-        $display= "<img alt=\"\" src=\"images/stop.png\" align=\"middle\">&nbsp;<b>".
+        $display= "<img alt=\"\" src=\"images/small-error.png\" align=\"middle\">&nbsp;<b>".
           msgPool::noValidExtension(_("Mail"))."</b>";
           msgPool::noValidExtension(_("Mail"))."</b>";
-
         $display.= back_to_main();
         return ($display);
       }
         $display.= back_to_main();
         return ($display);
       }
-
-      /* Show tab dialog headers */
       if ($this->parent !== NULL){
       if ($this->parent !== NULL){
-        if ($this->is_account){
-          if($this->accountDelegationsConfigured()){
-            $display= $this->show_disable_header(msgPool::removeFeaturesButton(_("Mail")),
-                _("Mail settings cannot be removed while there are delegations configured!"),TRUE,TRUE);
+        if ($this->is_account){ 
+          $reason = "";
+          if(!$this->mailMethod->accountRemoveable($reason)){
+            $display= $this->show_disable_header(msgPool::removeFeaturesButton(_("Mail")),$reason ,TRUE,TRUE);
           }else{
           }else{
-            $display= $this->show_disable_header(msgPool::removeFeaturesButton(_("Mail")),
-                msgPool::featuresEnabled(_("Mail")));
+            $display= $this->show_disable_header(msgPool::removeFeaturesButton(_("Mail")),msgPool::featuresEnabled(_("Mail")));
           }
         } else {
           }
         } else {
-          $display= $this->show_enable_header(msgPool::addFeaturesButton(_("Mail")),
-                msgPool::featuresDisabled(_("Mail")));
+          $reason = "";
+          if(!$this->mailMethod->accountCreateable($reason)){
+            $display= $this->show_enable_header(msgPool::addFeaturesButton(_("Mail")),$reason ,TRUE,TRUE);
+          }else{
+            $display= $this->show_enable_header(msgPool::addFeaturesButton(_("Mail")),msgPool::featuresDisabled(_("Mail")));
+          }
           return ($display);
         }
       }
     }
 
           return ($display);
         }
       }
     }
 
-    /* Forwarder  subdialog */
+    /****************
+      Sieve Management Dialog
+     ****************/
+    if($this->mailMethod->allowSieveManagement()){
+      if(isset($_POST['sieveManagement'])
+          && preg_match("/C/",$this->gosaMailDeliveryMode)
+          && $this->acl_is_writeable("sieveManagement") 
+          && $this->mailMethod->allowSieveManagement()) {
+        $this->dialog = $this->sieve_management;
+      }
+      if(isset($_POST['sieve_cancel'])){
+        $this->dialog = FALSE;
+      }
+      if(isset($_POST['sieve_finish'])){
+        $this->sieve_management = $this->dialog;
+        $this->dialog = FALSE;
+      }
+      if(is_object($this->dialog)){
+        $this->dialog->save_object();
+        return($this->dialog->execute());
+      }
+    }
+
+    /****************
+      Forward addresses 
+     ****************/
 
 
-    /* Trigger forward add dialog? */
     if (isset($_POST['add_local_forwarder'])){
     if (isset($_POST['add_local_forwarder'])){
-      $this->forward_dialog= TRUE;
+      $this->mailAddressSelect=  new mailAddressSelect($this->config, get_userinfo());
       $this->dialog= TRUE;
     }
       $this->dialog= TRUE;
     }
-
-    /* Cancel forward add dialog? */
-    if (isset($_POST['add_locals_cancel'])){
-      $this->forward_dialog= FALSE;
+    if (isset($_POST['mailAddressSelect_cancel'])){
+      $this->mailAddressSelect= FALSE;
       $this->dialog= FALSE;
     }
 
       $this->dialog= FALSE;
     }
 
-    /* Finished adding of locals? */
-    if (isset($_POST['add_locals_finish'])){
+    if (isset($_POST['mailAddressSelect_save']) && $this->mailAddressSelect instanceOf mailAddressSelect){
 
 
-      /* Check if we are able to write gosaMailForwardingAddress */
       if($this->acl_is_writeable("gosaMailForwardingAddress")){
       if($this->acl_is_writeable("gosaMailForwardingAddress")){
-
-        /* Walk through list of forwarders, ignore own addresses */
-        foreach ($_POST['local_list'] as $val){
-          if (!in_array ($val, $this->gosaMailAlternateAddress) &&
-              $val != $this->mail){
-
+        $list = $this->mailAddressSelect->save();
+        foreach ($list as $entry){
+          $val = $entry['mail'][0];
+          if (!in_array ($val, $this->gosaMailAlternateAddress) && $val != $this->mail){
             $this->addForwarder($val);
             $this->is_modified= TRUE;
           }
         }
             $this->addForwarder($val);
             $this->is_modified= TRUE;
           }
         }
+        $this->mailAddressSelect= FALSE;
+        $this->dialog= FALSE;
+      } else {
+        msg_dialog::display(_("Error"), _("Please select an entry!"), ERROR_DIALOG);
       }
       }
-      $this->forward_dialog= FALSE;
-      $this->dialog= FALSE;
     }
 
     }
 
-    /* Add forward email addresses */
+    if($this->mailAddressSelect instanceOf mailAddressSelect){
+      $used  = array();
+      $used['mail'] = array_values($this->gosaMailAlternateAddress);  
+      $used['mail'] = array_merge($used['mail'], array_values($this->gosaMailForwardingAddress));  
+      $used['mail'][] = $this->mail;
+
+      // Build up blocklist
+      session::set('filterBlacklist', $used);
+      return($this->mailAddressSelect->execute());
+    }
+
     if (isset($_POST['add_forwarder'])){
       if ($_POST['forward_address'] != ""){
     if (isset($_POST['add_forwarder'])){
       if ($_POST['forward_address'] != ""){
-
-        /* Valid email address specified? */
         $address= $_POST['forward_address'];
         $valid= FALSE;
         if (!tests::is_email($address)){
         $address= $_POST['forward_address'];
         $valid= FALSE;
         if (!tests::is_email($address)){
@@ -356,9 +327,8 @@ class mailAccount extends plugin
             if ($this->is_template){
               $valid= TRUE;
             } else {
             if ($this->is_template){
               $valid= TRUE;
             } else {
-              msg_dialog::display(_("Error"), 
-                  msgPool::invalid(_("Mail address"),"","","example@your-domain.com"),
-                  ERROR_DIALOG);
+              msg_dialog::display(_("Error"), msgPool::invalid(_("Mail address"),
+                    "","","your-address@your-domain.com"),ERROR_DIALOG);
             }
           }
         } elseif ($address == $this->mail
             }
           }
         } elseif ($address == $this->mail
@@ -367,10 +337,7 @@ class mailAccount extends plugin
         } else {
           $valid= TRUE;
         }
         } else {
           $valid= TRUE;
         }
-
         if ($valid){
         if ($valid){
-
-          /* Add it, if we are able to write gosaMailForwardingAddress */
           if($this->acl_is_writeable("gosaMailForwardingAddress")){
             $this->addForwarder ($address);
             $this->is_modified= TRUE;
           if($this->acl_is_writeable("gosaMailForwardingAddress")){
             $this->addForwarder ($address);
             $this->is_modified= TRUE;
@@ -378,205 +345,100 @@ class mailAccount extends plugin
         }
       }
     }
         }
       }
     }
-
-    /* Delete forward email addresses */
     if (isset($_POST['delete_forwarder'])){
       $this->delForwarder ($_POST['forwarder_list']);
     }
     if (isset($_POST['delete_forwarder'])){
       $this->delForwarder ($_POST['forwarder_list']);
     }
+    if ($this->mailAddressSelect instanceOf mailAddressSelect){
+    
+      return($this->mailAddressSelect->execute());
+    }
 
 
 
 
-    /* Add alternate email addresses */
-    if (isset($_POST['add_alternate'])){
+    /****************
+      Alternate addresses 
+     ****************/
 
 
+    if (isset($_POST['add_alternate'])){
       $valid= FALSE;
       if (!tests::is_email($_POST['alternate_address'])){
         if ($this->is_template){
           if (!(tests::is_email($_POST['alternate_address'], TRUE))){
       $valid= FALSE;
       if (!tests::is_email($_POST['alternate_address'])){
         if ($this->is_template){
           if (!(tests::is_email($_POST['alternate_address'], TRUE))){
-            msg_dialog::display(_("Error"), 
-                msgPool::invalid(_("Mail address"),"","","example@your-domain.com"),
-                ERROR_DIALOG);
-
+            msg_dialog::display(_("Error"),msgPool::invalid(_("Mail address"),"","","your-domain@your-domain.com"),ERROR_DIALOG);
           } else {
             $valid= TRUE;
           }
         } else {
           } else {
             $valid= TRUE;
           }
         } else {
-          msg_dialog::display(_("Error"), 
-              msgPool::invalid(_("Mail address"),"","","example@your-domain.com"),
-              ERROR_DIALOG);
+          msg_dialog::display(_("Error"),msgPool::invalid(_("Mail address"),"","","your-domain@your-domain.com"),ERROR_DIALOG);
         }
         }
-
       } else {
         $valid= TRUE;
       }
       } else {
         $valid= TRUE;
       }
-
       if ($valid && ($user= $this->addAlternate ($_POST['alternate_address'])) != ""){
         $ui= get_userinfo();
       if ($valid && ($user= $this->addAlternate ($_POST['alternate_address'])) != ""){
         $ui= get_userinfo();
-        if ($user != $ui->username){
-          msg_dialog::display(_("Error"), msgPool::duplicated(_("Mail address"))."&nbsp;".
-            sprintf(_("Address is already in use by user '%s'."), $user), ERROR_DIALOG);
+        $addon= "";
+        if ($user[0] == "!") {
+          $addon= sprintf(_("Address is already in use by group '%s'."), mb_substr($user, 1));
+        } else {
+          $addon= sprintf(_("Address is already in use by user '%s'."), $user);
         }
         }
+        msg_dialog::display(_("Error"), msgPool::duplicated(_("Mail address"))."<br><br><i>".
+            "$addon</i>", ERROR_DIALOG);
       }
     }
       }
     }
-
-    /* Delete alternate email addresses */
     if (isset($_POST['delete_alternate']) && isset($_POST['alternates_list'])){
       $this->delAlternate ($_POST['alternates_list']);
     }
 
     if (isset($_POST['delete_alternate']) && isset($_POST['alternates_list'])){
       $this->delAlternate ($_POST['alternates_list']);
     }
 
-  
-    /* Vacation message */
-  
-    /* Import vacation message? */
-    if (isset($_POST["import_vacation"]) && isset($this->vacation[$_POST["vacation_template"]])){
-
-      
-      /* Save message */
-      if($this->multiple_support_active){
-        $contents = file_get_contents($_POST["vacation_template"]);
-      }else{
-        $contents = $this->prepare_vacation_template(file_get_contents($_POST["vacation_template"]));
-      }
-      $this->gosaVacationMessage= htmlspecialchars($contents);
-    }
-
-  
-    /* Display forward dialog if requested above */
-
-    /* Show forward add dialog */
-    if ($this->forward_dialog){
-      $ldap= $this->config->get_ldap_link();
-
-      /* Save data */
-      $mailfilter= session::get("mailfilter");
-      foreach( array("depselect", "muser", "regex") as $type){
-        if (isset($_POST[$type])){
-          $mailfilter[$type]= $_POST[$type];
-        }
-      }
-      if (isset($_GET['search'])){
-        $s= mb_substr($_GET['search'], 0, 1, "UTF8")."*";
-        if ($s == "**"){
-          $s= "*";
-        }
-        $mailfilter['regex']= $s;
-      }
-      session::set("mailfilter", $mailfilter);
-
-      /* Get actual list */
-      $mailusers= array ();
-      if ($mailfilter['regex'] != '*' && $mailfilter['regex'] != ""){
-        $regex= $mailfilter['regex'];
-        $filter= "(|(mail=$regex)(gosaMailAlternateAddress=$regex))";
-      } else {
-        $filter= "";
-      }
-      if ($mailfilter['muser'] != ""){
-        $user= $mailfilter['muser'];
-        $filter= "$filter(|(uid=$user)(cn=$user)(givenName=$user)(sn=$user))";
-      }
-
-      /* Add already present people to the filter */
-      $exclude= "";
-      foreach ($this->gosaMailForwardingAddress as $mail){
-        $exclude.= "(mail=$mail)";
-      }
-      if ($exclude != ""){
-        $filter.= "(!(|$exclude))";
-      }
-
-      $res= get_list("(&(objectClass=gosaMailAccount)$filter)", "users", $mailfilter['depselect'], 
-                     array("sn", "mail", "givenName"), GL_SIZELIMIT | GL_SUBSEARCH);
-      $ldap->cd($mailfilter['depselect']);
-      $ldap->search ("(&(objectClass=gosaMailAccount)$filter)", array("sn", "mail", "givenName"));
-      error_reporting (0);
-      while ($attrs= $ldap->fetch()){
-        if(preg_match('/%/', $attrs['mail'][0])){
-          continue;
-        }
-        $name= $this->make_name($attrs);
-        $mailusers[$attrs['mail'][0]]= $name."&lt;".
-          $attrs['mail'][0]."&gt;";
-      }
-      error_reporting (E_ALL | E_STRICT);
-      natcasesort ($mailusers);
-      reset ($mailusers);
-
-      /* Show dialog */
-      $smarty->assign("search_image", get_template_path('images/search.png'));
-      $smarty->assign("usearch_image", get_template_path('images/search_user.png'));
-      $smarty->assign("tree_image", get_template_path('images/tree.png'));
-      $smarty->assign("infoimage", get_template_path('images/info.png'));
-      $smarty->assign("launchimage", get_template_path('images/small_filter.png'));
-      $smarty->assign("mailusers", $mailusers);
-      if (isset($_POST['depselect'])){
-        $smarty->assign("depselect", $_POST['depselect']);
-      }
-      $smarty->assign("deplist", $this->config->idepartments);
-      $smarty->assign("apply", apply_filter());
-      $smarty->assign("alphabet", generate_alphabet());
-      $smarty->assign("hint", print_sizelimit_warning());
-      foreach( array("depselect", "muser", "regex") as $type){
-        $smarty->assign("$type", $mailfilter[$type]);
-      }
-      $smarty->assign("hint", print_sizelimit_warning());
-
-      $display.= $smarty->fetch (get_template_path('mail_locals.tpl', TRUE, dirname(__FILE__)));
-      return ($display);
-    }
-
-    /* Display mail account tab */
-
-    $smarty->assign("mailServers", $mailserver);
-    $SkipWrite = (!isset($this->parent) || !$this->parent) && !session::is_set('edit');
+    /****************
+      SMARTY- Assign smarty variables 
+     ****************/
+    $smarty = get_smarty();
+    $smarty->assign("usePrototype", "true");
+    $smarty->assign("initially_was_account", $this->initially_was_account);
+    $smarty->assign("isModifyableMail"  , $this->mailMethod->isModifyableMail());
+    $smarty->assign("isModifyableServer", $this->mailMethod->isModifyableServer());
+    $smarty->assign("mailEqualsCN", $this->mailMethod->mailEqualsCN());
 
     $tmp  = $this->plInfo();
     foreach($tmp['plProvidedAcls'] as $name => $transl){
 
     $tmp  = $this->plInfo();
     foreach($tmp['plProvidedAcls'] as $name => $transl){
-      $smarty->assign("$name"."ACL", $this->getacl($name,$SkipWrite));
+      $smarty->assign("$name"."ACL", $this->getacl($name));
     }
     }
-
-    foreach(array("gosaMailServer", "gosaMailQuota", "perms", "mail",
-          "gosaMailAlternateAddress", "gosaMailForwardingAddress",
-          "gosaVacationMessage", "gosaMailDeliveryMode", "gosaVacationStart",
-          "gosaVacationStop", "gosaMailMaxSize", "gosaSpamSortLevel", "gosaSpamMailbox") as $val){
-      $smarty->assign("$val", $this->$val);
+    foreach($this->attributes as $attr){
+      $smarty->assign($attr,$this->$attr);
     }
     }
-
-    if (is_numeric($this->gosaMailQuota) && $this->gosaMailQuota != 0){
-      $smarty->assign("quotausage", progressbar(round(($this->quotaUsage * 100)/ $this->gosaMailQuota),100,15,true));
-      $smarty->assign("quotadefined", "true");
-    } else {
-      $smarty->assign("quotadefined", "false");
+    $smarty->assign("quotaEnabled", $this->mailMethod->quotaEnabled());
+    if($this->mailMethod->quotaEnabled()){
+      $smarty->assign("quotaUsage",   mailMethod::quota_to_image($this->quotaUsage,$this->gosaMailQuota));
+      $smarty->assign("gosaMailQuota",$this->gosaMailQuota);
     }
     }
+    $smarty->assign("domainSelectionEnabled", $this->mailMethod->domainSelectionEnabled());
+    $smarty->assign("MailDomains", $this->mailDomainParts);
+    $smarty->assign("MailDomain" , $this->mailDomainPart);
+    $smarty->assign("MailServers", $this->mailMethod->getMailServers());
+    $smarty->assign("allowSieveManagement", $this->mailMethod->allowSieveManagement());
+    $smarty->assign("own_script",  $this->sieveManagementUsed);
 
 
-    /* Disable mail field if needed */
-    $method= new $this->method($this->config);
-    if ($method->uattrib == "mail" && $this->initially_was_account){
-      $smarty->assign("mailACL", preg_replace("/w/","",$this->getacl("mail",$SkipWrite)));
+    /* _Multiple users vars_ */
+    foreach($this->attributes as $attr){
+      $u_attr = "use_".$attr;
+      $smarty->assign($u_attr,in_array($attr,$this->multi_boxes));
     }
     }
-
-    /* Disable/Enable range select, but do not disable them twice 
-     *  if they are already diabled by "use own sieve script"
-     */
-    if (preg_match('/V/', $this->gosaMailDeliveryMode) || preg_match("/C/",$this->gosaMailDeliveryMode)){
-      $smarty->assign('rangeEnabled', "");
-    } else {
-      $smarty->assign('rangeEnabled', "disabled");
+    foreach(array("only_local","gosaMailForwardingAddress","use_mailsize_limit","drop_own_mails","use_vacation","use_spam_filter") as $attr){
+      $u_attr = "use_".$attr;
+      $smarty->assign($u_attr,in_array($attr,$this->multi_boxes));
     }
 
     }
 
-    if (!preg_match("/L/", $this->gosaMailDeliveryMode)) {
-      $smarty->assign("only_local", "checked");
-    } else {
-      $smarty->assign("only_local", "");
-    }
 
 
-    $types = array(
-          "V"=>"use_vacation",
-          "S"=>"use_spam_filter",
-          "R"=>"use_mailsize_limit",
-          "I"=>"drop_own_mails",
-          "C"=>"own_script");
+    /****************
+      SMARTY- Assign flags 
+     ****************/
 
 
-    /* Fill checkboxes */
+    $types = array(
+        "V"=>"use_vacation",
+        "S"=>"use_spam_filter",
+        "R"=>"use_mailsize_limit",
+        "I"=>"drop_own_mails",
+        "C"=>"own_script");
     foreach($types as $option => $varname){
       if (preg_match("/".$option."/", $this->gosaMailDeliveryMode)) {
         $smarty->assign($varname, "checked");
     foreach($types as $option => $varname){
       if (preg_match("/".$option."/", $this->gosaMailDeliveryMode)) {
         $smarty->assign($varname, "checked");
@@ -584,48 +446,21 @@ class mailAccount extends plugin
         $smarty->assign($varname, "");
       }
     }
         $smarty->assign($varname, "");
       }
     }
-   
-    /* Display mail account tab */
-    if($this->gosaVacationStart ==0){
-      $date= getdate(time());
-    }else{
-      $date= getdate($this->gosaVacationStart);
-    }
-    $days= array();
-    for($d= 1; $d<32; $d++){
-      $days[$d]= $d;
-    }
-    $years= array();
-    for($y= $date['year']-10; $y<$date['year']+10; $y++){
-      $years[]= $y;
-    }
-    $months= array(_("January"), _("February"), _("March"), _("April"),
-        _("May"), _("June"), _("July"), _("August"), _("September"),
-        _("October"), _("November"), _("December"));
-    $smarty->assign("start_day", $date["mday"]);
-    $smarty->assign("days", $days);
-    $smarty->assign("months", $months);
-    $smarty->assign("start_month", $date["mon"]-1);
-    $smarty->assign("years", $years);
-    $smarty->assign("start_year", $date["year"]);
-
-    if($this->gosaVacationStop ==0){
-      $date= getdate(time());
-      $date["mday"]++;
-    }else{
-      $date= getdate($this->gosaVacationStop);
+    if (!preg_match("/L/", $this->gosaMailDeliveryMode)) {
+      $smarty->assign("only_local", "checked");
+    } else {
+      $smarty->assign("only_local", "");
     }
     }
-    $smarty->assign("end_day", $date["mday"]);
-    $smarty->assign("end_month", $date["mon"]-1);
-    $smarty->assign("end_year", $date["year"]);
 
 
 
 
-    /* Have vacation templates? */
+    /****************
+      Smarty- Vacation settings 
+     ****************/
+    $smarty->assign("rangeEnabled", FALSE);
     $smarty->assign("template", "");
     $smarty->assign("template", "");
-    if (count($this->vacation)){
+    if (count($this->vacationTemplates)){
       $smarty->assign("show_templates", "true");
       $smarty->assign("show_templates", "true");
-      $smarty->assign("vacationtemplates", $this->vacation);
+      $smarty->assign("vacationtemplates", $this->vacationTemplates);
       if (isset($_POST['vacation_template'])){
         $smarty->assign("template", $_POST['vacation_template']);
       }
       if (isset($_POST['vacation_template'])){
         $smarty->assign("template", $_POST['vacation_template']);
       }
@@ -633,99 +468,22 @@ class mailAccount extends plugin
       $smarty->assign("show_templates", "false");
     }
 
       $smarty->assign("show_templates", "false");
     }
 
-    /* Fill spam selector */
-    $spamlevel= array();
-    for ($i= 0; $i<21; $i++){
-      $spamlevel[]= $i;
-    }
-    $smarty->assign("spamlevel", $spamlevel);
-    $smarty->assign("spambox", $this->mailboxList);
-
-    foreach($this->attributes as $attr){
-      $u_attr = "use_".$attr;
-      $smarty->assign($u_attr,in_array($attr,$this->multi_boxes));
+    /* Vacation range assigments
+     */
+    if($this->mailMethod->vacationRangeEnabled()){
+      $smarty->assign("rangeEnabled", TRUE);
     }
 
     }
 
-    foreach(array("only_local","gosaMailForwardingAddress","use_mailsize_limit","drop_own_mails","use_vacation","use_spam_filter") as $attr){
-      $u_attr = "use_".$attr;
-      $smarty->assign($u_attr,in_array($attr,$this->multi_boxes));
-    }
+    /* fill filter settings 
+     */
+    $smarty->assign("spamlevel", $this->SpamLevels);
+    $smarty->assign("spambox"  , $this->MailBoxes);
 
 
-    $smarty->assign("multiple_support",$this->multiple_support_active);
-    $display.= $smarty->fetch (get_template_path('generic.tpl', TRUE, dirname(__FILE__)));
-    return ($display);
+    $smarty->assign("multiple_support",$this->multiple_support_active);  
+    return($display.$smarty->fetch(get_template_path("generic.tpl",TRUE,dirname(__FILE__))));
   }
 
 
   }
 
 
-  /* remove object from parent */
-  function remove_from_parent()
-  {
-    /* Cancel if there's nothing to do here */
-    if (!$this->initially_was_account){
-      return;
-    }
-    
-    /* include global link_info */
-    $ldap= $this->config->get_ldap_link();
-
-    /* Remove and write to LDAP */
-    plugin::remove_from_parent();
-
-    /* Zero arrays */
-    $this->attrs['gosaMailAlternateAddress']= array();
-    $this->attrs['gosaMailForwardingAddress']= array();
-
-    /* Adapt attributes if needed */
-    $method= new $this->method($this->config);
-    $method->fixAttributesOnRemove($this);
-
-    @DEBUG (DEBUG_LDAP, __LINE__, __FUNCTION__, __FILE__,$this->attributes, "Save");
-    $ldap->cd($this->dn);
-    $this->cleanup();
-
-    $ldap->modify ($this->attrs); 
-
-    /* Add "view" to logging class */ 
-    new log("remove","users/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
-
-    show_ldap_error($ldap->get_error(), sprintf(_("Removing of user/mail account with dn '%s' failed."),$this->dn));
-
-    /* Connect to IMAP server for account deletion */
-    if ($this->gosaMailServer != ""){
-      $method= new $this->method($this->config);
-      $id= $method->uattrib;
-      if ($method->connect($this->gosaMailServer)){
-
-        /* Remove account from IMAP server */
-        $method->deleteMailbox($this->folder_prefix.$this->$id);
-        $method->disconnect();
-      }
-    }
-
-    /* Update shared folder membership, ACL may need to be updated */
-    $this->updateSharedFolder(); 
-
-    /* Optionally execute a command after we're done */
-    $this->handle_post_events("remove",array("uid" => $this->uid));
-  }
-
-  
-  /* check if we have some delegations configured, those delegations must be removed first */
-  function accountDelegationsConfigured()
-  { 
-    /* We are in administrational edit mode.
-        Check tab configurations directly */
-    if(isset($this->attrs)){
-      $checkArray  = array("kolabInvitationPolicy","unrestrictedMailSize", "calFBURL","kolabDelegate","kolabFreeBusyFuture");
-      foreach($checkArray as $index){
-        if(isset($this->attrs[$index])){
-           return(true);
-        }
-      }
-    }
-    return(false); 
-  }
 
   /* Save data to object */
   function save_object()
 
   /* Save data to object */
   function save_object()
@@ -733,16 +491,45 @@ class mailAccount extends plugin
     if (isset($_POST['mailTab'])){
 
       /* Save ldap attributes */
     if (isset($_POST['mailTab'])){
 
       /* Save ldap attributes */
+      $mail   = $this->mail;
+      $server = $this->gosaMailServer;
       plugin::save_object();
 
       plugin::save_object();
 
+      if(!$this->mailMethod->isModifyableServer() && $this->initially_was_account){
+        $this->gosaMailServer = $server;
+      }
 
 
-      if(isset($_POST['own_script'])){
+      if(!$this->mailMethod->isModifyableMail() && $this->initially_was_account){
+        $this->mail = $mail;
+      }else{
+
+        /* Get posted mail domain part, if necessary  
+         */
+        if($this->mailMethod->domainSelectionEnabled() && isset($_POST['MailDomain'])){
+          if(in_array(get_post('MailDomain'), $this->mailDomainParts)){
+            $this->mailDomainPart = get_post('MailDomain');
+          }
+        }
+      }
+
+      /* Import vacation message? 
+       */
+      if (isset($_POST["import_vacation"]) && isset($this->vacationTemplates[$_POST["vacation_template"]])){
+        if($this->multiple_support_active){
+          $contents = ltrim(preg_replace("/^DESC:.*$/m","",file_get_contents($_POST["vacation_template"])));
+        }else{
+          $contents = $this->prepare_vacation_template(file_get_contents($_POST["vacation_template"]));
+        }
+        $this->gosaVacationMessage= htmlspecialchars($contents);
+      }
 
 
+      /* Handle flags 
+       */
+      if(isset($_POST['own_script'])){
         if(!preg_match("/C/",$this->gosaMailDeliveryMode)){
           $str= preg_replace("/[\[\]]/","",$this->gosaMailDeliveryMode);
           $this->gosaMailDeliveryMode = "[".$str."C]";
         }
         if(!preg_match("/C/",$this->gosaMailDeliveryMode)){
           $str= preg_replace("/[\[\]]/","",$this->gosaMailDeliveryMode);
           $this->gosaMailDeliveryMode = "[".$str."C]";
         }
-
       }else{
 
         /* Assemble mail delivery mode
       }else{
 
         /* Assemble mail delivery mode
@@ -750,13 +537,13 @@ class mailAccount extends plugin
            be called when 'mail' is set, because checkboxes may not be set when
            we're in some other dialog.
 
            be called when 'mail' is set, because checkboxes may not be set when
            we're in some other dialog.
 
-          Example for gosaMailDeliveryMode [LR        ]
-          L: Local delivery
-          R: Reject when exceeding mailsize limit
-          S: Use spam filter
-          V: Use vacation message
-          C: Use custm sieve script
-          I: Only insider delivery */
+           Example for gosaMailDeliveryMode [LR        ]
+           L -  Local delivery
+           R -  Reject when exceeding mailsize limit
+           S -  Use spam filter
+           V -  Use vacation message
+           C -  Use custm sieve script
+           I -  Only insider delivery */
 
         $tmp= preg_replace("/[^a-z]/i","",$this->gosaMailDeliveryMode);
 
 
         $tmp= preg_replace("/[^a-z]/i","",$this->gosaMailDeliveryMode);
 
@@ -769,8 +556,7 @@ class mailAccount extends plugin
             $tmp = preg_replace("/L/","",$tmp);
           }
         }
             $tmp = preg_replace("/L/","",$tmp);
           }
         }
-
-        $opts = array(     
+        $opts = array(
             "R"   => "use_mailsize_limit",
             "S"   => "use_spam_filter",
             "V"   => "use_vacation",
             "R"   => "use_mailsize_limit",
             "S"   => "use_spam_filter",
             "V"   => "use_vacation",
@@ -793,13 +579,16 @@ class mailAccount extends plugin
         }
         $this->gosaMailDeliveryMode= $tmp;
 
         }
         $this->gosaMailDeliveryMode= $tmp;
 
-
-        if($this->acl_is_writeable("gosaVacationMessage") && preg_match("/V/",$this->gosaMailDeliveryMode)){
-          if(isset($_POST['gosaVacationStart'])){
-            $this->gosaVacationStart = $_POST['gosaVacationStart'];
-          }
-          if(isset($_POST['gosaVacationStop'])){
-            $this->gosaVacationStop = $_POST['gosaVacationStop'];
+        /* Get start/stop values for vacation scope of application
+         */
+        if($this->mailMethod->vacationRangeEnabled()){
+          if($this->acl_is_writeable("gosaVacationMessage") && preg_match("/V/",$this->gosaMailDeliveryMode)){
+            if(isset($_POST['gosaVacationStart'])){
+              $this->gosaVacationStart = $_POST['gosaVacationStart'];
+            }
+            if(isset($_POST['gosaVacationStop'])){
+              $this->gosaVacationStop = $_POST['gosaVacationStop'];
+            }
           }
         }
       }
           }
         }
       }
@@ -807,199 +596,46 @@ class mailAccount extends plugin
   }
 
 
   }
 
 
-  /* Save data to LDAP, depending on is_account we save or delete */
-  function save()
+  /*! \brief  Parse vacation templates and build up an array
+    containing 'filename' => 'description'. 
+    Used to fill vacation dropdown box.
+    @return Array   All useable vacation templates.
+   */ 
+  function get_vacation_templates()
   {
   {
-    $ldap= $this->config->get_ldap_link();
-
-    /* Call parents save to prepare $this->attrs */
-    plugin::save();
-
-    /* Save arrays */
-    $this->attrs['gosaMailAlternateAddress']= $this->gosaMailAlternateAddress;
-    $this->attrs['gosaMailForwardingAddress']= $this->gosaMailForwardingAddress;
+    $vct = array();
+    if ($this->config->get_cfg_value("vacationTemplateDirectory") != ""){
+      $dir= $this->config->get_cfg_value("vacationTemplateDirectory");
+      if (is_dir($dir) && is_readable($dir)){
+        $dh = opendir($dir);
+        while($file = readdir($dh)){
+          $description= "";
+          if (is_file($dir."/".$file)){
+            $fh = fopen($dir."/".$file, "r");
+            $line= fgets($fh, 256);
+            if (!preg_match('/^DESC:/', $line)){
+              msg_dialog::display(_("Configuration error"), sprintf(_("No DESC tag in vacation template '%s'!"), $file), ERROR_DIALOG);
+            }else{
+              $description= trim(preg_replace('/^DESC:\s*/', '', $line));
+            }
+            fclose ($fh);
+          }
+          if ($description != ""){
+            $vct["$dir/$file"]= $description;
+          }
+        }
+        closedir($dh);
+      }
+    }
+    return($vct); 
+  }
 
 
-    /* Adapt attributes if needed */
-    $method= new $this->method($this->config);
-    $id= $method->uattrib;
 
 
-    $method->fixAttributesOnStore($this);
-
-    /* Remove Mailquota if = "" or "0"  */
-    if((isset($this->attrs['gosaMailQuota']))&&(!$this->attrs['gosaMailQuota'])) {
-      $this->attrs['gosaMailQuota']=0;
-    }
-
-    if(empty($this->attrs['gosaSpamMailbox'])){
-      unset($this->attrs['gosaSpamMailbox']);
-    }
-
-    $this->attrs['mail'] = strtolower($this->attrs['mail']); 
-
-        /* Remove attributes - if not needed */
-    if (!preg_match('/V/', $this->gosaMailDeliveryMode)){
-      unset($this->attrs['gosaVacationStart']);
-      unset($this->attrs['gosaVacationStop']);
-    }
-
-
-    /* Remove attributes - if not needed */
-    if (!preg_match('/V/', $this->gosaMailDeliveryMode)){
-      unset($this->attrs['gosaVacationStart']);
-      unset($this->attrs['gosaVacationStop']);
-    }
-
-    /* Save data to LDAP */
-    $ldap->cd($this->dn);
-    $this->cleanup();
-    $ldap->modify ($this->attrs); 
-
-    show_ldap_error($ldap->get_error(), sprintf(_("Saving of user/mail account with dn '%s' failed."),$this->dn));
-
-    /* Log last action */ 
-    if($this->initially_was_account){
-      new log("modify","users/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
-    }else{
-      new log("create","users/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
-    }
-
-    /* Only do IMAP actions if we are not a template */
-    if (!$this->is_template){
-
-      if ($method->connect($this->gosaMailServer)){
-        $method->updateMailbox($this->folder_prefix.$this->$id);
-        
-        $method->setQuota($this->folder_prefix.$this->$id, $this->gosaMailQuota);
-        $method->disconnect();
-
-        /* Ensure that this is an existing account */
-        if(1==1 || $this->initially_was_account){
-
-          /* Write sieve information only if not in C mode */
-          if (!is_integer(strpos($this->gosaMailDeliveryMode, "C"))){
-            $method->configureFilter($this->$id,
-                $this->gosaMailDeliveryMode,
-                $this->mail,
-                $this->gosaMailAlternateAddress,
-                $this->gosaMailMaxSize,
-                $this->gosaSpamMailbox,
-                $this->gosaSpamSortLevel,
-                $this->gosaVacationMessage);
-            $this->is_modified = TRUE;
-          }else{
-            $this->sieve_management->save();
-          }
-        }
-      }
-    }
-
-    /* Optionally execute a command after we're done */
-    if ($this->initially_was_account == $this->is_account){
-      if ($this->is_modified){
-        $this->handle_post_events("modify", array("uid" => $this->uid));
-      }
-    } else {
-      $this->handle_post_events("add", array("uid" => $this->uid));
-    }
-
-    $this->updateSharedFolder();
-  }
-
-
-  /* Check formular input */
-  function check()
-  {
-    if(!$this->is_account) return(array());
-
-    $ldap= $this->config->get_ldap_link();
-
-    /* Call common method to give check the hook */
-    $message= plugin::check();
-
-    if(empty($this->gosaMailServer)){
-      $message[]= msgPool::noserver(_("Mail"));
-    }
-
-    /* must: mail */
-    if ($this->mail == ""){
-      $message[]= msgPool::required(_("Primary address"));
-    }
-    if ($this->is_template){
-      if (!tests::is_email($this->mail, TRUE)){
-        $message[]= msgPool::invalid(_("Mail address"),"","","%givenName.%sn@your-domain.com");
-      }
-    } else {
-      if (!tests::is_email($this->mail)){
-        $message[]= msgPool::invalid(_("Mail address"),"","","example@your-domain.com");
-      }
-    }
-    $ldap->cd($this->config->current['BASE']);
-    $ldap->search ("(&(!(objectClass=gosaUserTemplate))(objectClass=gosaMailAccount)(|(mail=".$this->mail.")(gosaMailAlternateAddress=".$this->mail."))(!(uid=".$this->uid."))(!(cn=".$this->uid.")))", array("uid"));
-    if ($ldap->count() != 0){
-      $message[]= msgPool::duplicated(_("Mail address"));
-    }
-
-    /* Check quota */
-    if ($this->gosaMailQuota != '' && $this->acl_is_writeable("gosaMailQuota")){
-      if (!is_numeric($this->gosaMailQuota)) {
-        $message[]= msgPool::invalid(_("Quota size"),$this->gosaMailQuota,"/^[0-9]*/");
-      } else {
-        $this->gosaMailQuota= (int) $this->gosaMailQuota;
-      }
-    }
-
-    /* Check rejectsize for integer */
-    if ($this->gosaMailMaxSize != '' && $this->acl_is_writeable("gosaMailMaxSize")){
-      if (!is_numeric($this->gosaMailMaxSize)){
-        $message[]= msgPool::invalid(_("Mail reject size"),$this->gosaMailMaxSize,"/^[0-9]*/");
-      } else {
-        $this->gosaMailMaxSize= (int) $this->gosaMailMaxSize;
-      }
-    }
-
-    /* Need gosaMailMaxSize if use_mailsize_limit is checked */
-    if (is_integer(strpos($this->gosaMailDeliveryMode, "R")) && $this->gosaMailMaxSize == ""){
-      $message[]= msgPool::required(_("Mail reject size"));
-    }
-
-    if((preg_match("/S/", $this->gosaMailDeliveryMode))&&(empty($this->gosaSpamMailbox))) {
-      $message[]= msgPool::required(_("Spam folder"));
-    }
-
-    if (preg_match('/V/', $this->gosaMailDeliveryMode) && $this->gosaVacationStart >= $this->gosaVacationStop){
-      $message[]= msgPool::invalid(_("Vacation interval"));
-    }
-
-    return ($message);
-  }
-
-
-  /* Adapt from template, using 'dn' */
-  function adapt_from_template($dn)
-  {
-    plugin::adapt_from_template($dn);
-
-    foreach (array("gosaMailAlternateAddress", "gosaMailForwardingAddress") as $val){
-      $this->$val= array();
-      if (isset($this->attrs["$val"]["count"])){
-        for ($i= 0; $i<$this->attrs["$val"]["count"]; $i++){
-          $value= $this->attrs["$val"][$i];
-          foreach (array("sn", "givenName", "uid") as $repl){
-            if (preg_match("/%$repl/i", $value)){
-              $value= preg_replace ("/%$repl/i", $this->parent->$repl, $value);
-            }
-          }
-          array_push($this->$val, strtolower(rewrite($value)));
-        }
-      }
-    }
-    $this->mail= strtolower(rewrite($this->mail));
-  }
-
-
-  /* Add entry to forwarder list */
+  /*! \brief  Adds the given mail address to the list of mail forwarders 
+   */ 
   function addForwarder($address)
   {
   function addForwarder($address)
   {
+    if(empty($address)) return;
     if($this->acl_is_writeable("gosaMailForwardingAddress")){
       $this->gosaMailForwardingAddress[]= $address;
       $this->gosaMailForwardingAddress= array_unique ($this->gosaMailForwardingAddress);
     if($this->acl_is_writeable("gosaMailForwardingAddress")){
       $this->gosaMailForwardingAddress[]= $address;
       $this->gosaMailForwardingAddress= array_unique ($this->gosaMailForwardingAddress);
@@ -1012,7 +648,8 @@ class mailAccount extends plugin
   }
 
 
   }
 
 
-  /* Remove list of addresses from forwarder list */
+  /*! \brief  Removes the given mail address from the list of mail forwarders 
+   */ 
   function delForwarder($addresses)
   {
     if($this->acl_is_writeable("gosaMailForwardingAddress")){
   function delForwarder($addresses)
   {
     if($this->acl_is_writeable("gosaMailForwardingAddress")){
@@ -1024,30 +661,31 @@ class mailAccount extends plugin
   }
 
 
   }
 
 
-  /* Add given mail address to the list of alternate adresses , 
-     check if this mal address is used, skip adding in this case */
+  /*! \brief  Add given mail address to the list of alternate adresses ,
+    .          check if this mal address is used, skip adding in this case 
+   */ 
   function addAlternate($address)
   {
   function addAlternate($address)
   {
+    if(empty($address)) return;
     if($this->acl_is_writeable("gosaMailAlternateAddress")){
       $ldap= $this->config->get_ldap_link();
       $address= strtolower($address);
 
       /* Is this address already assigned in LDAP? */
       $ldap->cd ($this->config->current['BASE']);
     if($this->acl_is_writeable("gosaMailAlternateAddress")){
       $ldap= $this->config->get_ldap_link();
       $address= strtolower($address);
 
       /* Is this address already assigned in LDAP? */
       $ldap->cd ($this->config->current['BASE']);
-      $ldap->search ("(&(objectClass=gosaMailAccount)(|(mail=$address)"."(gosaMailAlternateAddress=$address)))", array("uid"));
-      $ldap->search ("(&(!(objectClass=gosaUserTemplate))(objectClass=gosaMailAccount)(|(mail=$address)"."(gosaMailAlternateAddress=$address)))", array("uid"));
-
+      $ldap->search ("(&(!(objectClass=gosaUserTemplate))(objectClass=gosaMailAccount)(|(mail=$address)".
+          "(alias=$address)(gosaMailAlternateAddress=$address)))", array("uid", "cn"));
       if ($ldap->count() > 0){
         $attrs= $ldap->fetch ();
       if ($ldap->count() > 0){
         $attrs= $ldap->fetch ();
+        if (!isset($attrs["uid"])) {
+          return ("!".$attrs["cn"][0]);
+        }
         return ($attrs["uid"][0]);
       }
         return ($attrs["uid"][0]);
       }
-
-      /* Add to list of alternates */
       if (!in_array($address, $this->gosaMailAlternateAddress)){
         $this->gosaMailAlternateAddress[]= $address;
         $this->is_modified= TRUE;
       }
       if (!in_array($address, $this->gosaMailAlternateAddress)){
         $this->gosaMailAlternateAddress[]= $address;
         $this->is_modified= TRUE;
       }
-
       sort ($this->gosaMailAlternateAddress);
       reset ($this->gosaMailAlternateAddress);
       return ("");
       sort ($this->gosaMailAlternateAddress);
       reset ($this->gosaMailAlternateAddress);
       return ("");
@@ -1057,6 +695,8 @@ class mailAccount extends plugin
   }
 
 
   }
 
 
+  /*! \brief  Removes the given mail address from the alternate addresses list 
+   */ 
   function delAlternate($addresses)
   {
     if($this->acl_is_writeable("gosaMailAlternateAddress")){
   function delAlternate($addresses)
   {
     if($this->acl_is_writeable("gosaMailAlternateAddress")){
@@ -1067,234 +707,470 @@ class mailAccount extends plugin
     }
   }
 
     }
   }
 
-  function make_name($attrs)
+
+  /*! \brief  Prepare importet vacation string. \
+    .         Replace placeholder like %givenName a.s.o.
+    @param  string  Vacation string
+    @return string  Completed vacation string
+   */
+  private function prepare_vacation_template($contents)
   {
   {
-    $name= "";
-    if (isset($attrs['sn'][0])){
-      $name= $attrs['sn'][0];
+    /* Replace attributes */
+    $attrs = array();
+    $obj   = NULL;
+    if(isset($this->parent->by_object['user'])){
+      $attrs  = $this->parent->by_object['user']->attributes;
+      $obj    = $this->parent->by_object['user'];
+    }else{
+      $obj    = new user($this->config,$this->dn);
+      $attrs  = $obj->attributes;
     }
     }
-    if (isset($attrs['givenName'][0])){
-      if ($name != ""){
-        $name.= ", ".$attrs['givenName'][0];
-      } else {
-        $name.= $attrs['givenName'][0];
+    if($obj){
+
+      /* Replace vacation start and end time */
+      if($this->mailMethod->vacationRangeEnabled()){
+        if(preg_match("/%start/",$contents)){
+          $contents = preg_replace("/%start/",$this->gosaVacationStart,$contents);
+        }
+        if(preg_match("/%end/",$contents)){
+          $contents = preg_replace("/%end/",$this->gosaVacationStop,$contents);
+        }
+      }else{
+        if(preg_match("/%start/",$contents)){
+          $contents = preg_replace("/%start/", _("unknown"),$contents);
+        }
+        if(preg_match("/%end/",$contents)){
+          $contents = preg_replace("/%end/", _("unknown"), $contents);
+        }
       }
       }
-    }
-    if ($name != ""){
-      $name.= " ";
-    }
 
 
-    return ($name);
-  }
+      foreach ($attrs as $val){
 
 
-  
-  /* Create the mail part for the copy & paste dialog */
-  function getCopyDialog()
-  {
-    if(!$this->is_account) return("");
-    $smarty = get_smarty();
-    $smarty->assign("mail",$this->mail); 
-    $smarty->assign("gosaMailAlternateAddress",$this->gosaMailAlternateAddress);
-    $smarty->assign("gosaMailForwardingAddress",$this->gosaMailForwardingAddress);
-    $str = $smarty->fetch(get_template_path("copypaste.tpl",TRUE, dirname(__FILE__)));
+        // We can only replace strings here
+        if(!is_string($obj->$val)) continue;
 
 
-    $ret = array();
-    $ret['status'] = "";
-    $ret['string'] = $str;
-    return($ret);
+        if(preg_match("/dateOfBirth/",$val)){
+          if($obj->use_dob){
+            $contents= preg_replace("/%$val/",date("Y-d-m",$obj->dateOfBirth),$contents);
+          }
+        }else {
+          $contents= preg_replace("/%$val/",
+              $obj->$val, $contents);
+        }
+
+      }
+    }
+    $contents = ltrim(preg_replace("/^DESC:.*$/m","",$contents),"\n ");
+    return($contents);
   }
 
   }
 
-  function saveCopyDialog()
+
+  /*! \brief  Removes the mailAccount extension from ldap 
+   */  
+  function remove_from_parent()
   {
   {
-    if(!$this->is_account) return;  
+    /* Cancel if there's nothing to do here */
+    if (!$this->initially_was_account){
+      return;
+    }
 
 
-    /* Execute to save mailAlternateAddress && gosaMailForwardingAddress */
-    $this->execute();
+    /* If domain part was selectable, contruct mail address */
+    if($this->mailMethod->domainSelectionEnabled()){
+      $this->mail = $this->mail."@".$this->mailDomainPart;
+    }
+
+    /* Update sharedFolder dependencies. 
+       Open each shared folder and remove this account. 
+       Then Save the group to ensure that all necessary 
+        actions will be taken (imap acls updated aso.).
+     */
+    $ldap = $this->config->get_ldap_link();    
+    $ldap->cd($this->config->current['BASE']);
+    $ldap->search("(&(objectClass=posixGroup)(objectClass=gosaMailAccount)(memberUid=".$this->uid."))",array("dn"));
+    while($attrs = $ldap->fetch()){
+      $grp = new grouptabs($this->config, $this->config->data['TABS']['GROUPTABS'], $attrs['dn']);
+      if(isset($grp->by_object['mailgroup']) && isset($grp->by_object['group'])){
+        $grp->by_object['group']->removeUser($this->uid);
+
+        /* Do not save the complete group! This will quit the complete membership 
+         */
+        $grp->by_object['mailgroup']->save();
+      } 
+    }
+
+    /* Remove GOsa attributes */
+    plugin::remove_from_parent();
+
+    /* Zero arrays */
+    $this->attrs['gosaMailAlternateAddress'] = array();
+    $this->attrs['gosaMailForwardingAddress']= array();
+
+
+    $this->mailMethod->fixAttributesOnRemove();
+    $this->cleanup();
+
+    @DEBUG (DEBUG_LDAP, __LINE__, __FUNCTION__, __FILE__,$this->attributes, "Save");
+    $ldap= $this->config->get_ldap_link();
+    $ldap->cd($this->dn);
+    $ldap->modify ($this->attrs);
+
+    /* Add "view" to logging class */
+    new log("remove","users/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
+    if (!$ldap->success()){
+      msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_MOD, get_class()));
+    }
     
     
-    if(isset($_POST['mail'])){
-      $this->mail = $_POST['mail'];
+    /* Let the mailMethod remove this mailbox, e.g. from imap and
+       update shared folder membership, ACL may need to be updated. 
+     */
+    if (!$this->is_template){
+
+      if(!$this->mailMethod->connect()){
+        msg_dialog::display(_("Mail error"), sprintf(_("Mail method cannot connect: %s"), 
+              $this->mailMethod->get_error()), ERROR_DIALOG);
+      }else{
+        if(!$this->mailMethod->deleteMailbox()){
+          msg_dialog::display(_("Mail error"), sprintf(_("Cannot remove mailbox: %s"), 
+                $this->mailMethod->get_error()), ERROR_DIALOG);
+        }
+      }
     }
     }
+    $this->mailMethod->disconnect();
 
 
+    /* Optionally execute a command after we're done */
+    $this->handle_post_events("remove",array("uid" => $this->uid));
   }
 
   }
 
-  function allow_remove()
+
+  /*! \brief  Save the mailAccount settings to the ldap database.
+   */
+  function save()
   {
   {
-    if (isset($this->config->current['MAILMETHOD'])){
-      $method= $this->config->current['MAILMETHOD'];
-      if(preg_match("/olab/i",$method)){
-        $ldap = $this->config->get_ldap_link();
-        $ldap->cd($this->config->current['BASE']);
-        $ldap->cat($this->dn);
-        if($ldap->count()){
-          $attrs = $ldap->fetch();
-          if(isset($attrs['kolabDeleteFlag'])){ 
-            return(_("Waiting for kolab to remove mail properties..."));
-          }elseif(in_array("gosaMailAccount",$attrs['objectClass'])){
-            return(_("Please remove the mail settings first to allow kolab to call its remove methods!"));
+    $ldap= $this->config->get_ldap_link();
+
+    /* If domain part was selectable, contruct mail address */
+    if(!(!$this->mailMethod->isModifyableMail() && $this->initially_was_account)){
+
+      if($this->mailMethod->domainSelectionEnabled()){
+        $this->mail = $this->mail."@".$this->mailDomainPart;
+      }
+
+      /* Enforce lowercase mail address and trim whitespaces
+       */
+      $this->mail = trim(strtolower($this->mail));
+    }
+
+
+    /* Call parents save to prepare $this->attrs */
+    plugin::save();
+
+    /* Save arrays */
+    $this->attrs['gosaMailAlternateAddress'] = $this->gosaMailAlternateAddress;
+    $this->attrs['gosaMailForwardingAddress']= $this->gosaMailForwardingAddress;
+
+    if(!$this->mailMethod->vacationRangeEnabled()){
+      $this->attrs['gosaVacationStart'] = $this->attrs['gosaVacationStop'] = array();
+    }elseif (!preg_match('/V/', $this->gosaMailDeliveryMode)){
+      unset($this->attrs['gosaVacationStart']);
+      unset($this->attrs['gosaVacationStop']);
+    } else {
+      /* Adapt values to be timestamps */
+      list($day, $month, $year)= explode('.', $this->gosaVacationStart);
+      $this->attrs['gosaVacationStart']= mktime(0,0,0,$month, $day, $year);
+      list($day, $month, $year)= explode('.', $this->gosaVacationStop);
+      $this->attrs['gosaVacationStop']= mktime(0,0,0,$month, $day, $year);
+    }
+
+    /* Map method attributes */ 
+    $this->mailMethod->fixAttributesOnStore();
+    
+    /* Save data to LDAP */
+    $ldap->cd($this->dn);
+    $this->cleanup();
+    $ldap->modify ($this->attrs);
+
+    if (!$ldap->success()){
+      msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_MOD, get_class()));
+    }
+
+    /* Log last action */
+    if($this->initially_was_account){
+      new log("modify","users/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
+    }else{
+      new log("create","users/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
+    }
+
+    /* Only do IMAP actions if we are not a template */
+    if (!$this->is_template){
+      $this->mailMethod->connect();
+      if(!$this->mailMethod->is_connected()){
+        msg_dialog::display(_("Mail error"), sprintf(_("Mail method cannot connect: %s"), 
+              $this->mailMethod->get_error()), ERROR_DIALOG);
+      }else{
+        if(!$this->mailMethod->updateMailbox()){
+          msg_dialog::display(_("Mail error"), sprintf(_("Cannot update mailbox: %s"), 
+                $this->mailMethod->get_error()), ERROR_DIALOG);
+        }
+        if(!$this->mailMethod->setQuota($this->gosaMailQuota)){
+          msg_dialog::display(_("Mail error"), sprintf(_("Cannot write quota settings: %s"), 
+                $this->mailMethod->get_error()), ERROR_DIALOG);
+        }
+
+        if (!is_integer(strpos($this->gosaMailDeliveryMode, "C"))){
+
+          /* Do not write sieve settings if this account is new and 
+             doesn't seem to exist.
+           */
+          if(!$this->initially_was_account && !$this->mailMethod->account_exists()){
+            @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__,
+                "Skipping sieve settings, the account doesn't seem to be created already.</b>","");
+          }else{
+            if(!$this->mailMethod->saveSieveSettings()){
+              msg_dialog::display(_("Mail error saving sieve settings"), $this->mailMethod->get_error(), ERROR_DIALOG);
+            }
+          }
+        }else{
+          if ($this->sieve_management) {
+            @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__, 
+                "User uses an own sieve script, skipping sieve update.".$str."</b>","");
+            $this->sieve_management->save();
           }
         }
       }
     }
           }
         }
       }
     }
-  }
+    $this->mailMethod->disconnect();
 
 
-   
-  function PrepareForCopyPaste($source)
-  {
-    plugin::PrepareForCopyPaste($source);
+    /* Update sharedFolder dependencies.
+       Open each shared folder and remove this account.
+       Then Save the group to ensure that all necessary
+       actions will be taken (imap acls updated aso.).
+     */
+    if(!$this->initially_was_account){
+      $ldap = $this->config->get_ldap_link();
+      $ldap->cd($this->config->current['BASE']);
+      $ldap->search("(&(objectClass=posixGroup)(objectClass=gosaMailAccount)(memberUid=".$this->uid."))",array("dn"));
+      while($attrs = $ldap->fetch()){
+        $grp = new grouptabs($this->config, $this->config->data['TABS']['GROUPTABS'], $attrs['dn']);
+        if(isset($grp->by_object['mailgroup'])){
+          /* Do not save the complete group! This will quit the complete membership
+           */
+          $grp->by_object['mailgroup']->save();
+        }
+      }
+    }
 
 
-    /* Reset alternate mail addresses */
-    $this->gosaMailAlternateAddress = array();    
-   }
+    /* Optionally execute a command after we're done */
+    if ($this->initially_was_account == $this->is_account){
+      if ($this->is_modified){
+        $this->handle_post_events("modify", array("uid" => $this->uid));
+      }
+    } else {
+      $this->handle_post_events("add", array("uid" => $this->uid));
+    }
+  }
 
 
 
 
-  static function plInfo()
+  /*! \brief  Check given values 
+   */
+  function check()
   {
   {
-    return (array(
-          "plShortName"     => _("Mail"),
-          "plDescription"   => _("Mail settings"),
-          "plSelfModify"    => TRUE,
-          "plDepends"       => array("user"),                     // This plugin depends on
-          "plPriority"      => 4,                                 // Position in tabs
-          "plSection"     => array("personal" => _("My account")),
-          "plCategory"    => array("users"),
-          "plOptions"       => array(),
-  
-          "plProvidedAcls"  => array(
-            "mail"                      =>  _("Mail address"),
-            "gosaMailServer"            =>  _("Mail server"),
-            "gosaMailQuota"             =>  _("Quota size"),
+    if(!$this->is_account){
+      return(array());
+    }
 
 
-            "gosaMailDeliveryModeV"     =>  _("Add vacation information"),  // This is flag of gosaMailDeliveryMode
-            "gosaVacationMessage"       =>  _("Vacation message"),
+    $ldap= $this->config->get_ldap_link();
 
 
-            "gosaMailDeliveryModeS"     =>  _("Use spam filter"),           // This is flag of gosaMailDeliveryMode
-            "gosaSpamSortLevel"         =>  _("Spam level"),
-            "gosaSpamMailbox"           =>  _("Spam mail box"),
+    /* Call common method to give check the hook */
+    $message= plugin::check();
 
 
-            "sieveManagement"           =>  _("Sieve management"),
+    if(empty($this->gosaMailServer)){
+      $message[]= msgPool::noserver(_("Mail"));
+    }
 
 
-            "gosaMailDeliveryModeR"     =>  _("Reject due to mailsize"),    // This is flag of gosaMailDeliveryMode
-            "gosaMailMaxSize"           =>  _("Mail max size"),
+    /* Mail address checks */
+    $mail = $this->mail;
+    if(!(!$this->mailMethod->isModifyableMail() && $this->initially_was_account)){
 
 
-            "gosaMailForwardingAddress" =>  _("Forwarding address"),
-            "gosaMailDeliveryModeL"     =>  _("Local delivery"),            // This is flag of gosaMailDeliveryMode
-            "gosaMailDeliveryModeI"     =>  _("No delivery to own mailbox "),     // This is flag of gosaMailDeliveryMode
-            "gosaMailAlternateAddress"  =>  _("Mail alternative addresses"),
+      if($this->mailMethod->domainSelectionEnabled()){
+        $mail.= "@".$this->mailDomainPart;
+      }
+
+      if (empty($mail)){
+        $message[]= msgPool::required(_("Primary address"));
+      }
+      if ($this->is_template){
+        if (!tests::is_email($mail, TRUE)){
+          $message[]= msgPool::invalid(_("Mail address"),"","","%givenName.%sn@your-domain.com");
+        }
+      } else {
+        if (!tests::is_email($mail)){
+          $message[]= msgPool::invalid(_("Mail address"),"","","your-address@your-domain.com");
+        }
+      }
+
+      /* Check if this mail address is already in use */
+      $ldap->cd($this->config->current['BASE']);
+      $filter = "(&(!(objectClass=gosaUserTemplate))(!(uid=".$this->uid."))".
+        "(objectClass=gosaMailAccount)".
+        "(|(mail=".$mail.")(alias=".$mail.")(gosaMailAlternateAddress=".$mail.")))";
+      $ldap->search($filter,array("uid", "cn"));
+      if ($ldap->count() != 0){
+        $entry= $ldap->fetch();
+        $addon= "";
+        if (!isset($entry['uid'])) {
+           $addon= sprintf(_("Address is already in use by group '%s'."), $entry['cn'][0]);
+        } else {
+           $addon= sprintf(_("Address is already in use by user '%s'."), $entry['uid'][0]);
+        }
+        $message[]= msgPool::duplicated(_("Mail address"))."<br><br><i>$addon</i>";
+      }
+    }
 
 
-            "gosaMailForwardingAddress" =>  _("Forwarding address"),
-            "gosaMailDeliveryModeC"     =>  _("Use custom sieve script"))   // This is flag of gosaMailDeliveryMode
-        ));
-  }
 
 
+    /* Check quota */
+    if ($this->gosaMailQuota != '' && $this->acl_is_writeable("gosaMailQuota")){
+      if (!is_numeric($this->gosaMailQuota)) {
+        $message[]= msgPool::invalid(_("Quota size"),$this->gosaMailQuota,"/^[0-9]*/");
+      } else {
+        $this->gosaMailQuota= (int) $this->gosaMailQuota;
+      }
+    }
 
 
-  /*! \brief  Prepare importet vacation string. \
-              Replace placeholder like %givenName a.s.o.
-      @param  string  Vacation string
-      @return string  Completed vacation string
-   */  
-  private function prepare_vacation_template($contents)
-  {
-    /* Replace attributes */
-    $attrs = array();
-    $obj   = NULL;
-    if(isset($this->parent->by_object['user'])){
-      $attrs  = $this->parent->by_object['user']->attributes;
-      $obj    = $this->parent->by_object['user'];
-    }else{
-      $obj    = new user($this->config,$this->dn);
-      $attrs  = $obj->attributes;
+    /* Check rejectsize for integer */
+    if ($this->gosaMailMaxSize != '' && $this->acl_is_writeable("gosaMailMaxSize")){
+      if (!is_numeric($this->gosaMailMaxSize)){
+        $message[]= msgPool::invalid(_("Mail reject size"),$this->gosaMailMaxSize,"/^[0-9]*/");
+      } else {
+        $this->gosaMailMaxSize= (int) $this->gosaMailMaxSize;
+      }
     }
 
     }
 
-    if($obj){
-      foreach ($attrs as $val){
-        if(preg_match("/dateOfBirth/",$val)){
-          if($obj->use_dob){
-            $contents= preg_replace("/%$val/",date("Y-d-m",$obj->dateOfBirth),$contents);
-          }
-        }else {
-          $contents= preg_replace("/%$val/",
-              $obj->$val, $contents);
-        }
+    /* Need gosaMailMaxSize if use_mailsize_limit is checked */
+    if (is_integer(strpos($this->gosaMailDeliveryMode, "R")) && $this->gosaMailMaxSize == ""){
+      $message[]= msgPool::required(_("Mail reject size"));
+    }
 
 
-        /* Replace vacation start and end time */
-        if(preg_match("/%start/",$contents)){
-          $contents = preg_replace("/%start/",date("d.m.Y",$this->gosaVacationStart),$contents);
-        }
-        if(preg_match("/%end/",$contents)){
-          $contents = preg_replace("/%end/",date("d.m.Y",$this->gosaVacationStop),$contents);
+    if((preg_match("/S/", $this->gosaMailDeliveryMode))&&(empty($this->gosaSpamMailbox))) {
+      $message[]= msgPool::required(_("Spam folder"));
+    }
+
+    if ($this->mailMethod->vacationRangeEnabled() && preg_match('/V/', $this->gosaMailDeliveryMode)){ 
+
+      /* Check date strings */
+      $state= true;
+      if ($this->gosaVacationStart == "" || !tests::is_date($this->gosaVacationStart)) {
+        $message[]= msgPool::invalid(_("from"),$this->gosaVacationStart);
+        $state= false;
+      }
+      if ($this->gosaVacationStart == "" || !tests::is_date($this->gosaVacationStop)) {
+        $message[]= msgPool::invalid(_("to"),$this->gosaVacationStop);
+        $state= false;
+      }
+
+      #TODO: take care of date format
+      if ($state) {
+        list($day, $month, $year)= explode('.', $this->gosaVacationStart);
+        $start= mktime(0,0,0,$month, $day, $year);
+        list($day, $month, $year)= explode('.', $this->gosaVacationStop);
+        $stop= mktime(0,0,0,$month, $day, $year);
+        if($start > $stop){
+          $message[]= msgPool::invalid(_("Vacation interval"));
         }
       }
     }
         }
       }
     }
-    return($contents);
+    return($message);
   }
 
   }
 
-  
 
 
-  /* Upated shared folder ACLs 
+  /*! \brief  Adapt from template, using 'dn' 
    */
    */
-  function updateSharedFolder()
+  function adapt_from_template($dn, $skip= array())
   {
   {
-    $ldap = $this->config->get_ldap_link();
-    $ldap->cd($this->config->current['BASE']);
-    $ldap->search("(&(objectClass=posixGroup)(objectClass=gosaMailAccount)(memberUid=".$this->uid."))",array('dn','cn'));
-    if(class_exists("grouptabs")){
-      while($attrs = $ldap->fetch()){
-        $tmp = new grouptabs($this->config, $this->config->data['TABS']['GROUPTABS'], $attrs['dn']);
-        if(isset($tmp->by_object['mailgroup'])){
-          $tmp->by_object['mailgroup']->members= $tmp->by_object['group']->memberUid;
-          if(!$this->is_account){
-            $tmp->by_object['mailgroup']->removeUserAcl($this->uid);
-            $tmp->by_object['mailgroup']->removeUserAcl($this->mail);
+    plugin::adapt_from_template($dn, $skip);
+
+    foreach (array("gosaMailAlternateAddress", "gosaMailForwardingAddress") as $val){
+
+      if (in_array($val, $skip)){
+        continue;
+      }
+
+      $this->$val= array();
+      if (isset($this->attrs["$val"]["count"])){
+        for ($i= 0; $i<$this->attrs["$val"]["count"]; $i++){
+          $value= $this->attrs["$val"][$i];
+          foreach (array("sn", "givenName", "uid") as $repl){
+            if (preg_match("/%$repl/i", $value)){
+              $value= preg_replace ("/%$repl/i", $this->parent->$repl, $value);
+            }
           }
           }
-          $tmp->by_object['mailgroup']->save();
+          array_push($this->$val, strtolower(rewrite($value)));
         }
       }
         }
       }
-    } 
-  }
-
-  /* Initialize plugin with given atribute arrays
-   */
-  function init_multiple_support($attrs,$all)
-  {
-    plugin::init_multiple_support($attrs,$all);
+    }
+    $this->mail= strtolower(rewrite($this->mail));
 
 
-    if(isset($this->multi_attrs['gosaMailQuota'])){
-      $this->gosaMailQuota = $this->multi_attrs['gosaMailQuota'];
+    // Fix mail address when using templates
+    if($this->is_account && $this->mailMethod->domainSelectionEnabled()){
+      $this->mailDomainPart = preg_replace("/^[^@]*+@/","",$this->mail);
+      $this->mail = preg_replace("/@.*$/","\\1",$this->mail);
+      if(!in_array($this->mailDomainPart,$this->mailDomainParts)){
+        $this->mailDomainParts[] = $this->mailDomainPart;
+      }
     }
   }
 
     }
   }
 
-  function get_multi_init_values()
+
+  /*! \brief  Creates the mail part for the copy & paste dialog 
+   */ 
+  function getCopyDialog()
   {
   {
-    $attrs = plugin::get_multi_init_values();
-    $attrs['gosaMailQuota'] = $this->gosaMailQuota;
-    return($attrs);
+    if(!$this->is_account) return("");
+    $smarty = get_smarty();
+    $smarty->assign("mail",$this->mail);
+    $smarty->assign("gosaMailAlternateAddress",$this->gosaMailAlternateAddress);
+    $smarty->assign("gosaMailForwardingAddress",$this->gosaMailForwardingAddress);
+    $str = $smarty->fetch(get_template_path("copypaste.tpl",TRUE, dirname(__FILE__)));
+
+    $ret = array();
+    $ret['status'] = "";
+    $ret['string'] = $str;
+    return($ret);
   }
 
   }
 
-  function multiple_execute()
+    
+  /*! \brief  save_object for copy&paste vars 
+   */  
+  function saveCopyDialog()
   {
   {
-    return($this->execute());
+    if(!$this->is_account) return;
+
+    /* Execute to save mailAlternateAddress && gosaMailForwardingAddress */
+    $this->execute();
+    if(isset($_POST['mail'])){
+      $this->mail = $_POST['mail'];
+    }
   }
 
   }
 
-  function multiple_save_object()
+  
+  /*! \brief  Prepare this account to be copied 
+   */
+  function PrepareForCopyPaste($source)
   {
   {
-    plugin::multiple_save_object();
+    plugin::PrepareForCopyPaste($source);
 
 
-    $this->save_object();
-    foreach(array("only_local","gosaMailForwardingAddress","use_mailsize_limit","drop_own_mails","use_vacation","use_spam_filter") as $attr){
-      if(isset($_POST["use_".$attr])){
-        $this->multi_boxes[] = $attr;
-      }
-    }
+    /* Reset alternate mail addresses */
+    $this->gosaMailAlternateAddress = array();
   }
 
   }
 
+
+  /*! \brief  Prepare this class the be useable when editing multiple users at once 
+   */
   function get_multi_edit_values()
   {
     $ret = plugin::get_multi_edit_values();
   function get_multi_edit_values()
   {
     $ret = plugin::get_multi_edit_values();
-
     if(in_array("gosaMailQuota",$this->multi_boxes)){
       $ret['gosaMailQuota'] = $this->gosaMailQuota;
     }
     if(in_array("gosaMailQuota",$this->multi_boxes)){
       $ret['gosaMailQuota'] = $this->gosaMailQuota;
     }
-
     $flag_add = $flag_remove = array();
     $tmp= preg_replace("/[^a-z]/i","",$this->gosaMailDeliveryMode);
     $opts = array(
     $flag_add = $flag_remove = array();
     $tmp= preg_replace("/[^a-z]/i","",$this->gosaMailDeliveryMode);
     $opts = array(
@@ -1304,7 +1180,6 @@ class mailAccount extends plugin
         "V"   => "use_vacation",
         "C"   => "own_script",
         "I"   => "drop_own_mails");
         "V"   => "use_vacation",
         "C"   => "own_script",
         "I"   => "drop_own_mails");
-
     foreach($opts as $flag => $post){
       if(in_array($post, $this->multi_boxes)){
         if(preg_match("/".$flag."/",$tmp)){
     foreach($opts as $flag => $post){
       if(in_array($post, $this->multi_boxes)){
         if(preg_match("/".$flag."/",$tmp)){
@@ -1314,13 +1189,21 @@ class mailAccount extends plugin
         }
       }
     }
         }
       }
     }
-  
     $ret['flag_add'] = $flag_add;
     $ret['flag_remove'] = $flag_remove;
     $ret['flag_add'] = $flag_add;
     $ret['flag_remove'] = $flag_remove;
+
+    if($this->mailMethod->vacationRangeEnabled()){
+      if(in_array("V",$flag_add)){
+        $ret['gosaVacationStart'] =  $this->gosaVacationStart = $_POST['gosaVacationStart'];
+        $ret['gosaVacationStop'] =  $this->gosaVacationStop = $_POST['gosaVacationStop'];
+      }
+    }
     return($ret);
   }
 
 
     return($ret);
   }
 
 
+  /*! \brief  Check given input for multiple user edit 
+   */
   function multiple_check()
   {
     $message = plugin::multiple_check();
   function multiple_check()
   {
     $message = plugin::multiple_check();
@@ -1351,14 +1234,36 @@ class mailAccount extends plugin
       $message[]= msgPool::required(_("Spam folder"));
     }
 
       $message[]= msgPool::required(_("Spam folder"));
     }
 
-    if (  in_array("use_vacation",$this->multi_boxes) &&
-          preg_match('/V/', $this->gosaMailDeliveryMode) && $this->gosaVacationStart > $this->gosaVacationStop){
-      $message[]= msgPool::invalid(_("Vacation interval"));
+    if ($this->mailMethod->vacationRangeEnabled() && preg_match('/V/', $this->gosaMailDeliveryMode)){ 
+
+      /* Check date strings */
+      $state= true;
+      if ($this->gosaVacationStart == "" || !tests::is_date($this->gosaVacationStart)) {
+        $message[]= msgPool::invalid(_("from"),$this->gosaVacationStart);
+        $state= false;
+      }
+      if ($this->gosaVacationStart == "" || !tests::is_date($this->gosaVacationStop)) {
+        $message[]= msgPool::invalid(_("to"),$this->gosaVacationStop);
+        $state= false;
+      }
+
+      #TODO: take care of date format
+      if ($state) {
+        list($day, $month, $year)= explode('.', $this->gosaVacationStart);
+        $start= mktime(0,0,0,$month, $day, $year);
+        list($day, $month, $year)= explode('.', $this->gosaVacationStop);
+        $stop= mktime(0,0,0,$month, $day, $year);
+        if($start > $stop){
+          $message[]= msgPool::invalid(_("Vacation interval"));
+        }
+      }
     }
     return($message);
   }
 
     }
     return($message);
   }
 
-
+  
+  /*! \brief  ...
+   */
   function set_multi_edit_values($values)
   {
     plugin::set_multi_edit_values($values);
   function set_multi_edit_values($values)
   {
     plugin::set_multi_edit_values($values);
@@ -1379,12 +1284,134 @@ class mailAccount extends plugin
     }
     $this->gosaMailDeliveryMode = "[".$tmp."]";
 
     }
     $this->gosaMailDeliveryMode = "[".$tmp."]";
 
-    /* Set vacation message and replace placeholder like %givenName 
+    /* Set vacation message and replace placeholder like %givenName
      */
     if(isset($values['gosaVacationMessage'])){
       $this->gosaVacationMessage = $this->prepare_vacation_template($values['gosaVacationMessage']);
     }
   }
      */
     if(isset($values['gosaVacationMessage'])){
       $this->gosaVacationMessage = $this->prepare_vacation_template($values['gosaVacationMessage']);
     }
   }
+
+
+  /*! \brief  Initialize plugin to be used as multiple edit class. 
+   */
+  function init_multiple_support($attrs,$all)
+  {
+    plugin::init_multiple_support($attrs,$all);
+    if(isset($this->multi_attrs['gosaMailQuota'])){
+      $this->gosaMailQuota = $this->multi_attrs['gosaMailQuota'];
+    }
+  }
+
+  /*! \brief
+   */
+  function get_multi_init_values()
+  {
+    $attrs = plugin::get_multi_init_values();
+    $attrs['gosaMailQuota'] = $this->gosaMailQuota;
+    return($attrs);
+  }
+
+
+  /*! \brief  Display multiple edit dialog 
+   */
+  function multiple_execute()
+  {
+    return($this->execute());
+  }
+
+  
+  /*! \brief  Save posts from multiple edit dialog 
+   */
+  function multiple_save_object()
+  {
+    plugin::multiple_save_object();
+
+    $this->save_object();
+    foreach(array("only_local","gosaMailForwardingAddress","use_mailsize_limit","drop_own_mails","use_vacation","use_spam_filter") as $attr){
+      if(isset($_POST["use_".$attr])){
+        $this->multi_boxes[] = $attr;
+      }
+    }
+  }
+
+
+  /*! \brief  Creates the user names for the add_local_forward dialog
+   */
+  function make_name($attrs)
+  {
+    $name= "";
+    if (isset($attrs['sn'][0])){
+      $name= $attrs['sn'][0];
+    }
+    if (isset($attrs['givenName'][0])){
+      if ($name != ""){
+        $name.= ", ".$attrs['givenName'][0];
+      } else {
+        $name.= $attrs['givenName'][0];
+      }
+    }
+    if ($name != ""){
+      $name.= " ";
+    }
+
+    return ($name);
+  }
+
+
+  function allow_remove()
+  {
+    $resason = "";
+    if(!$this->mailMethod->allow_remove($reason)){
+      return($reason);
+    }
+    return("");
+  }
+
+
+
+  /*! \brief  ACL settings 
+   */
+  static function plInfo()
+  {
+    return (array(
+          "plShortName"     => _("Mail"),
+          "plDescription"   => _("Mail settings"),
+          "plSelfModify"    => TRUE,
+          "plDepends"       => array("user"),                     // This plugin depends on
+          "plPriority"      => 4,                                 // Position in tabs
+          "plSection"     => array("personal" => _("My account")),
+          "plCategory"    => array("users"),
+          "plOptions"       => array(),
+
+          "plProvidedAcls"  => array(
+            "mail"                      =>  _("Mail address"),
+            "gosaMailServer"            =>  _("Mail server"),
+            "gosaMailQuota"             =>  _("Quota size"),
+
+            "gosaMailDeliveryModeV"     =>  _("Add vacation information"),  // This is flag of gosaMailDeliveryMode
+            "gosaVacationMessage"       =>  _("Vacation message"),
+
+            "gosaMailDeliveryModeS"     =>  _("Use spam filter"),           // This is flag of gosaMailDeliveryMode
+            "gosaSpamSortLevel"         =>  _("Spam level"),
+            "gosaSpamMailbox"           =>  _("Spam mail box"),
+
+            "sieveManagement"           =>  _("Sieve management"),
+
+            "gosaMailDeliveryModeR"     =>  _("Reject due to mailsize"),    // This is flag of gosaMailDeliveryMode
+            "gosaMailMaxSize"           =>  _("Mail max size"),
+
+            "gosaMailForwardingAddress" =>  _("Forwarding address"),
+            "gosaMailDeliveryModeL"     =>  _("Local delivery"),            // This is flag of gosaMailDeliveryMode
+            "gosaMailDeliveryModeI"     =>  _("No delivery to own mailbox "),     // This is flag of gosaMailDeliveryMode
+            "gosaMailAlternateAddress"  =>  _("Mail alternative addresses"),
+
+            "gosaMailForwardingAddress" =>  _("Forwarding address"),
+            "gosaMailDeliveryModeC"     =>  _("Use custom sieve script"))   // This is flag of gosaMailDeliveryMode
+              ));
+  }
+
+
 }
 
 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
 }
 
 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler: