From f734a0d9dfde8fbf45224542961d55a93ea4101a Mon Sep 17 00:00:00 2001
From: Riccardo De Maria <riccardodemaria@gmail.com>
Date: Tue, 24 May 2022 14:24:55 +0200
Subject: [PATCH 1/4] adding last option in install

---
 Makefile_test                                |   2 +-
 src/mad_dict.c                               |   6 +-
 src/mad_seq.c                                | 214 ++++++++++---------
 tests/test-sequence-10/ssfirst.cfg           |   0
 tests/test-sequence-10/ssfirst.ref           |  29 +++
 tests/test-sequence-10/sslast.cfg            |   0
 tests/test-sequence-10/sslast.ref            |  29 +++
 tests/test-sequence-10/test-sequence-10.cfg  |   1 +
 tests/test-sequence-10/test-sequence-10.madx |  57 +++++
 tests/test-sequence-10/test-sequence-10.ref  | 151 +++++++++++++
 10 files changed, 387 insertions(+), 102 deletions(-)
 create mode 100644 tests/test-sequence-10/ssfirst.cfg
 create mode 100644 tests/test-sequence-10/ssfirst.ref
 create mode 100644 tests/test-sequence-10/sslast.cfg
 create mode 100644 tests/test-sequence-10/sslast.ref
 create mode 100644 tests/test-sequence-10/test-sequence-10.cfg
 create mode 100644 tests/test-sequence-10/test-sequence-10.madx
 create mode 100644 tests/test-sequence-10/test-sequence-10.ref

diff --git a/Makefile_test b/Makefile_test
index 686853a8c..a1a6ba9b1 100644
--- a/Makefile_test
+++ b/Makefile_test
@@ -89,7 +89,7 @@ test-ptc-track-polygonaper \
 test-ptc-trackline test-ptc-trackline-2 test-ptc-trackline-3 \
 test-ptc-align test-ptc-align-2 \
 test-touschek test-touschek-2 \
-test-sequence test-sequence-2 test-sequence-3 test-sequence-4 test-sequence-5 test-sequence-6 test-sequence-7 test-sequence-8 test-sequence-9\
+test-sequence test-sequence-2 test-sequence-3 test-sequence-4 test-sequence-5 test-sequence-6 test-sequence-7 test-sequence-8 test-sequence-9 test-sequence-10\
 test-line \
 test-plot test-plot-2 \
 test-setknob test-fillknob \
diff --git a/src/mad_dict.c b/src/mad_dict.c
index 1b4334538..7eb2f774d 100644
--- a/src/mad_dict.c
+++ b/src/mad_dict.c
@@ -921,13 +921,15 @@ const char *const_command_def =
 "element  = [s, none, none], "
 "class    = [s, none, none], "
 "at       = [r, 0, 0], "
-"from     = [s, none, none]; "
+"from     = [s, none, none], "
+"last     = [l, true, true]; "
 " "
 "move: edit edit 0 0 "
 "element  = [s, none, none], "
 "by       = [r, 0, 0], "
 "to       = [r, 0, 0], "
-"from     = [s, none, none]; "
+"from     = [s, none, none], "
+"last     = [l, true, true]; "
 " "
 "remove: edit edit 0 0 "
 "element  = [s, none, none]; "
diff --git a/src/mad_seq.c b/src/mad_seq.c
index 3694f12f2..fe9bdcf90 100644
--- a/src/mad_seq.c
+++ b/src/mad_seq.c
@@ -357,7 +357,7 @@ expand_line(struct char_p_array* l_buff)
       if (b_level->i[i] == level && (pos = lbpos->i[i]) > 1) {
         if (*l_buff->p[pos-1] == '*') {
           sscanf(l_buff->p[pos-2], "%d", &rep);
-	  add = rep - 1;
+          add = rep - 1;
           number = rbpos->i[i] - pos - 1; /* inside bracket */
           n = number * add; /* extra tokens */
           while (l_buff->curr + n >= l_buff->max) grow_char_p_array(l_buff);
@@ -481,7 +481,7 @@ expand_sequence(struct sequence* sequ, int flag)
 
   if (debug)
     printf("\n\nTOP Expand_sequence name %s with length %e, ref_flag %d\n",
-	   sequ->name, sequ->length, sequ->ref_flag);
+           sequ->name, sequ->length, sequ->ref_flag);
 
   p = sequ->ex_start = clone_node(sequ->start, 0);
   add_to_node_list(p, 0, sequ->ex_nodes);
@@ -496,25 +496,25 @@ expand_sequence(struct sequence* sequ, int flag)
     if (p->p_sequ == NULL) { // simple element, not a subsequence
       // 2015-Jun-09  14:14:24  ghislain: guard added for negative element length
       if (p->length < 0)
-	fatal_error("trying to add node with negative length to current sequence:", p->name);
+        fatal_error("trying to add node with negative length to current sequence:", p->name);
 
       add_to_node_list(p, 0, sequ->ex_nodes);
     }
     else { // subsequence
       if (p->p_sequ->refpos != NULL) { // REFPOS given for subsequence, ignore REFER of current sequence
-	if (debug)
-	  printf("\n\n Expand sub-sequence %s with initial position %e, final position %e, length %e, ref_flag %d, refpos '%s'\n",
-		 p->name, p->position, p->position - sequ->ref_flag*p->p_sequ->length/2.,
-		 p->length, sequ->ref_flag, p->p_sequ->refpos);
-	p = expand_node(p, sequ, sequ, p->position - sequ->ref_flag*p->p_sequ->length/2. );
-	if (debug) printf("\n\n");
+        if (debug)
+          printf("\n\n Expand sub-sequence %s with initial position %e, final position %e, length %e, ref_flag %d, refpos '%s'\n",
+                 p->name, p->position, p->position - sequ->ref_flag*p->p_sequ->length/2.,
+                 p->length, sequ->ref_flag, p->p_sequ->refpos);
+        p = expand_node(p, sequ, sequ, p->position - sequ->ref_flag*p->p_sequ->length/2. );
+        if (debug) printf("\n\n");
       }
       else { // no REFPOS given
-	if (debug)
-	  printf("\n\n Expand sub-sequence %s with position %e, length %e, ref_flag %d\n",
-		 p->name, p->position, p->length, sequ->ref_flag);
-	p = expand_node(p, sequ, sequ, p->position);
-	if (debug) printf("\n\n");
+        if (debug)
+          printf("\n\n Expand sub-sequence %s with position %e, length %e, ref_flag %d\n",
+                 p->name, p->position, p->length, sequ->ref_flag);
+        p = expand_node(p, sequ, sequ, p->position);
+        if (debug) printf("\n\n");
       }
     }
   }
@@ -578,20 +578,32 @@ seq_flatten(struct sequence* sequ)
 }
 
 static void
-insert_elem(struct sequence* sequ, struct node* node)
-  /* inserts an element in a sequence as function of its position */
+insert_elem(struct sequence* sequ, struct node* node, int last)
+  /* inserts an element in a sequence as function of its position
+   * if there is another element in the same localtion, if last is True */
 {
   struct node* c_node = sequ->start->next;
 
-  while (c_node != NULL) {
-    if (node->position <= c_node->position || c_node == sequ->end) break;
-    c_node = c_node->next;
-  }
+  if (last)
+      for(; c_node && c_node != sequ->end && node->position >= c_node->position; c_node = c_node->next );
+  else
+      for(; c_node && c_node != sequ->end && node->position > c_node->position; c_node = c_node->next );
+
+  //while (c_node != NULL) {
+  //  if (node->position <= c_node->position || c_node == sequ->end) break;
+  //  c_node = c_node->next;
+  //}
+
+//  if (last)
+//      for(; c_node && (c_node != sequ->end || node->position >= c_node->position); c_node = c_node->next );
+//  else
+//      for(; c_node && (c_node != sequ->end || node->position > c_node->position); c_node = c_node->next );
+
   link_in_front(node, c_node);
 }
 
 static struct node*
-install_one(struct element* el, char* from_name, double at_value, struct expression* at_expr, double position)
+install_one(struct element* el, char* from_name, double at_value, struct expression* at_expr, double position, int last)
   /* adds an element to a sequence */
 {
   struct node* node;
@@ -611,7 +623,7 @@ install_one(struct element* el, char* from_name, double at_value, struct express
   node->at_expr = at_expr;
   node->from_name = from_name;
   set_command_par_value("at", el->def, position);
-  insert_elem(edit_sequ, node);
+  insert_elem(edit_sequ, node, last);
   return node;
 }
 
@@ -625,7 +637,7 @@ make_sequ_from_line(char* name)
   int mpos = name_list_pos("marker", defined_commands->list);
   struct command* clone = clone_command(defined_commands->commands[mpos]);
   struct element* el;
-  
+
   if (pos < 0) fatal_error("unknown line: ", name);
   line = line_list->macros[pos];
   line->dead = 1;   /* prevent line from further conversion to sequence */
@@ -658,10 +670,10 @@ make_sequ_from_line(char* name)
   current_sequ->end = current_node;
   current_sequ->start->previous = current_sequ->end;
   current_sequ->end->next = current_sequ->start;
-  
+
   /*current_sequ->line = 1;  remember origin of sequence */
   //printf("skowron: warning make_sequ_from_line line=0 \n");
-  current_sequ->line = 0; // remember origin of sequence 
+  current_sequ->line = 0; // remember origin of sequence
 
   if(line_buffer) delete_char_p_array(line_buffer,1);
 }
@@ -916,7 +928,7 @@ seq_cycle(struct in_cmd* cmd)
         strcpy(clone->p_elem->name, c_dum->c);
 
         /* IA 29.11.07 : fixes a bug with aperture module */
-	     /* Removed HG 11.10.2009 */
+             /* Removed HG 11.10.2009 */
         /* sprintf(c_dum->c, " ");
            set_command_par_string("apertype", clone->p_elem->def,c_dum->c); */
 
@@ -979,10 +991,13 @@ seq_install(struct in_cmd* cmd)
   double at, from = zero;
   char name[NAME_L], *pname, *name_e = NULL, *name_c = NULL, *from_name = NULL;
   int k, any = 0;
+  int last; // if last is true, an element at the same location is installed in the end
 
   name_e = command_par_string_user("element", cmd->clone);
   name_c = command_par_string_user("class", cmd->clone);
 
+  last = command_par_value("last", cmd->clone);
+
   if (name_e) {
     if (name_c) {
       if ((cl = find_element(name_c, element_list)) == NULL) {
@@ -1016,26 +1031,26 @@ seq_install(struct in_cmd* cmd)
     if (strcmp(from_name, "selected") == 0) {
       if (seqedit_select->curr == 0) {
         warning("no active select commands:", "ignored");
-	return;
+        return;
       }
       if (get_select_ranges(edit_sequ, seqedit_select, selected_ranges) == 0) any = 1;
       c_node = edit_sequ->start;
       while (c_node != NULL) {
-	if (any || name_list_pos(c_node->name, selected_ranges->list) > -1) {
-	  for (k = 0; k < seqedit_select->curr; k++) {
-	    myrepl(":", "[", c_node->name, name);
-	    strcat(name, "]");
-	    if (strchr(name, '$') == NULL && pass_select_el(c_node->p_elem, seqedit_select->commands[k])) break;
-	  }
-	  if (k < seqedit_select->curr) {
-	    from = get_node_pos(c_node, edit_sequ);
-	    pname = permbuff(name);
-	    install_one(el, pname, at, expr, at+from);
-	    seqedit_install++;
-	  }
-	}
-	if (c_node == edit_sequ->end) break;
-	c_node = c_node->next;
+        if (any || name_list_pos(c_node->name, selected_ranges->list) > -1) {
+          for (k = 0; k < seqedit_select->curr; k++) {
+            myrepl(":", "[", c_node->name, name);
+            strcat(name, "]");
+            if (strchr(name, '$') == NULL && pass_select_el(c_node->p_elem, seqedit_select->commands[k])) break;
+          }
+          if (k < seqedit_select->curr) {
+            from = get_node_pos(c_node, edit_sequ);
+            pname = permbuff(name);
+            install_one(el, pname, at, expr, at+from, last);
+            seqedit_install++;
+          }
+        }
+        if (c_node == edit_sequ->end) break;
+        c_node = c_node->next;
       }
 
     } else {
@@ -1044,11 +1059,11 @@ seq_install(struct in_cmd* cmd)
         warning("ignoring 'from' reference to unknown element:", from_name);
         return;
       }
-      install_one(el, from_name, at, expr, at+from);
+      install_one(el, from_name, at, expr, at+from, last);
       seqedit_install++;
     }
   } else {
-    install_one(el, from_name, at, expr, at);
+    install_one(el, from_name, at, expr, at, last);
     seqedit_install++;
   }
 }
@@ -1064,8 +1079,10 @@ seq_move_noexpression(struct in_cmd* cmd)
   struct element* el;
   int pos;
   char tmp[2*NAME_L];
+  int last;
 
   name = command_par_string_user("element", cmd->clone);
+  last = command_par_value("last", cmd->clone);
   if (name)
   {
     if (strcmp(name, "selected") == 0)
@@ -1098,7 +1115,7 @@ seq_move_noexpression(struct in_cmd* cmd)
             if (any
                 || name_list_pos(node->name, selected_ranges->list) > -1)
             {
-              
+
               name = NULL;
               for (k = 0; k < seqedit_select->curr; k++)
               {
@@ -1114,7 +1131,7 @@ seq_move_noexpression(struct in_cmd* cmd)
 
                 if (remove_one(node) > 0)
                 {
-                  node = install_one(el, NULL, at, NULL, at);
+                  node = install_one(el, NULL, at, NULL, at,last);
                   node->moved = 1;
                   seqedit_move++;
                 }
@@ -1131,7 +1148,7 @@ seq_move_noexpression(struct in_cmd* cmd)
                   el = node->p_elem;
                   if (remove_one(node) > 0)
                   {
-                    node = install_one(el, NULL, at, NULL, at);
+                    node = install_one(el, NULL, at, NULL, at,last);
                     node->moved = 1;
                     seqedit_move++;
                   }
@@ -1176,10 +1193,10 @@ seq_move_noexpression(struct in_cmd* cmd)
 
         }
         el = node->p_elem;
-       
+
         if (remove_one(node) > 0)
         {
-          install_one(el, NULL, at, NULL, at);
+          install_one(el, NULL, at, NULL, at,last);
           seqedit_move++;
         }
       }
@@ -1196,15 +1213,14 @@ seq_move_expression(struct in_cmd* cmd)
       struct node *node, *next, *node2, *next2;
       struct element* el;
       int pos, is_ref_from_moved,max_c=100;
-      struct expression* tmp = NULL; 
+      struct expression* tmp = NULL;
       struct expression* expr = NULL;
       struct expression* newexp = NULL;
-      struct name_list* movelist;  
-     
-
-
+      struct name_list* movelist;
+      int last;
 
       name = command_par_string_user("element", cmd->clone);
+      last = command_par_value("last", cmd->clone);
       if (name)
       {
         if (strcmp(name, "selected") == 0)
@@ -1266,7 +1282,7 @@ seq_move_expression(struct in_cmd* cmd)
                       free(result);
                     }
                     if(tmp==NULL)
-                    { 
+                    {
                      char *result = malloc(max_c * sizeof(char));
                      sprintf(result, "%.16f", node->position);
                      tmp = new_expression(result,NULL);
@@ -1300,12 +1316,12 @@ seq_move_expression(struct in_cmd* cmd)
                             if (node2->p_elem != NULL) name = node2->p_elem->name;
                             if (name != NULL && strchr(name, '$') == NULL &&
                               pass_select_el(node2->p_elem,
-                                seqedit_select->commands[k])) 
+                                seqedit_select->commands[k]))
                             {
                               if(strcmp(from_name, name)==0)
                               {
                                 is_ref_from_moved=1;
-                                
+
                               }
                                 break;
                             }
@@ -1337,7 +1353,7 @@ seq_move_expression(struct in_cmd* cmd)
                       expr = clone_expression(command_par_expr("by", cmd->clone));
                       tmp = clone_expression(node->at_expr);
                         if(expr==NULL)
-                        { 
+                        {
 
                           char *result = malloc(max_c * sizeof(char));
                           sprintf(result, "%.16f", by);
@@ -1345,7 +1361,7 @@ seq_move_expression(struct in_cmd* cmd)
                           free(result);
                         }
                         if(tmp==NULL)
-                        { 
+                        {
                           char *result = malloc(max_c * sizeof(char));
                           sprintf(result, "%.16f", node->at_value);
 
@@ -1358,13 +1374,13 @@ seq_move_expression(struct in_cmd* cmd)
                         //printf("heeeereee %e %e\n", expression_value(tmp, 2), expression_value(expr, 2));
                         //printf("heeeereeea %.16e, %.16e \n", expression_value(newexp, 2), at);
                         //dump_expression(newexp);
-                      
+
                     }
                   }
 
                   if (remove_one(node) > 0)
-                  { 
-                     install_one(el, from_name, at, newexp, at);
+                  {
+                     install_one(el, from_name, at, newexp, at, last);
 
                     node->moved = 1;
                     seqedit_move++;
@@ -1409,7 +1425,7 @@ seq_move_expression(struct in_cmd* cmd)
 
             }
             if(from_name==NULL) newexp = clone_expression(command_par_expr("to", cmd->clone));
-            
+
             from_name = NULL;
             at = to + from;
           }
@@ -1421,17 +1437,17 @@ seq_move_expression(struct in_cmd* cmd)
             tmp = clone_expression(node->at_expr);
             expr = clone_expression(command_par_expr("by", cmd->clone));
             if(expr==NULL)
-            { 
+            {
 
               char *result = malloc(max_c * sizeof(char));
               sprintf(result, "%.16f", by);
               expr = new_expression(result,NULL);
               free(result);
-              
+
             }
             if(tmp==NULL)
-            { 
-              
+            {
+
               char *result = malloc(max_c * sizeof(char));
               sprintf(result, "%.16f", node->at_value);
               tmp = new_expression(result,NULL);
@@ -1443,7 +1459,7 @@ seq_move_expression(struct in_cmd* cmd)
           el = node->p_elem;
           if (remove_one(node) > 0)
           {
-            install_one(el, from_name, at, newexp, at);
+            install_one(el, from_name, at, newexp, at, last);
             seqedit_move++;
           }
         }
@@ -1595,16 +1611,16 @@ seq_replace(struct in_cmd* cmd)
     c_node = edit_sequ->start;
     while (c_node != NULL) {
       if (any || name_list_pos(c_node->name, selected_ranges->list) > -1) {
-	name = NULL;
-	for (k = 0; k < seqedit_select->curr; k++) {
-	  if (c_node->p_elem != NULL) name = c_node->p_elem->name;
-	  if (name != NULL && strchr(name, '$') == NULL &&
-	      pass_select_el(c_node->p_elem, seqedit_select->commands[k]) ) break;
-	}
-	if (k < seqedit_select->curr) {
-	  rep_els[rep_cnt] = el;
-	  rep_nodes[rep_cnt++] = c_node;
-	}
+        name = NULL;
+        for (k = 0; k < seqedit_select->curr; k++) {
+          if (c_node->p_elem != NULL) name = c_node->p_elem->name;
+          if (name != NULL && strchr(name, '$') == NULL &&
+              pass_select_el(c_node->p_elem, seqedit_select->commands[k]) ) break;
+        }
+        if (k < seqedit_select->curr) {
+          rep_els[rep_cnt] = el;
+          rep_nodes[rep_cnt++] = c_node;
+        }
       }
       if (c_node == edit_sequ->end) break;
       c_node = c_node->next;
@@ -1622,11 +1638,11 @@ seq_replace(struct in_cmd* cmd)
       node = edit_sequ->nodes->nodes[pos];
       name = command_par_string_user("by", cmd->clone);
       if (name) {
-	if ((el = find_element(name, element_list)) != NULL) {
-	  rep_els[rep_cnt] = el;
-	  rep_nodes[rep_cnt++] = node;
-	}
-	else warning("ignoring unknown 'by' element: ",name);
+        if ((el = find_element(name, element_list)) != NULL) {
+          rep_els[rep_cnt] = el;
+          rep_nodes[rep_cnt++] = node;
+        }
+        else warning("ignoring unknown 'by' element: ",name);
       }
       else warning("'by' missing, ","ignored");
     }
@@ -1677,7 +1693,7 @@ add_drifts(struct node* c_node, struct node* end,struct sequence* sequ)
 
   int debug;
   debug = get_option("debug");
-  double sequencelength = sequence_length(sequ); 
+  double sequencelength = sequence_length(sequ);
   if (!c_node) return 0;
 
   for (cnt=1; c_node != end && c_node->next; c_node = c_node->next, cnt++) {
@@ -1685,7 +1701,7 @@ add_drifts(struct node* c_node, struct node* end,struct sequence* sequ)
     double drift_end = c_node->next->position - c_node->next->length / 2;
     double drift_len = drift_end-drift_beg;
 
-    if(fabs((drift_len) + sequencelength) < tol){ //If the drift is exactly -length of the accelerator -> do nothing. 
+    if(fabs((drift_len) + sequencelength) < tol){ //If the drift is exactly -length of the accelerator -> do nothing.
       (void)0;
     }
     else if (drift_len < -tol) {
@@ -1693,10 +1709,10 @@ add_drifts(struct node* c_node, struct node* end,struct sequence* sequ)
       sprintf(buf, " %s and %s, length %e", c_node->name, c_node->next->name, drift_len);
 
       if (debug) {
-	printf("\ncurrent node name %s position: %e length %e \n",
-	       c_node->name, c_node->position, c_node->length);
-	printf("next    node name %s position: %e length %e \n\n",
-	       c_node->next->name, c_node->next->position, c_node->next->length);
+        printf("\ncurrent node name %s position: %e length %e \n",
+               c_node->name, c_node->position, c_node->length);
+        printf("next    node name %s position: %e length %e \n\n",
+               c_node->next->name, c_node->next->position, c_node->next->length);
       }
 
      fatal_error("negative drift between elements", buf);
@@ -1708,7 +1724,7 @@ add_drifts(struct node* c_node, struct node* end,struct sequence* sequ)
       link_in_front(drift_node, c_node->next);
       drift_node->position = drift_beg + drift_len / 2;
       if (debug) printf("inserting a drift of length %e at position %e \n \n",
-			drift_len,drift_beg + drift_len / 2);
+                        drift_len,drift_beg + drift_len / 2);
       c_node = c_node->next;    // avoid double counting implicit drifts
       cnt++;
     }
@@ -1767,7 +1783,7 @@ use_sequ(struct in_cmd* cmd)
          pro_use_survey();
          if (par_present("survtest", cmd->clone)) survtest_();
          exec_delete_table("survey");
-     	}
+        }
     }
     else warning("unknown sequence skipped:", name);
   }
@@ -1936,11 +1952,11 @@ enter_sequence(struct in_cmd* cmd)
   else if (strcmp(toks[aux_pos+2], "sequence") == 0) {
     for (i = aux_pos+3; i < cmd->tok_list->curr; i++) {
       if (strcmp(toks[i], "refer") == 0) {
-	if (i+2 < cmd->tok_list->curr) {
-	  if      (strcmp(toks[i+2], "entry") == 0)  k = 1;
-	  else if (strcmp(toks[i+2], "exit")  == 0)  k = -1;
-	}
-	break;
+        if (i+2 < cmd->tok_list->curr) {
+          if      (strcmp(toks[i+2], "entry") == 0)  k = 1;
+          else if (strcmp(toks[i+2], "exit")  == 0)  k = -1;
+        }
+        break;
       }
     }
 
@@ -2081,7 +2097,7 @@ exec_save(struct in_cmd* cmd)
       store_orbit_correctors();
     }
   }
-  
+
   //store_orbit_correctors();
 
   filename = command_par_string_user("file", cmd->clone);
@@ -2154,7 +2170,7 @@ exec_save(struct in_cmd* cmd)
     while (c_node != NULL) {
       if ((el = c_node->p_elem) != NULL && strchr(el->name, '$') == NULL
           && strcmp(el->base_type->name, "drift") != 0) {
-         
+
 
         while (el->base_type != el) {
           add_to_el_list(&el, 0, ell, 0);
@@ -2331,7 +2347,7 @@ expand_curr_sequ(int flag)
 
 int get_nnodes(void){
   return current_sequ->n_nodes;
-} 
+}
 
 void
 reset_errors(struct sequence* sequ)
diff --git a/tests/test-sequence-10/ssfirst.cfg b/tests/test-sequence-10/ssfirst.cfg
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/test-sequence-10/ssfirst.ref b/tests/test-sequence-10/ssfirst.ref
new file mode 100644
index 000000000..e8feaa60b
--- /dev/null
+++ b/tests/test-sequence-10/ssfirst.ref
@@ -0,0 +1,29 @@
+none = 0;
+n3: marker;
+n2: marker;
+m1: marker;
+m2: marker;
+m3: marker;
+m4: marker;
+n5: marker;
+m5: marker;
+m6: marker;
+m7: marker;
+n9: marker;
+m8: marker;
+m9: marker;
+ssfirst: sequence, l = 10;
+n3, at = 0;
+n2, at = 0;
+m1: marker, at = 0;
+m2: marker, at = 0;
+m3: marker, at = 1;
+m4: marker, at = 1;
+n5, at = 2;
+m5: marker, at = 2;
+m6: marker, at = 3;
+m7: marker, at = 3;
+n9, at = 4;
+m8: marker, at = 4;
+m9: marker, at = 4;
+endsequence;
diff --git a/tests/test-sequence-10/sslast.cfg b/tests/test-sequence-10/sslast.cfg
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/test-sequence-10/sslast.ref b/tests/test-sequence-10/sslast.ref
new file mode 100644
index 000000000..8c11e88a0
--- /dev/null
+++ b/tests/test-sequence-10/sslast.ref
@@ -0,0 +1,29 @@
+none = 0;
+m1: marker;
+m2: marker;
+n2: marker;
+n3: marker;
+m3: marker;
+m4: marker;
+m5: marker;
+n5: marker;
+m6: marker;
+m7: marker;
+m8: marker;
+m9: marker;
+n9: marker;
+sslast: sequence, l = 10;
+m1: marker, at = 0;
+m2: marker, at = 0;
+n2, at = 0;
+n3, at = 0;
+m3: marker, at = 1;
+m4: marker, at = 1;
+m5: marker, at = 2;
+n5, at = 2;
+m6: marker, at = 3;
+m7: marker, at = 3;
+m8: marker, at = 4;
+m9: marker, at = 4;
+n9, at = 4;
+endsequence;
diff --git a/tests/test-sequence-10/test-sequence-10.cfg b/tests/test-sequence-10/test-sequence-10.cfg
new file mode 100644
index 000000000..fc33ceff1
--- /dev/null
+++ b/tests/test-sequence-10/test-sequence-10.cfg
@@ -0,0 +1 @@
+1-7      *     skip         # head
diff --git a/tests/test-sequence-10/test-sequence-10.madx b/tests/test-sequence-10/test-sequence-10.madx
new file mode 100644
index 000000000..76d0c737b
--- /dev/null
+++ b/tests/test-sequence-10/test-sequence-10.madx
@@ -0,0 +1,57 @@
+sslast: sequence, l=10;
+m1: marker, at=0;
+m2: marker, at=0;
+m3: marker, at=1;
+m4: marker, at=1;
+m5: marker, at=2;
+m6: marker, at=3;
+m7: marker, at=3;
+m8: marker, at=4;
+m9: marker, at=4;
+endsequence;
+
+n2: marker;
+n3: marker;
+n5: marker;
+n9: marker;
+
+
+seqedit,sequence=sslast;
+install,element=n2,at=0,last=true;
+install,element=n3,at=0,last=true;
+install,element=n5,at=2,last=true;
+install,element=n9,at=4,last=true;
+endedit;
+
+save,sequence=sslast,file=sslast;
+
+
+
+ssfirst: sequence, l=10;
+m1: marker, at=0;
+m2: marker, at=0;
+m3: marker, at=1;
+m4: marker, at=1;
+m5: marker, at=2;
+m6: marker, at=3;
+m7: marker, at=3;
+m8: marker, at=4;
+m9: marker, at=4;
+endsequence;
+
+n2: marker;
+n3: marker;
+n5: marker;
+n9: marker;
+
+
+seqedit,sequence=ssfirst;
+install,element=n2,at=0,last=false;
+install,element=n3,at=0,last=false;
+install,element=n5,at=2,last=false;
+install,element=n9,at=4,last=false;
+endedit;
+
+save,sequence=ssfirst,file=ssfirst;
+
+
diff --git a/tests/test-sequence-10/test-sequence-10.ref b/tests/test-sequence-10/test-sequence-10.ref
new file mode 100644
index 000000000..7504070ca
--- /dev/null
+++ b/tests/test-sequence-10/test-sequence-10.ref
@@ -0,0 +1,151 @@
+
+  ++++++++++++++++++++++++++++++++++++++++++++
+  +     MAD-X 5.08.01  (64 bit, Linux)       +
+  + Support: mad@cern.ch, http://cern.ch/mad +
+  + Release   date: 2022.02.25               +
+  + Execution date: 2022.05.24 13:42:26      +
+  ++++++++++++++++++++++++++++++++++++++++++++
+sslast: sequence, l=10;
+
+m1: marker, at=0;
+
+m2: marker, at=0;
+
+m3: marker, at=1;
+
+m4: marker, at=1;
+
+m5: marker, at=2;
+
+m6: marker, at=3;
+
+m7: marker, at=3;
+
+m8: marker, at=4;
+
+m9: marker, at=4;
+
+endsequence;
+
+
+
+n2: marker;
+
+n3: marker;
+
+n5: marker;
+
+n9: marker;
+
+
+
+
+
+seqedit,sequence=sslast;
+
+install,element=n2,at=0,last=true;
+
+install,element=n3,at=0,last=true;
+
+install,element=n5,at=2,last=true;
+
+install,element=n9,at=4,last=true;
+
+endedit;
+
+++++++ info: seqedit - number of elements installed:  4
+++++++ info: seqedit - number of elements moved:      0
+++++++ info: seqedit - number of elements removed:    0
+++++++ info: seqedit - number of elements replaced:   0
+
+
+save,sequence=sslast,file=sslast;
+
+++++++ warning: SAVE makes all previous USE invalid !  
+
+
+
+
+
+
+ssfirst: sequence, l=10;
+
+m1: marker, at=0;
+
+++++++ warning: implicit element re-definition ignored: m1
+m2: marker, at=0;
+
+++++++ warning: implicit element re-definition ignored: m2
+m3: marker, at=1;
+
+++++++ warning: implicit element re-definition ignored: m3
+m4: marker, at=1;
+
+++++++ warning: implicit element re-definition ignored: m4
+m5: marker, at=2;
+
+++++++ warning: implicit element re-definition ignored: m5
+m6: marker, at=3;
+
+++++++ warning: implicit element re-definition ignored: m6
+m7: marker, at=3;
+
+++++++ warning: implicit element re-definition ignored: m7
+m8: marker, at=4;
+
+++++++ warning: implicit element re-definition ignored: m8
+m9: marker, at=4;
+
+++++++ warning: implicit element re-definition ignored: m9
+endsequence;
+
+
+
+n2: marker;
+
+++++++ info: element redefined: n2
+n3: marker;
+
+++++++ info: element redefined: n3
+n5: marker;
+
+++++++ info: element redefined: n5
+n9: marker;
+
+++++++ info: element redefined: n9
+
+
+
+
+seqedit,sequence=ssfirst;
+
+install,element=n2,at=0,last=false;
+
+install,element=n3,at=0,last=false;
+
+install,element=n5,at=2,last=false;
+
+install,element=n9,at=4,last=false;
+
+endedit;
+
+++++++ info: seqedit - number of elements installed:  4
+++++++ info: seqedit - number of elements moved:      0
+++++++ info: seqedit - number of elements removed:    0
+++++++ info: seqedit - number of elements replaced:   0
+
+
+save,sequence=ssfirst,file=ssfirst;
+
+++++++ warning: SAVE makes all previous USE invalid !  
+
+
+
+
+
+  Number of warnings: 11
+11 in C and 0 in Fortran
+
+  ++++++++++++++++++++++++++++++++++++++++++++
+  +          MAD-X finished normally         +
+  ++++++++++++++++++++++++++++++++++++++++++++

From 38954bd8d172051fbbcd7a0e34befeef2751b0c9 Mon Sep 17 00:00:00 2001
From: Riccardo De Maria <riccardodemaria@gmail.com>
Date: Tue, 24 May 2022 14:30:08 +0200
Subject: [PATCH 2/4] adding LAST in manual

---
 doc/latexuguide/seqedit.tex | 230 ++++++++++++++++++------------------
 1 file changed, 118 insertions(+), 112 deletions(-)

diff --git a/doc/latexuguide/seqedit.tex b/doc/latexuguide/seqedit.tex
index 929a0e9df..05237f680 100644
--- a/doc/latexuguide/seqedit.tex
+++ b/doc/latexuguide/seqedit.tex
@@ -1,24 +1,24 @@
 %%%\title{Sequence Editor}
-%  Changed by: Chris ISELIN, 24-Feb-1998 
-%  Changed by: Hans Grote, 17-Jun-2002 
+%  Changed by: Chris ISELIN, 24-Feb-1998
+%  Changed by: Hans Grote, 17-Jun-2002
 
 \chapter{Sequence Editor}
 \label{chap:seqedit}
 With the help of a few commands, an existing sequence may be
-modified in many ways: in the case of a circular machine, the starting point of 
+modified in many ways: in the case of a circular machine, the starting point of
 the sequence can be moved to another place;
 the order of elements can be inverted; elements can be inserted one by
 one, or as a whole group with one single command; single elements, or
 classes thereof can be removed; elements can be replaced by others;
 finally, the sequence can be "flattened", i.e. all inserted sequences
 are replaced by their actual elements, such that a flattened sequence
-contains only elements. 
+contains only elements.
 
 It is good practice to add a \hyperref[sec:flatten]{\texttt{FLATTEN}}
 statement at the end of a \texttt{SEQEDIT} operation to ensure a fully
-operational sequence. This is particularly useful for the 
+operational sequence. This is particularly useful for the
 \hyperref[sec:save]{\texttt{SAVE}} command to properly save
-\textit{shared sequences} and to write them out in \madeight format. 
+\textit{shared sequences} and to write them out in \madeight format.
 
 
 %% 2013-Jul-11  17:35:46  ghislain: need a synopsis paragraph similar to
@@ -27,36 +27,36 @@ \chapter{Sequence Editor}
 
 \section{SEQEDIT}
 \label{sec:seqedit}
-\madx provides an environment for the edition of sequences that is invoked with 
+\madx provides an environment for the edition of sequences that is invoked with
 the command:
 \madbox{SEQEDIT, SEQUENCE=string;}
-The only attribute is the name of the sequence to be edited. 
+The only attribute is the name of the sequence to be edited.
 
-The editing is performed on the sequence as provided by the user and before it 
-is expanded with the \hyperref[sec:use]{\texttt{USE}} command. 
-At the end of sequence edition, the resulting sequence must be expanded through 
+The editing is performed on the sequence as provided by the user and before it
+is expanded with the \hyperref[sec:use]{\texttt{USE}} command.
+At the end of sequence edition, the resulting sequence must be expanded through
 the \hyperref[sec:use]{\texttt{USE}} command as necessary.
 
 \section{FLATTEN}
 \label{sec:flatten}
-Sequences can be built from elements but also sub-sequences resulting in a 
-nested structure (see chapter \ref{chap:sequence} on sequence definition). 
-The positioning of elements within a sequence can also be specified with values 
+Sequences can be built from elements but also sub-sequences resulting in a
+nested structure (see chapter \ref{chap:sequence} on sequence definition).
+The positioning of elements within a sequence can also be specified with values
 or expressions, and by reference to other elements.
 
-\madx provides a command to resolve these dependencies and transform a complex 
-sequence into a simple list of elements with positioning values referring to 
-the start of the sequence, discarding the user-specified expressions for the 
+\madx provides a command to resolve these dependencies and transform a complex
+sequence into a simple list of elements with positioning values referring to
+the start of the sequence, discarding the user-specified expressions for the
 positioning.
 
-This command takes no argument: 
+This command takes no argument:
 \madbox{
 FLATTEN;
 }
 
 If the sequence being edited contains sub-sequences, \texttt{FLATTEN}
 recursively includes all sub-sequences until the sequence is only
-composed of a simple list of elements. 
+composed of a simple list of elements.
 
 \texttt{FLATTEN} also resolves the positioning of each element within
 the sequence to a single value with reference to the start of the
@@ -67,9 +67,9 @@ \section{FLATTEN}
 edition as well as at the very end as in
 \madxmp{
 SEQEDIT, \=SEQUENCE=name; \\
-	 \>FLATTEN; \\
-	 \>\ldots commands to edit the named sequence\ldots \\
-	 \>FLATTEN; \\
+         \>FLATTEN; \\
+         \>\ldots commands to edit the named sequence\ldots \\
+         \>FLATTEN; \\
 ENDEDIT;
 }
 
@@ -80,33 +80,33 @@ \section{CYCLE}
 }
 This makes the sequence start at the location given as attribute value
 of the \texttt{START} attribute. The element named by the \texttt{START}
-attribute must be a marker. \\  
+attribute must be a marker. \\
 In case there is a shared sequence in the used sequence, the
 command \texttt{FLATTEN} should be used before the command
-\texttt{CYCLE}. \\ 
-Example:  
+\texttt{CYCLE}. \\
+Example:
 \madxmp{
 FLATTEN; \\
-CYCLE, START=place; 
+CYCLE, START=place;
 }
 
 Note that the \texttt{FLATTEN} command inserts another marker before the
 start location, with a name composed of the name of the sequence being
-edited, followed by the start location name and the string "\_P\_". 
+edited, followed by the start location name and the string "\_P\_".
 
 \section{REFLECT}
 \label{sec:reflect}
 \madbox{REFLECT;}
 This inverts the order of element in the sequence, starting from the
-last element. \\ 
+last element. \\
 If there are shared sequences inside the
-\hyperref[sec:use]{\texttt{USE}}d sequence,  
+\hyperref[sec:use]{\texttt{USE}}d sequence,
 the command \texttt{FLATTEN} must be used before the command
-\texttt{REFLECT}.   
-Alternatively each shared sequence must first be reflected. Example:   
+\texttt{REFLECT}.
+Alternatively each shared sequence must first be reflected. Example:
 \madxmp{
 FLATTEN;\\
-REFLECT; 
+REFLECT;
 }
 
 
@@ -114,25 +114,29 @@ \section{INSTALL}
 \label{sec:install}
 \madbox{
   INSTALL, \= ELEMENT=string, CLASS=string, \\
-           \> AT=real, FROM=\{string|SELECTED\};
+           \> AT=real, FROM=\{string|SELECTED\}, LAST=\{true|false\};
 }
-where the parameters have the following meaning: 
+where the parameters have the following meaning:
 \begin{madlist}
-   \ttitem{ELEMENT} name of the element to be inserted (mandatory) 
+   \ttitem{ELEMENT} name of the element to be inserted (mandatory)
 
-   \ttitem{CLASS} class of the new element to be inserted. 
+   \ttitem{CLASS} class of the new element to be inserted.
 
    \ttitem{AT} position where the element is to be inserted; if no "from"
      is given,this is relative to the start of the sequence. If "from"
-     is given, it is relative to the position specified there. 
+     is given, it is relative to the position specified there.
 
    \ttitem{FROM} either a place (i.e. the name(+occurrence count) of an
      element already existing in the sequence, e.g. mb[15], or
      mq.a..i1..4 etc.; or the string \texttt{SELECTED}; in the latter
      case an element of the type specified will be inserted behind all
      elements in the sequence that are currently selected by one or several
-     \hyperref[sec:select]{\texttt{SELECT}} commands of the type 
+     \hyperref[sec:select]{\texttt{SELECT}} commands of the type
      \madxmp{SELECT, FLAG=seqedit, CLASS=.., PATTERN=.., RANGE=..;}
+
+   \ttitem{LAST} if there are one or more elements at the same location the new element
+    will be placed after the last element unless LAST is FALSE.
+
 \end{madlist}
 
 \textbf{Note:} No element definition can occur inside a \texttt{SEQEDIT
@@ -142,21 +146,23 @@ \section{INSTALL}
 \section{MOVE}
 \label{sec:move}
 \madbox{
-MOVE, ELEMENT=\{string|SELECTED\}, BY=real, TO=real, FROM=string;
+MOVE, ELEMENT=\{string|SELECTED\}, BY=real, TO=real, FROM=string, LAST=\{true|false\};
 }
 \begin{madlist}
   \ttitem{ELEMENT} name of the existing element to be moved, or
   "SELECTED", in which case all elements from existing
   \hyperref[sec:select]{\texttt{SELECT}} commands will be moved;
-  in the latter case, the \texttt{BY} attribute must be given.  
+  in the latter case, the \texttt{BY} attribute must be given.
   \ttitem{BY} distance by which the element(s) is/are to be moved; no
-  \texttt{TO} or \texttt{FROM} attributes should be given in this case.  
+  \texttt{TO} or \texttt{FROM} attributes should be given in this case.
   \ttitem{TO} position to which the element has to be moved; if no
   \texttt{FROM} attribute is given, the position is relative to the
   start of the sequence; otherwise, it is relative to the location
-  given in the \texttt{FROM} argument   
+  given in the \texttt{FROM} argument
   \ttitem{FROM} place in the sequence with respect to which the element
-  is to be positioned.  
+  is to be positioned.
+  \ttitem{LAST} if there are one or more elements at the same location the new element
+   will be placed after the last element unless LAST is FALSE.
 \end{madlist}
 
 \section{REMOVE}
@@ -170,9 +176,9 @@ \section{REMOVE}
   previously selected by \hyperref[sec:select]{\texttt{SELECT}} commands
 \end{madlist}
 
-\textbf{Note:} \madx expects to find some special markers in a beam line and it  
-is therefore dangerous to remove all markers from a sequence! In particular the 
-\texttt{START=...} marker and markers added by a \hyperref[sec:cycle]{\texttt{CYCLE}} 
+\textbf{Note:} \madx expects to find some special markers in a beam line and it
+is therefore dangerous to remove all markers from a sequence! In particular the
+\texttt{START=...} marker and markers added by a \hyperref[sec:cycle]{\texttt{CYCLE}}
 command must never be removed from a sequence.
 
 
@@ -185,16 +191,16 @@ \section{REPLACE}
 The parameters are defined as:
 \begin{madlist}
   \ttitem{ELEMENT} names the elements to be replaced. \\
-  The special case \texttt{ELEMENT = SELECTED} replaces all elements previously 
-  selected by \hyperref[sec:select]{\texttt{SELECT}} commands 
-  
-  \ttitem{BY} names the elements replacing the elements selected for 
+  The special case \texttt{ELEMENT = SELECTED} replaces all elements previously
+  selected by \hyperref[sec:select]{\texttt{SELECT}} commands
+
+  \ttitem{BY} names the elements replacing the elements selected for
   replacement.
 \end{madlist}
 
 \section{EXTRACT}
 \label{sec:extract}
-A new sequence can be extracted as a subset of an existing sequence. The 
+A new sequence can be extracted as a subset of an existing sequence. The
 extracted sequence is given a new name and can be
 \hyperref[sec:use]{\texttt{USE}}d as any user defined sequence.
 \madbox{
@@ -204,16 +210,16 @@ \section{EXTRACT}
 
 The parameters are defined as:
 \begin{madlist}
-\ttitem{SEQUENCE} the name of the existing sequence from which the new sequence 
+\ttitem{SEQUENCE} the name of the existing sequence from which the new sequence
 is extracted.
 
-\ttitem{FROM} the name of an element in the sequence that becomes the first 
+\ttitem{FROM} the name of an element in the sequence that becomes the first
 element of the extracted sequence.
 
-\ttitem{TO} the name of an element in the sequence that becomes the last 
-element of the extracted sequence. 
+\ttitem{TO} the name of an element in the sequence that becomes the last
+element of the extracted sequence.
 
-\ttitem{NEWNAME} the name of the extracted sequence. 
+\ttitem{NEWNAME} the name of the extracted sequence.
 \end{madlist}
 
 
@@ -222,18 +228,18 @@ \section{EXTRACT}
 
 \textbf{Note:} the element given by the \texttt{FROM} attribute must be
 located, in the existing sequence, before the element given by the
-\texttt{TO} attribute, or \madx fails with a fatal error. 
-In the case of circular sequences, this can be ensured by performing a 
+\texttt{TO} attribute, or \madx fails with a fatal error.
+In the case of circular sequences, this can be ensured by performing a
 \hyperref[sec:cycle]{\texttt{CYCLE}} of the original sequence with
 \texttt{START} pointing to the same element given in the \texttt{FROM}
-attribute of the \texttt{EXTRACT} command. 
+attribute of the \texttt{EXTRACT} command.
 
 
 \section{ENDEDIT}
 \label{sec:endedit}
 The sequence editing environment is closed with the command
 \madbox{ENDEDIT;}
-The nodes in the sequence are finally renumbered according to their occurrence 
+The nodes in the sequence are finally renumbered according to their occurrence
 which might have changed during editing.
 
 
@@ -242,7 +248,7 @@ \section{ENDEDIT}
 \section{SAVE}
 \label{sec:save}
 
-The \texttt{SAVE} command saves a sequence to a specified file together with all 
+The \texttt{SAVE} command saves a sequence to a specified file together with all
 relevant information.
 
 \madbox{
@@ -251,40 +257,40 @@ \section{SAVE}
       \>NOEXPR=logical, NEWNAME=string;
 }
 
-The parameters are defined as: 
+The parameters are defined as:
 \begin{madlist}
-	\ttitem{SEQUENCE} lists the sequences to be saved, separated by commas. 
-	This attribute is optional and when omitted, all known 
-	sequences are saved. \\
-	However, because of internal inconsistencies that can result in spurious 
-	entries in the output file, the user is strongly advised to always provide 
-	explicitly the names of sequences to be saved.
-
-	\ttitem{FILE} the filename of the output file. (Default: "save")
-
-	\ttitem{BEAM} an optional flag to specify that all beams linked to the
-	specified sequences are saved at the top of the output file.
-
-	\ttitem{BARE} an optional flag to save only the sequence without the
-	element definitions nor beam information. This allows to re-read in a
-	sequence with might otherwise create a stop of the program. This is
-	particularly useful to turn a line into a sequence in order to further edit 
-	it with \hyperref[sec:seqedit]{\texttt{SEQEDIT}}.
-
-	\ttitem{MAD8} an optional flag to request that the sequences should be  
-	saved using \madeight input format.
-
-	\ttitem{NOEXPR} an optional flag to save values of expressions 
-	instead of the expressions themselves: the expressions in commands 
-	and variables are expanded and evaluated before saving.
-	This option must be used with care because the exported values were not deeply
-	checked and the code that writes variables and commands is widely spread
-	in the internal structure. \\
-	This option does not apply only for the saving of sequences in \madeight format. 
-
-	\ttitem {NEWNAME} provides a name for the saved sequence, overriding the 
-	original name. (see \hyperref[sec:extract]{\texttt{EXTRACT}} above)
-  
+        \ttitem{SEQUENCE} lists the sequences to be saved, separated by commas.
+        This attribute is optional and when omitted, all known
+        sequences are saved. \\
+        However, because of internal inconsistencies that can result in spurious
+        entries in the output file, the user is strongly advised to always provide
+        explicitly the names of sequences to be saved.
+
+        \ttitem{FILE} the filename of the output file. (Default: "save")
+
+        \ttitem{BEAM} an optional flag to specify that all beams linked to the
+        specified sequences are saved at the top of the output file.
+
+        \ttitem{BARE} an optional flag to save only the sequence without the
+        element definitions nor beam information. This allows to re-read in a
+        sequence with might otherwise create a stop of the program. This is
+        particularly useful to turn a line into a sequence in order to further edit
+        it with \hyperref[sec:seqedit]{\texttt{SEQEDIT}}.
+
+        \ttitem{MAD8} an optional flag to request that the sequences should be
+        saved using \madeight input format.
+
+        \ttitem{NOEXPR} an optional flag to save values of expressions
+        instead of the expressions themselves: the expressions in commands
+        and variables are expanded and evaluated before saving.
+        This option must be used with care because the exported values were not deeply
+        checked and the code that writes variables and commands is widely spread
+        in the internal structure. \\
+        This option does not apply only for the saving of sequences in \madeight format.
+
+        \ttitem {NEWNAME} provides a name for the saved sequence, overriding the
+        original name. (see \hyperref[sec:extract]{\texttt{EXTRACT}} above)
+
   \ttitem{CSAVE} an option that saves the strength of the corrector magnets used
   for an orbit correction.
 \end{madlist}
@@ -292,28 +298,28 @@ \section{SAVE}
 Any number of \texttt{SELECT, FLAG=save, ...} commands may precede
 the \texttt{SAVE} command. In that case, the names of elements, variables, and
 sequences must match the pattern(s) if given, and in addition the
-elements must be of the class(es) specified. 
+elements must be of the class(es) specified.
 
 %% See here for a
 %% \href{../Introduction/select.html#save_select}{SAVE with SELECT}
-%% example.  
+%% example.
 
 The precision of the output of the \texttt{SAVE} command depends on the
-defined output precision for \madx, which can be adjusted with the 
+defined output precision for \madx, which can be adjusted with the
 \hyperref[sec:set]{\texttt{SET, FORMAT...}} command.
 
 %Details about default
 %precision and how to adjust it can be found at the
-%\href{../Introduction/set.html#Format}{SET Format} instruction page.   
- 
-Note that with \texttt{BARE=false} the saved sequence may contain redundant 
+%\href{../Introduction/set.html#Format}{SET Format} instruction page.
+
+Note that with \texttt{BARE=false} the saved sequence may contain redundant
 efinitions of elements, \textsl{i.e.} the same element is defined in the
 declaration  of elements in the form \texttt{label:\ type...} and in the
 sequence itself in the form \texttt{label:\ type, at=...}. This is
 flagged by \madx as implicit element redefinition and is ignored but a
-warning is issued.  
+warning is issued.
 
-Example:  
+Example:
 \begin{verbatim}
 tl3: LINE = ( ldl6, qtl301, mqn, qtl301, ldl7, qtl302,
                             mqn, qtl302, ldl8, ison);
@@ -350,7 +356,7 @@ \section{DUMPSEQU}
 }
 This command is actually more of a debug statement, but it may come handy at certain
 occasions. The argument of the \texttt{SEQUENCE} attribute is the name of an
-already expanded (i.e. \hyperref[sec:use]{\texttt{USE}}d) sequence. The amount of 
+already expanded (i.e. \hyperref[sec:use]{\texttt{USE}}d) sequence. The amount of
 detail in the output is controlled by the \texttt{LEVEL} argument:
 \begin{itemize}
 \item[$=0$ : ]    print only the cumulative node length = sequence length
@@ -360,9 +366,9 @@ \section{DUMPSEQU}
 \end{itemize}
 
 \chapter{Save state}
-\label{chap:savestate}  
-It is sometimes convientine to save the state of a MAD-X script in order to reload it at a later occation or in order to distribute it to another users. 
-The \texttt{SAVE\_STATE} command provide the user with the possiblity to save a sequence, the beam information, the errors, and the macros in a single command. 
+\label{chap:savestate}
+It is sometimes convientine to save the state of a MAD-X script in order to reload it at a later occation or in order to distribute it to another users.
+The \texttt{SAVE\_STATE} command provide the user with the possiblity to save a sequence, the beam information, the errors, and the macros in a single command.
 A MAD-X file is also created in order to load the produced files. The files are saved in a separate folder and in hexadecimal format in order not to lose
 any information in the saving.
 
@@ -371,13 +377,13 @@ \chapter{Save state}
       \>BEAM=logical, FOLDER=foldername, csave=logical ;
 }
 
-The parameters are defined as: 
+The parameters are defined as:
 \begin{madlist}
-  \ttitem{SEQUENCE} lists the sequences to be saved, separated by commas. 
-  This attribute is optional and when omitted, all known 
+  \ttitem{SEQUENCE} lists the sequences to be saved, separated by commas.
+  This attribute is optional and when omitted, all known
   sequences are saved. \\
-  However, because of internal inconsistencies that can result in spurious 
-  entries in the output file, the user is strongly advised to always provide 
+  However, because of internal inconsistencies that can result in spurious
+  entries in the output file, the user is strongly advised to always provide
   explicitly the names of sequences to be saved.
 
   \ttitem{FILE} the starting of the filenames the output files will have. (Default: "save")
@@ -388,7 +394,7 @@ \chapter{Save state}
   \ttitem{FOLDER} the name of the folder where the files are saved (Default:"save\_state")
 
   \ttitem{CSAVE} an option that saves the strength of the corrector magnets used
-  for an orbit correction (Default=TRUE). 
+  for an orbit correction (Default=TRUE).
 
 \end{madlist}
 

From 045ab854fba901d6fdf325ea0999a8a2974e7e1a Mon Sep 17 00:00:00 2001
From: Riccardo De Maria <riccardodemaria@gmail.com>
Date: Tue, 24 May 2022 14:35:11 +0200
Subject: [PATCH 3/4] change test to reproduce old install behaviour

---
 tests/test-sequence-4/test-sequence-4.madx |   4 +-
 tests/test-sequence-4/test-sequence-4.ref  | 164 ++++++++++-----------
 tests/test-sequence-6/test-sequence-6.madx |   4 +-
 tests/test-sequence-6/test-sequence-6.ref  |   4 +-
 4 files changed, 88 insertions(+), 88 deletions(-)

diff --git a/tests/test-sequence-4/test-sequence-4.madx b/tests/test-sequence-4/test-sequence-4.madx
index 8cc188583..a0a88605c 100644
--- a/tests/test-sequence-4/test-sequence-4.madx
+++ b/tests/test-sequence-4/test-sequence-4.madx
@@ -40,8 +40,8 @@ TI2.END: marker;
 TI2.START: marker;
 
 Seqedit, sequence=TI2;
-   Install, element=ti2.start, at=0, from=TI2$START;
-   Install, element=ti2.end, at=0, from=TI2$END;
+   Install, element=ti2.start, at=0, from=TI2$START, last=false;
+   Install, element=ti2.end, at=0, from=TI2$END, last=false;
    Flatten;
 endedit;
 
diff --git a/tests/test-sequence-4/test-sequence-4.ref b/tests/test-sequence-4/test-sequence-4.ref
index 258608a75..1aa94f46d 100644
--- a/tests/test-sequence-4/test-sequence-4.ref
+++ b/tests/test-sequence-4/test-sequence-4.ref
@@ -5,169 +5,169 @@
   + Release   date: 2022.01.13               +
   + Execution date: 2022.01.27 20:52:35      +
   ++++++++++++++++++++++++++++++++++++++++++++
-
 
-BEAM, PARTICLE = proton, PC = 450;
 
-
+BEAM, PARTICLE = proton, PC = 450;
 
-option, -echo;
 
-
 
-QF.60010.E:MARKER;
+option, -echo;
 
-QDA.61910.S:MARKER;
 
-REFPOINT: MARKER;
 
-
+QF.60010.E:MARKER;
 
-SEQEDIT, SEQUENCE = SPS; 
+QDA.61910.S:MARKER;
 
-	INSTALL, ELEMENT = QF.60010.E,  AT = 5759.5865,      FROM = BEGI.10010;
+REFPOINT: MARKER;
 
-	INSTALL, ELEMENT = QDA.61910.S, AT = QDA.61910->L/2, FROM = QDA.61910;
 
-	INSTALL, ELEMENT = REFPOINT,    AT = qf.60010->L/2,  FROM = qf.60010;
 
-	FLATTEN; 
+SEQEDIT, SEQUENCE = SPS; 
 
-ENDEDIT;
+	INSTALL, ELEMENT = QF.60010.E,  AT = 5759.5865,      FROM = BEGI.10010;
+
+	INSTALL, ELEMENT = QDA.61910.S, AT = QDA.61910->L/2, FROM = QDA.61910;
+
+	INSTALL, ELEMENT = REFPOINT,    AT = qf.60010->L/2,  FROM = qf.60010;
+
+	FLATTEN; 
+
+ENDEDIT;
 
 ++++++ info: seqedit - number of elements installed:  3
 ++++++ info: seqedit - number of elements moved:      0
 ++++++ info: seqedit - number of elements removed:    0
 ++++++ info: seqedit - number of elements replaced:   0
-
 
-// ------------- extract LSS6 ---------------------
 
-
+// ------------- extract LSS6 ---------------------
+
+
 
-EXTRACT, SEQUENCE=SPS, FROM=QF.60010.E, TO=QDA.61910.S, NEWNAME=SPS6, REFPOS=REFPOINT; 
+EXTRACT, SEQUENCE=SPS, FROM=QF.60010.E, TO=QDA.61910.S, NEWNAME=SPS6, REFPOS=REFPOINT; 
 
 +++ extracting sequence sps from qf.60010.e:1 to qda.61910.s:1
 +++ new sequence: sps6  with current length = 611.3944
 
-
 
-sps6length = QDA.61910.S->at - QF.60010.E->at;
 
-VALUE, sps6length;
+sps6length = QDA.61910.S->at - QF.60010.E->at;
+
+VALUE, sps6length;
 
 sps6length         =           611.3944 ;
-
 
-refpointpos = REFPOINT->AT - QF.60010.E->AT;
 
-value, refpointpos;
+refpointpos = REFPOINT->AT - QF.60010.E->AT;
+
+value, refpointpos;
 
 refpointpos        =              3.085 ;
-
 
-// ------------- combine with TI 2 -----------------
 
-
+// ------------- combine with TI 2 -----------------
+
 
-option, -echo;
+
+option, -echo;
 
 ++++++ info: element redefined: btv
 ++++++ info: element redefined: vvfa
 ++++++ info: element redefined: vvsa
 ++++++ info: element redefined: vvsb
 ++++++ info: element redefined: mbb
-
 
-TI2.END: marker;
 
-TI2.START: marker;
+TI2.END: marker;
+
+TI2.START: marker;
 
-
 
-Seqedit, sequence=TI2;
 
-   Install, element=ti2.start, at=0, from=TI2$START;
+Seqedit, sequence=TI2;
 
-   Install, element=ti2.end, at=0, from=TI2$END;
+   Install, element=ti2.start, at=0, from=TI2$START, last=false;
 
-   Flatten;
+   Install, element=ti2.end, at=0, from=TI2$END,last=false;
 
-endedit;
+   Flatten;
+
+endedit;
 
 ++++++ info: seqedit - number of elements installed:  2
 ++++++ info: seqedit - number of elements moved:      0
 ++++++ info: seqedit - number of elements removed:    0
 ++++++ info: seqedit - number of elements replaced:   0
-
 
-ti2length = TI2.END->AT-TI2.START->at; // reference ti2length =  3188.384281;
 
-VALUE, ti2length;
+ti2length = TI2.END->AT-TI2.START->at; // reference ti2length =  3188.384281;
+
+VALUE, ti2length;
 
 ti2length          =        3188.384281 ;
-
 
-LFULL = ti2length + sps6length + 0.00457; //=  3188.384281 + 611.3944 + 0.00457     
 
-value, lfull;
+LFULL = ti2length + sps6length + 0.00457; //=  3188.384281 + 611.3944 + 0.00457     
+
+value, lfull;
 
 lfull              =        3799.783251 ;
-
 
-all: SEQUENCE, refer=entry,  L= LFULL; 
 
-     sps6,    at= refpointpos;
+all: SEQUENCE, refer=entry,  L= LFULL; 
+
+     sps6,    at= refpointpos;
+
+     ti2,     at= sps6length+0.00457;       
 
-     ti2,     at= sps6length+0.00457;       
+ENDSEQUENCE;
 
-ENDSEQUENCE;
 
-
 
-!all: SEQUENCE, refer=centre,  L= LFULL; ! should be identical
+!all: SEQUENCE, refer=centre,  L= LFULL; ! should be identical
 
-!     sps6,    at= refpointpos;
+!     sps6,    at= refpointpos;
 
-!     ti2,     at= sps6length+ti2length/2.+0.00457;       
+!     ti2,     at= sps6length+ti2length/2.+0.00457;       
 
-!ENDSEQUENCE;
+!ENDSEQUENCE;
 
-
 
-!all: SEQUENCE, refer=exit,  L= LFULL; ! should be identical
 
-!     sps6,    at= refpointpos;
+!all: SEQUENCE, refer=exit,  L= LFULL; ! should be identical
 
-!     ti2,     at= sps6length+ti2length+0.00457;       
+!     sps6,    at= refpointpos;
 
-!ENDSEQUENCE;
+!     ti2,     at= sps6length+ti2length+0.00457;       
 
-
+!ENDSEQUENCE;
 
-SEQEDIT, SEQUENCE=all;
 
-	FLATTEN; 
 
-ENDEDIT;
+SEQEDIT, SEQUENCE=all;
+
+	FLATTEN; 
+
+ENDEDIT;
 
 ++++++ info: seqedit - number of elements installed:  0
 ++++++ info: seqedit - number of elements moved:      0
 ++++++ info: seqedit - number of elements removed:    0
 ++++++ info: seqedit - number of elements replaced:   0
-
 
-! Now calculate the twiss functions at reference place in SPS
 
-USE,     SEQUENCE=sps; 
+! Now calculate the twiss functions at reference place in SPS
+
+USE,     SEQUENCE=sps; 
 
-SAVEBETA, LABEL = QF.60010.BETA, PLACE = QF.60010.E;
+SAVEBETA, LABEL = QF.60010.BETA, PLACE = QF.60010.E;
 
-SELECT, FLAG=TWISS, CLEAR;
+SELECT, FLAG=TWISS, CLEAR;
 
-SELECT, FLAG=TWISS, COLUMN=name,L,s,betx,bety,alfx,alfy,dx,dpx,dy,dpy,x,px,y,py,mux,muy;
+SELECT, FLAG=TWISS, COLUMN=name,L,s,betx,bety,alfx,alfy,dx,dpx,dy,dpy,x,px,y,py,mux,muy;
 
-TWISS, SAVE; 
+TWISS, SAVE; 
 
 enter Twiss module
   
@@ -199,17 +199,17 @@ orbit:   0.000000E+00  0.000000E+00  0.000000E+00  0.000000E+00  0.000000E+00  0
 
        dqmin_phase 
                  0 
-QF.60010.BETA->mux = 0.0;
+QF.60010.BETA->mux = 0.0;
 
-QF.60010.BETA->muy = 0.0;
+QF.60010.BETA->muy = 0.0;
 
-
 
-! Now calculate the twiss functions through extraction and TI2
 
-OPTION, DEBUG;
+! Now calculate the twiss functions through extraction and TI2
 
-USE,     SEQUENCE=all;
+OPTION, DEBUG;
+
+USE,     SEQUENCE=all;
 
    in get_node_pos: name: all$start, pos: 0.000000e+00, fact: 0.000000e+00, length: 0.000000e+00, from_name: (null)
 	 in get_node_pos: name: all$start, from: 0.000000e+00			  ---> final pos: 0.000000e+00 
@@ -2632,13 +2632,13 @@ inserting a drift of length 1.116000e+00 at position 3.798231e+03
  
 inserting a drift of length 9.940000e-01 at position 3.799286e+03 
  
-SURVEY, FILE="all_survey";
+SURVEY, FILE="all_survey";
 
-SELECT, FLAG=TWISS, CLEAR;
+SELECT, FLAG=TWISS, CLEAR;
 
-SELECT, FLAG=TWISS, COLUMN=name,L,s,betx,bety,alfx,alfy,dx,dpx,dy,dpy,x,px,y,py,mux,muy;
+SELECT, FLAG=TWISS, COLUMN=name,L,s,betx,bety,alfx,alfy,dx,dpx,dy,dpy,x,px,y,py,mux,muy;
 
-TWISS, beta0=QF.60010.BETA,SAVE; !, FILE="twiss.all.tfs";
+TWISS, beta0=QF.60010.BETA,SAVE; !, FILE="twiss.all.tfs";
 
 enter Twiss module
  Found 6 initial orbit vector values from twiss command. 
@@ -2692,9 +2692,9 @@ final orbit vector:    -6.835225E-06  2.632486E-07 -4.259852E-06 -3.205229E-08
 
        dqmin_phase 
      -0.1525114948 
-
 
-stop;
+
+stop;
 
 
   Number of warnings: 0
diff --git a/tests/test-sequence-6/test-sequence-6.madx b/tests/test-sequence-6/test-sequence-6.madx
index 25b87cf73..bf947a02b 100644
--- a/tests/test-sequence-6/test-sequence-6.madx
+++ b/tests/test-sequence-6/test-sequence-6.madx
@@ -22,9 +22,9 @@ Option, debug;
 
 SEQEDIT,SEQUENCE=PR.BHT000001;
  FLATTEN;
- REPLACE, element=PR.BHT000001.corr3, by=aa;       
+ REPLACE, element=PR.BHT000001.corr3, by=aa;
  REMOVE, element=PR.BHT000001.corr1;
- INSTALL, ELEMENT=aa, AT= 2.985726e-01, FROM=pr.bht000001$start;
+ INSTALL, ELEMENT=aa, AT= 2.985726e-01, FROM=pr.bht000001$start,last=false;
  FLATTEN;
 ENDEDIT;
 
diff --git a/tests/test-sequence-6/test-sequence-6.ref b/tests/test-sequence-6/test-sequence-6.ref
index 6213b43c4..cfe0f2270 100644
--- a/tests/test-sequence-6/test-sequence-6.ref
+++ b/tests/test-sequence-6/test-sequence-6.ref
@@ -134,11 +134,11 @@ SEQEDIT,SEQUENCE=PR.BHT000001;
 
 
 TOP Expand_sequence name pr.bht000001 with length 5.003185e+00, ref_flag 0
- REPLACE, element=PR.BHT000001.corr3, by=aa;       
+ REPLACE, element=PR.BHT000001.corr3, by=aa;
 
  REMOVE, element=PR.BHT000001.corr1;
 
- INSTALL, ELEMENT=aa, AT= 2.985726e-01, FROM=pr.bht000001$start;
+ INSTALL, ELEMENT=aa, AT= 2.985726e-01, FROM=pr.bht000001$start,last=false;
 
    in get_node_pos: name: pr.bht000001$start, pos: 0.000000e+00, fact: 0.000000e+00, length: 0.000000e+00, from_name: (null)
 	 in get_node_pos: name: pr.bht000001$start, from: 0.000000e+00			  ---> final pos: 0.000000e+00 

From 9b31e6ca746f8ea47968ab1f5c9de96b90980440 Mon Sep 17 00:00:00 2001
From: Riccardo De Maria <riccardodemaria@gmail.com>
Date: Tue, 24 May 2022 14:42:53 +0200
Subject: [PATCH 4/4] update changelog

---
 Changes.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Changes.md b/Changes.md
index 0076072a5..5500bd64d 100644
--- a/Changes.md
+++ b/Changes.md
@@ -3,6 +3,7 @@ MAD-X master
 *   [PR 1107](https://github.com/MethodicalAcceleratorDesign/MAD-X/pull/1107) Stabizes few tests due to compiler dependent numerical noise (R. De Maria)
 *   [PR 1095](https://github.com/MethodicalAcceleratorDesign/MAD-X/pull/1095) Implement more robust, optional, PTC DA map output (L. Deniau)
 *   [PR 1088](https://github.com/MethodicalAcceleratorDesign/MAD-X/pull/1088) Additional explanation bv flag (J. Dilly)
+*   [PR 1113](https://github.com/MethodicalAcceleratorDesign/MAD-X/pull/1113) Introduce LAST option in INSTALL and MOVE and change default behaviour [Breaking change!]
 
 MAD-X release 5.08.01 (2022.02.25)
 
