diff --git a/src/main/java/edu/mit/blocks/codeblocks/BlockGenus.java b/src/main/java/edu/mit/blocks/codeblocks/BlockGenus.java
index ad77269b5a5c23e90b6a2abf236424a5befee54b..04b4d79eae777616e56b11c59a02def94ffc603a 100644
--- a/src/main/java/edu/mit/blocks/codeblocks/BlockGenus.java
+++ b/src/main/java/edu/mit/blocks/codeblocks/BlockGenus.java
@@ -891,6 +891,13 @@ public class BlockGenus {
                                 && newGenus.sockets.get(1).getPositionType() == BlockConnector.PositionType.BOTTOM) {
                             newGenus.isInfix = true;
                         }
+                        //TODO: test -> 3 bottom connectors test - added by letsgoING
+                        else if (newGenus.sockets != null && newGenus.sockets.size() == 3
+                                && newGenus.sockets.get(0).getPositionType() == BlockConnector.PositionType.BOTTOM
+                                && newGenus.sockets.get(1).getPositionType() == BlockConnector.PositionType.BOTTOM
+                        	 	&& newGenus.sockets.get(2).getPositionType() == BlockConnector.PositionType.BOTTOM) {
+                            newGenus.isInfix = true;
+                        }
                     } else if (genusChild.getNodeName().equals("Images")) {
                         /// LOAD BLOCK IMAGES ///
                         loadBlockImages(genusChild.getChildNodes(), newGenus);
diff --git a/src/main/java/edu/mit/blocks/codeblocks/InfixBlockShape.java b/src/main/java/edu/mit/blocks/codeblocks/InfixBlockShape.java
index a849561a97b37ff5fc1d00212d3e546208499d08..adc4d3cb229ecaa0eea9ab5aff6f652c4f282444 100644
--- a/src/main/java/edu/mit/blocks/codeblocks/InfixBlockShape.java
+++ b/src/main/java/edu/mit/blocks/codeblocks/InfixBlockShape.java
@@ -43,13 +43,19 @@ public class InfixBlockShape extends BlockShape {
         //curve down and right
         BlockShapeUtil.cornerTo(gpBottom, botLeftCorner, botRightCorner, blockCornerRadius);
 
-
+        //added by letsgoING for new setVariableBlock test
+        if (block.hasAfterConnector() && !rb.isCollapsed()) {
+            //control connector if necessary
+            // Trying left-aligned ports
+            Point2D p = BCS.addControlConnectorShape(gpBottom, (float) COMMAND_PORT_OFFSET + blockCornerRadius, true);
+            rb.updateSocketPoint(block.getAfterConnector(), p);
+        }
 
         /// BOTTOM SOCKETS
         //for each socket in the iterator
         int socketCounter = 0; //need to use this to determine which socket we're on
         for (BlockConnector curSocket : block.getSockets()) {
-
+     
             //if bottom socket
             if (curSocket.getPositionType() == BlockConnector.PositionType.BOTTOM) {
 
@@ -58,17 +64,18 @@ public class InfixBlockShape extends BlockShape {
                     gpBottom.lineTo(
                             (float) gpBottom.getCurrentPoint().getX() + BOTTOM_SOCKET_MIDDLE_SPACER,
                             (float) gpBottom.getCurrentPoint().getY());
-                } else {
+                }else {
                     gpBottom.lineTo(
                             (float) gpBottom.getCurrentPoint().getX() + BOTTOM_SOCKET_SIDE_SPACER,
                             (float) gpBottom.getCurrentPoint().getY());
                 }
-
+               
 
                 //move down so bevel doesn't screw up from connecting infinitely sharp corner
                 // as occurs from a curved port
                 BlockShapeUtil.lineToRelative(gpBottom, 0, -0.1f);
 
+
                 //////////////////////
                 //begin drawing socket
                 //////////////////////
@@ -86,12 +93,13 @@ public class InfixBlockShape extends BlockShape {
                             (float) gpBottom.getCurrentPoint().getX() + BOTTOM_SOCKET_SIDE_SPACER,
                             (float) gpBottom.getCurrentPoint().getY());
 
-
                     //draw first socket - down right side
                     BCS.addDataSocket(gpBottom, curSocket.getKind(), false);
                     //rb.updateSocketPoint(curSocket, rightSocket);
                 } else { //there is a connected block
                     Block connectedBlock = rb.getWorkspace().getEnv().getBlock(curSocket.getBlockID());
+                    
+                    //TODO: check why RBlock on second connector is always NULL???
                     RenderableBlock connectedRBlock = rb.getWorkspace().getEnv().getRenderableBlock(curSocket.getBlockID());
 
                     //calculate and update the new socket point
@@ -232,18 +240,27 @@ public class InfixBlockShape extends BlockShape {
         //System.out.println("determining block width");
 
         int width = super.determineBlockWidth();
-
-        //if the sum of bottom sockets is greater than the calculated width, then use it
+        
         int bottomSocketWidth = 0;
+        
+        
         for (BlockConnector socket : block.getSockets()) {
             if (socket.getPositionType() == BlockConnector.PositionType.BOTTOM) {
                 if (socket.getBlockID() == Block.NULL) {
                     //3 socket spacers = left of socket, between connectors, right of socket
                     bottomSocketWidth += BOTTOM_SOCKET_SIDE_SPACER;
+                    if(block.isCommandBlock()) {//added by letsgoING for new setVariableBlock test
+                    	//TODO get correct size of socket
+                    	bottomSocketWidth +=  rb.accomodateLabelsWidth();
+                    }
                 } else { //a block is connected to socket
                     //TODO get their assigned width from rb
                     if (rb.getSocketSpaceDimension(socket) != null) {
                         bottomSocketWidth += rb.getSocketSpaceDimension(socket).width;
+                        if(block.isCommandBlock()) {//added by letsgoING for new setVariableBlock test
+                        	//TODO get correct size of socket
+	                    	bottomSocketWidth += rb.accomodateLabelsWidth();
+	                    }
                     }
                     bottomSocketWidth -= BlockConnectorShape.NORMAL_DATA_PLUG_WIDTH;
                     // if it's a mirror plug, subtract for the other side, too.
@@ -255,6 +272,7 @@ public class InfixBlockShape extends BlockShape {
         }
 
 
+
         bottomSocketWidth += 2 * BOTTOM_SOCKET_MIDDLE_SPACER;  //TODO need to decide for a size of the middle spacer and how to place them
         bottomSocketWidth += 2 * BOTTOM_SOCKET_SIDE_SPACER;
 
diff --git a/src/main/java/edu/mit/blocks/renderable/NameLabel.java b/src/main/java/edu/mit/blocks/renderable/NameLabel.java
index 75ca66dbfd98b5225222330937e7407da569346f..6b4f14b34d85e496273fed921f87ec410ca86afa 100644
--- a/src/main/java/edu/mit/blocks/renderable/NameLabel.java
+++ b/src/main/java/edu/mit/blocks/renderable/NameLabel.java
@@ -34,11 +34,20 @@ class NameLabel extends BlockLabel {
                 x += 4 + BlockConnectorShape.getConnectorDimensions(rb.getBlock().getPlug()).width;
             }
             if (rb.getBlock().isInfix()) {
-                if (!rb.getBlock().getSocketAt(0).hasBlock()) {
-                    x += 30;
-                } else {
-                    x += rb.getSocketSpaceDimension(rb.getBlock().getSocketAt(0)).width;
-                }
+            	//added by letsgoING for new setVariableBlock test
+            	if(rb.getBlock().isCommandBlock()) {
+            		if (!rb.getBlock().getSocketAt(0).hasBlock()) {
+                        x += 60;
+                    } else {
+                        x += rb.getSocketSpaceDimension(rb.getBlock().getSocketAt(0)).width+30;
+                    }
+            	}else {
+	                if (!rb.getBlock().getSocketAt(0).hasBlock()) {
+	                    x += 30;
+	                } else {
+	                    x += rb.getSocketSpaceDimension(rb.getBlock().getSocketAt(0)).width;
+	                }
+            	}
             }
 
             if (rb.getBlockWidget() == null) {
diff --git a/src/main/java/edu/mit/blocks/renderable/RenderableBlock.java b/src/main/java/edu/mit/blocks/renderable/RenderableBlock.java
index eb2a7065c57b91f3541a9ff4de8b1541ba507f0e..920869a888092ec74cc5266b41385a84c6c00796 100644
--- a/src/main/java/edu/mit/blocks/renderable/RenderableBlock.java
+++ b/src/main/java/edu/mit/blocks/renderable/RenderableBlock.java
@@ -147,6 +147,7 @@ public class RenderableBlock extends JComponent implements SearchableElement,
 	 * loading as well. In this case, isLoading would still be false
 	 */
 	private boolean isSearchResult = false;
+	private boolean contextMenueActive = false;
 	private boolean pickedUp = false;
 	private boolean dragging = false;
 	private boolean linkedDefArgsBefore = false;
@@ -1597,14 +1598,14 @@ public class RenderableBlock extends JComponent implements SearchableElement,
 		return location;
 	}
 
-	public void cloneMe() {
-		cloneThis(this);
+	public void cloneMe(boolean cloneFollowing) {
+		cloneThis(this, cloneFollowing);
 		workspace.notifyListeners(new WorkspaceEvent(workspace, this
 				.getParentWidget(), this.getBlockID(),
 				WorkspaceEvent.BLOCK_CLONED, true));	
 	}
 
-	private RenderableBlock cloneThis(RenderableBlock rb)
+	private RenderableBlock cloneThis(RenderableBlock rb, boolean cloneFollowing)
     {
     	Block oriBlock = rb.getBlock();
     	oriBlock.getSockets();
@@ -1626,7 +1627,7 @@ public class RenderableBlock extends JComponent implements SearchableElement,
     		{
     			oriSocket.getBlockID();
     			RenderableBlock subRb = workspace.getEnv().getRenderableBlock(oriSocket.getBlockID());
-    			RenderableBlock newSubRb = cloneThis(subRb);
+    			RenderableBlock newSubRb = cloneThis(subRb, true);
     			
     			if (newSubRb.getBlock().isFunctionBlock())
     			{
@@ -1649,7 +1650,7 @@ public class RenderableBlock extends JComponent implements SearchableElement,
     		++i;
     	}
     	
-    	if (rb.getBlock().isCommandBlock())
+    	if (rb.getBlock().isCommandBlock() && cloneFollowing)
     	{
     		BlockConnector oriAfterConnector = rb.getBlock().getAfterConnector();
     		if (oriAfterConnector != null)
@@ -1657,7 +1658,7 @@ public class RenderableBlock extends JComponent implements SearchableElement,
 	    		if (oriAfterConnector.hasBlock())
 	    		{
 	    			RenderableBlock oriAfterRb = workspace.getEnv().getRenderableBlock(oriAfterConnector.getBlockID());
-	    			RenderableBlock newAfterRb = cloneThis(oriAfterRb);
+	    			RenderableBlock newAfterRb = cloneThis(oriAfterRb, true);
 	    			
 	    			newAfterRb.getBlock().getBeforeConnector().setConnectorBlockID(newRb.getBlockID());
 	    			newRb.getBlock().getAfterConnector().setConnectorBlockID(newAfterRb.getBlockID());
@@ -1848,9 +1849,10 @@ public class RenderableBlock extends JComponent implements SearchableElement,
 
 	public void mouseReleased(MouseEvent e) {
 		if (SwingUtilities.isLeftMouseButton(e)) {
-			if (!pickedUp) {
+			if (!pickedUp && ! contextMenueActive) { // contextMenueActive -> added by letsgoING
 				throw new RuntimeException("dropping without prior dragging?");
 			}
+			contextMenueActive = false; //TODO: check if reset is needed in other places
 			dragHandler.mouseReleased(e);
 
 			// if the block was dragged before...then
@@ -1907,10 +1909,13 @@ public class RenderableBlock extends JComponent implements SearchableElement,
 			}
 		}
 		pickedUp = false;
-		if (e.isPopupTrigger() || SwingUtilities.isRightMouseButton(e) || e.isControlDown()) {
-			if ( SwingUtilities.isRightMouseButton(e) &  e.isControlDown()){// added by letsgoING
+		if (e.isPopupTrigger() || SwingUtilities.isRightMouseButton(e) || e.isControlDown() || e.isShiftDown()) {
+			if ( SwingUtilities.isRightMouseButton(e) &  e.isControlDown() && e.isShiftDown()){// added by letsgoING
 				//System.out.println("CLONING");
-				this.cloneMe();
+				this.cloneMe(true);
+			}
+			else if(SwingUtilities.isRightMouseButton(e) &  e.isControlDown()) {
+				this.cloneMe(false);
 			}
 			else{
 				// add context menu at right click location to provide functionality
@@ -1918,6 +1923,7 @@ public class RenderableBlock extends JComponent implements SearchableElement,
 				PopupMenu popup = ContextMenu.getContextMenuFor(this);
 				add(popup);
 				popup.show(this, e.getX(), e.getY());
+				contextMenueActive = true; //TODO: check where to reset
 			}
 			workspace.getMiniMap().repaint();
 		}
diff --git a/src/main/java/edu/mit/blocks/renderable/SocketLabel.java b/src/main/java/edu/mit/blocks/renderable/SocketLabel.java
index 7cc953554868ee0d103750292f14b7e9327bd0ac..b01741678792466af67c970182f5cc9e0e91c2fd 100644
--- a/src/main/java/edu/mit/blocks/renderable/SocketLabel.java
+++ b/src/main/java/edu/mit/blocks/renderable/SocketLabel.java
@@ -24,7 +24,10 @@ class SocketLabel extends BlockLabel {
      * @return true if the specified socket should have a corresponding Blocklabel instance added to this.
      */
     static boolean ignoreSocket(BlockConnector socket) {
-        return (socket.getPositionType() == BlockConnector.PositionType.BOTTOM) || socket.getLabel().equals("");
+    	//removed bottom-connector from ignore-list for new setVariable-Block by letsgoING
+    	//TODO: TEST for all Blocks -> letsgoING
+        //return (socket.getPositionType() == BlockConnector.PositionType.BOTTOM) || socket.getLabel().equals("");
+    	return socket.getLabel().equals("");
     }
 
     void update(Point2D socketPoint) {
diff --git a/src/main/java/edu/mit/blocks/workspace/ContextMenu.java b/src/main/java/edu/mit/blocks/workspace/ContextMenu.java
index 14d088c00ddf062e47665ae17d254afec1091bc2..d5208fb0ba344f806377d0760a9618738744f91c 100644
--- a/src/main/java/edu/mit/blocks/workspace/ContextMenu.java
+++ b/src/main/java/edu/mit/blocks/workspace/ContextMenu.java
@@ -30,8 +30,11 @@ public class ContextMenu extends PopupMenu implements ActionListener {
     private final static String REMOVE_COMMENT_BLOCK = "REMOVECOMMENT";
     private static boolean removeCommentMenuInit = false;
     private final static String CLONE_BLOCK = "CLONE";	//heqichen
+    private final static String CLONE_BLOCKS = "CLONEALL"; //letsgoING
     private static MenuItem cloneItem1 = null;	//heqichen
     private static MenuItem cloneItem2 = null;	//heqichen
+    private static MenuItem cloneAllItem1 = null;	//heqichen
+    private static MenuItem cloneAllItem2 = null;	//heqichen
     //context menu for canvas plus
     //menu items for canvas context menu
     private static ContextMenu canvasMenu = new ContextMenu();
@@ -62,6 +65,11 @@ public class ContextMenu extends PopupMenu implements ActionListener {
     	cloneItem1.addActionListener(rndBlockMenu);
         addCommentMenu.add(cloneItem1);
         
+        cloneAllItem1 = new MenuItem(uiMessageBundle.getString("ardublock.ui.clone_all"));
+    	cloneAllItem1.setActionCommand(CLONE_BLOCKS);
+    	cloneAllItem1.addActionListener(rndBlockMenu);
+        addCommentMenu.add(cloneAllItem1);
+        
         addCommentMenuInit = true;
         
     }
@@ -85,6 +93,11 @@ public class ContextMenu extends PopupMenu implements ActionListener {
     	cloneItem2.addActionListener(rndBlockMenu);
         removeCommentMenu.add(cloneItem2);
         
+        cloneAllItem2 = new MenuItem(uiMessageBundle.getString("ardublock.ui.clone_all"));
+    	cloneAllItem2.setActionCommand(CLONE_BLOCKS);
+    	cloneAllItem2.addActionListener(rndBlockMenu);
+    	removeCommentMenu.add(cloneAllItem2);
+        
         removeCommentMenuInit = true;
     }
 
@@ -152,10 +165,16 @@ public class ContextMenu extends PopupMenu implements ActionListener {
             if (activeComponent != null && activeComponent instanceof RenderableBlock) {
                 ((RenderableBlock) activeComponent).removeComment();
             }
-        } else if (a.getActionCommand() == CLONE_BLOCK) {
+        } else if (a.getActionCommand() == CLONE_BLOCKS) {
+        	//notify the renderableblock componenet that lauched the conetxt menu
+            if (activeComponent != null && activeComponent instanceof RenderableBlock) {
+                ((RenderableBlock) activeComponent).cloneMe(true);
+            }
+        }
+        else if (a.getActionCommand() == CLONE_BLOCK) {
         	//notify the renderableblock componenet that lauched the conetxt menu
             if (activeComponent != null && activeComponent instanceof RenderableBlock) {
-                ((RenderableBlock) activeComponent).cloneMe();
+                ((RenderableBlock) activeComponent).cloneMe(false);
             }
         }
     }