Added new ECL Command "find-all"

Signed-off-by: Alexander Dudaev <aleksandr.dudayev@xored.com>
Change-Id: I9544f53a458e33b74f949cb31c8cbff963e17583
diff --git a/ecl/plugins/org.eclipse.rcptt.ecl.operations/gen-src/org/eclipse/rcptt/ecl/operations/FindAll.java b/ecl/plugins/org.eclipse.rcptt.ecl.operations/gen-src/org/eclipse/rcptt/ecl/operations/FindAll.java
new file mode 100644
index 0000000..e50c1fc
--- /dev/null
+++ b/ecl/plugins/org.eclipse.rcptt.ecl.operations/gen-src/org/eclipse/rcptt/ecl/operations/FindAll.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (c) 2018 Xored Software Inc and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Xored Software Inc - initial API and implementation and/or initial documentation
+ *******************************************************************************/
+package org.eclipse.rcptt.ecl.operations;
+
+import org.eclipse.rcptt.ecl.core.Command;
+
+/**
+ * <!-- begin-user-doc -->
+ * A representation of the model object '<em><b>Find All</b></em>'.
+ * <!-- end-user-doc -->
+ *
+ * <p>
+ * The following features are supported:
+ * </p>
+ * <ul>
+ *   <li>{@link org.eclipse.rcptt.ecl.operations.FindAll#getStr <em>Str</em>}</li>
+ *   <li>{@link org.eclipse.rcptt.ecl.operations.FindAll#getRegex <em>Regex</em>}</li>
+ * </ul>
+ *
+ * @see org.eclipse.rcptt.ecl.operations.OperationsPackage#getFindAll()
+ * @model annotation="http://www.eclipse.org/ecl/docs description='' example=''"
+ * @generated
+ */
+public interface FindAll extends Command {
+	/**
+	 * Returns the value of the '<em><b>Str</b></em>' attribute.
+	 * <!-- begin-user-doc -->
+	 * <p>
+	 * If the meaning of the '<em>Str</em>' attribute isn't clear,
+	 * there really should be more of a description here...
+	 * </p>
+	 * <!-- end-user-doc -->
+	 * @return the value of the '<em>Str</em>' attribute.
+	 * @see #setStr(String)
+	 * @see org.eclipse.rcptt.ecl.operations.OperationsPackage#getFindAll_Str()
+	 * @model
+	 * @generated
+	 */
+	String getStr();
+
+	/**
+	 * Sets the value of the '{@link org.eclipse.rcptt.ecl.operations.FindAll#getStr <em>Str</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @param value the new value of the '<em>Str</em>' attribute.
+	 * @see #getStr()
+	 * @generated
+	 */
+	void setStr(String value);
+
+	/**
+	 * Returns the value of the '<em><b>Regex</b></em>' attribute.
+	 * <!-- begin-user-doc -->
+	 * <p>
+	 * If the meaning of the '<em>Regex</em>' attribute isn't clear,
+	 * there really should be more of a description here...
+	 * </p>
+	 * <!-- end-user-doc -->
+	 * @return the value of the '<em>Regex</em>' attribute.
+	 * @see #setRegex(String)
+	 * @see org.eclipse.rcptt.ecl.operations.OperationsPackage#getFindAll_Regex()
+	 * @model
+	 * @generated
+	 */
+	String getRegex();
+
+	/**
+	 * Sets the value of the '{@link org.eclipse.rcptt.ecl.operations.FindAll#getRegex <em>Regex</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @param value the new value of the '<em>Regex</em>' attribute.
+	 * @see #getRegex()
+	 * @generated
+	 */
+	void setRegex(String value);
+
+} // FindAll
diff --git a/ecl/plugins/org.eclipse.rcptt.ecl.operations/gen-src/org/eclipse/rcptt/ecl/operations/OperationsFactory.java b/ecl/plugins/org.eclipse.rcptt.ecl.operations/gen-src/org/eclipse/rcptt/ecl/operations/OperationsFactory.java
index 0de6f93..cc2c95e 100644
--- a/ecl/plugins/org.eclipse.rcptt.ecl.operations/gen-src/org/eclipse/rcptt/ecl/operations/OperationsFactory.java
+++ b/ecl/plugins/org.eclipse.rcptt.ecl.operations/gen-src/org/eclipse/rcptt/ecl/operations/OperationsFactory.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2014 Xored Software Inc and others.
+ * Copyright (c) 2009, 2014, 2018 Xored Software Inc and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -399,6 +399,15 @@
 	ThrowError createThrowError();
 
 	/**
+	 * Returns a new object of class '<em>Find All</em>'.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return a new object of class '<em>Find All</em>'.
+	 * @generated
+	 */
+	FindAll createFindAll();
+
+	/**
 	 * Returns a new object of class '<em>Binary Op</em>'.
 	 * <!-- begin-user-doc -->
 	 * <!-- end-user-doc -->
diff --git a/ecl/plugins/org.eclipse.rcptt.ecl.operations/gen-src/org/eclipse/rcptt/ecl/operations/OperationsPackage.java b/ecl/plugins/org.eclipse.rcptt.ecl.operations/gen-src/org/eclipse/rcptt/ecl/operations/OperationsPackage.java
index 24d044b..2e0db4c 100644
--- a/ecl/plugins/org.eclipse.rcptt.ecl.operations/gen-src/org/eclipse/rcptt/ecl/operations/OperationsPackage.java
+++ b/ecl/plugins/org.eclipse.rcptt.ecl.operations/gen-src/org/eclipse/rcptt/ecl/operations/OperationsPackage.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2014 Xored Software Inc and others.
+ * Copyright (c) 2009, 2014, 2018 Xored Software Inc and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -2325,6 +2325,61 @@
 	int THROW_ERROR_FEATURE_COUNT = CorePackage.COMMAND_FEATURE_COUNT + 1;
 
 	/**
+	 * The meta object id for the '{@link org.eclipse.rcptt.ecl.operations.impl.FindAllImpl <em>Find All</em>}' class.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see org.eclipse.rcptt.ecl.operations.impl.FindAllImpl
+	 * @see org.eclipse.rcptt.ecl.operations.impl.OperationsPackageImpl#getFindAll()
+	 * @generated
+	 */
+	int FIND_ALL = 43;
+
+	/**
+	 * The feature id for the '<em><b>Host</b></em>' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	int FIND_ALL__HOST = CorePackage.COMMAND__HOST;
+
+	/**
+	 * The feature id for the '<em><b>Bindings</b></em>' containment reference list.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	int FIND_ALL__BINDINGS = CorePackage.COMMAND__BINDINGS;
+
+	/**
+	 * The feature id for the '<em><b>Str</b></em>' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	int FIND_ALL__STR = CorePackage.COMMAND_FEATURE_COUNT + 0;
+
+	/**
+	 * The feature id for the '<em><b>Regex</b></em>' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	int FIND_ALL__REGEX = CorePackage.COMMAND_FEATURE_COUNT + 1;
+
+	/**
+	 * The number of structural features of the '<em>Find All</em>' class.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	int FIND_ALL_FEATURE_COUNT = CorePackage.COMMAND_FEATURE_COUNT + 2;
+
+	/**
 	 * Returns the meta object for class '{@link org.eclipse.rcptt.ecl.operations.Eq <em>Eq</em>}'.
 	 * <!-- begin-user-doc -->
 	 * <!-- end-user-doc -->
@@ -3317,6 +3372,38 @@
 	EAttribute getThrowError_Message();
 
 	/**
+	 * Returns the meta object for class '{@link org.eclipse.rcptt.ecl.operations.FindAll <em>Find All</em>}'.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the meta object for class '<em>Find All</em>'.
+	 * @see org.eclipse.rcptt.ecl.operations.FindAll
+	 * @generated
+	 */
+	EClass getFindAll();
+
+	/**
+	 * Returns the meta object for the attribute '{@link org.eclipse.rcptt.ecl.operations.FindAll#getStr <em>Str</em>}'.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the meta object for the attribute '<em>Str</em>'.
+	 * @see org.eclipse.rcptt.ecl.operations.FindAll#getStr()
+	 * @see #getFindAll()
+	 * @generated
+	 */
+	EAttribute getFindAll_Str();
+
+	/**
+	 * Returns the meta object for the attribute '{@link org.eclipse.rcptt.ecl.operations.FindAll#getRegex <em>Regex</em>}'.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the meta object for the attribute '<em>Regex</em>'.
+	 * @see org.eclipse.rcptt.ecl.operations.FindAll#getRegex()
+	 * @see #getFindAll()
+	 * @generated
+	 */
+	EAttribute getFindAll_Regex();
+
+	/**
 	 * Returns the meta object for the attribute '{@link org.eclipse.rcptt.ecl.operations.ParseTime#getInput <em>Input</em>}'.
 	 * <!-- begin-user-doc -->
 	 * <!-- end-user-doc -->
@@ -4218,6 +4305,32 @@
 		EAttribute THROW_ERROR__MESSAGE = eINSTANCE.getThrowError_Message();
 
 		/**
+		 * The meta object literal for the '{@link org.eclipse.rcptt.ecl.operations.impl.FindAllImpl <em>Find All</em>}' class.
+		 * <!-- begin-user-doc -->
+		 * <!-- end-user-doc -->
+		 * @see org.eclipse.rcptt.ecl.operations.impl.FindAllImpl
+		 * @see org.eclipse.rcptt.ecl.operations.impl.OperationsPackageImpl#getFindAll()
+		 * @generated
+		 */
+		EClass FIND_ALL = eINSTANCE.getFindAll();
+
+		/**
+		 * The meta object literal for the '<em><b>Str</b></em>' attribute feature.
+		 * <!-- begin-user-doc -->
+		 * <!-- end-user-doc -->
+		 * @generated
+		 */
+		EAttribute FIND_ALL__STR = eINSTANCE.getFindAll_Str();
+
+		/**
+		 * The meta object literal for the '<em><b>Regex</b></em>' attribute feature.
+		 * <!-- begin-user-doc -->
+		 * <!-- end-user-doc -->
+		 * @generated
+		 */
+		EAttribute FIND_ALL__REGEX = eINSTANCE.getFindAll_Regex();
+
+		/**
 		 * The meta object literal for the '<em><b>Input</b></em>' attribute feature.
 		 * <!-- begin-user-doc -->
 		 * <!-- end-user-doc -->
diff --git a/ecl/plugins/org.eclipse.rcptt.ecl.operations/gen-src/org/eclipse/rcptt/ecl/operations/impl/FindAllImpl.java b/ecl/plugins/org.eclipse.rcptt.ecl.operations/gen-src/org/eclipse/rcptt/ecl/operations/impl/FindAllImpl.java
new file mode 100644
index 0000000..2585967
--- /dev/null
+++ b/ecl/plugins/org.eclipse.rcptt.ecl.operations/gen-src/org/eclipse/rcptt/ecl/operations/impl/FindAllImpl.java
@@ -0,0 +1,226 @@
+/*******************************************************************************
+ * Copyright (c) 2018 Xored Software Inc and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Xored Software Inc - initial API and implementation and/or initial documentation
+ *******************************************************************************/
+package org.eclipse.rcptt.ecl.operations.impl;
+
+import org.eclipse.emf.common.notify.Notification;
+
+import org.eclipse.emf.ecore.EClass;
+
+import org.eclipse.emf.ecore.impl.ENotificationImpl;
+
+import org.eclipse.rcptt.ecl.core.impl.CommandImpl;
+
+import org.eclipse.rcptt.ecl.operations.FindAll;
+import org.eclipse.rcptt.ecl.operations.OperationsPackage;
+
+/**
+ * <!-- begin-user-doc -->
+ * An implementation of the model object '<em><b>Find All</b></em>'.
+ * <!-- end-user-doc -->
+ * <p>
+ * The following features are implemented:
+ * </p>
+ * <ul>
+ *   <li>{@link org.eclipse.rcptt.ecl.operations.impl.FindAllImpl#getStr <em>Str</em>}</li>
+ *   <li>{@link org.eclipse.rcptt.ecl.operations.impl.FindAllImpl#getRegex <em>Regex</em>}</li>
+ * </ul>
+ *
+ * @generated
+ */
+public class FindAllImpl extends CommandImpl implements FindAll {
+	/**
+	 * The default value of the '{@link #getStr() <em>Str</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #getStr()
+	 * @generated
+	 * @ordered
+	 */
+	protected static final String STR_EDEFAULT = null;
+
+	/**
+	 * The cached value of the '{@link #getStr() <em>Str</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #getStr()
+	 * @generated
+	 * @ordered
+	 */
+	protected String str = STR_EDEFAULT;
+
+	/**
+	 * The default value of the '{@link #getRegex() <em>Regex</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #getRegex()
+	 * @generated
+	 * @ordered
+	 */
+	protected static final String REGEX_EDEFAULT = null;
+
+	/**
+	 * The cached value of the '{@link #getRegex() <em>Regex</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #getRegex()
+	 * @generated
+	 * @ordered
+	 */
+	protected String regex = REGEX_EDEFAULT;
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	protected FindAllImpl() {
+		super();
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	protected EClass eStaticClass() {
+		return OperationsPackage.Literals.FIND_ALL;
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public String getStr() {
+		return str;
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public void setStr(String newStr) {
+		String oldStr = str;
+		str = newStr;
+		if (eNotificationRequired())
+			eNotify(new ENotificationImpl(this, Notification.SET, OperationsPackage.FIND_ALL__STR, oldStr, str));
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public String getRegex() {
+		return regex;
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public void setRegex(String newRegex) {
+		String oldRegex = regex;
+		regex = newRegex;
+		if (eNotificationRequired())
+			eNotify(new ENotificationImpl(this, Notification.SET, OperationsPackage.FIND_ALL__REGEX, oldRegex, regex));
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public Object eGet(int featureID, boolean resolve, boolean coreType) {
+		switch (featureID) {
+			case OperationsPackage.FIND_ALL__STR:
+				return getStr();
+			case OperationsPackage.FIND_ALL__REGEX:
+				return getRegex();
+		}
+		return super.eGet(featureID, resolve, coreType);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public void eSet(int featureID, Object newValue) {
+		switch (featureID) {
+			case OperationsPackage.FIND_ALL__STR:
+				setStr((String)newValue);
+				return;
+			case OperationsPackage.FIND_ALL__REGEX:
+				setRegex((String)newValue);
+				return;
+		}
+		super.eSet(featureID, newValue);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public void eUnset(int featureID) {
+		switch (featureID) {
+			case OperationsPackage.FIND_ALL__STR:
+				setStr(STR_EDEFAULT);
+				return;
+			case OperationsPackage.FIND_ALL__REGEX:
+				setRegex(REGEX_EDEFAULT);
+				return;
+		}
+		super.eUnset(featureID);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public boolean eIsSet(int featureID) {
+		switch (featureID) {
+			case OperationsPackage.FIND_ALL__STR:
+				return STR_EDEFAULT == null ? str != null : !STR_EDEFAULT.equals(str);
+			case OperationsPackage.FIND_ALL__REGEX:
+				return REGEX_EDEFAULT == null ? regex != null : !REGEX_EDEFAULT.equals(regex);
+		}
+		return super.eIsSet(featureID);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public String toString() {
+		if (eIsProxy()) return super.toString();
+
+		StringBuilder result = new StringBuilder(super.toString());
+		result.append(" (str: ");
+		result.append(str);
+		result.append(", regex: ");
+		result.append(regex);
+		result.append(')');
+		return result.toString();
+	}
+
+} //FindAllImpl
diff --git a/ecl/plugins/org.eclipse.rcptt.ecl.operations/gen-src/org/eclipse/rcptt/ecl/operations/impl/OperationsFactoryImpl.java b/ecl/plugins/org.eclipse.rcptt.ecl.operations/gen-src/org/eclipse/rcptt/ecl/operations/impl/OperationsFactoryImpl.java
index eb0ea44..ffb5f1f 100644
--- a/ecl/plugins/org.eclipse.rcptt.ecl.operations/gen-src/org/eclipse/rcptt/ecl/operations/impl/OperationsFactoryImpl.java
+++ b/ecl/plugins/org.eclipse.rcptt.ecl.operations/gen-src/org/eclipse/rcptt/ecl/operations/impl/OperationsFactoryImpl.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2014 Xored Software Inc and others.
+ * Copyright (c) 2009, 2014, 2018 Xored Software Inc and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -29,6 +29,7 @@
 import org.eclipse.rcptt.ecl.operations.Emit;
 import org.eclipse.rcptt.ecl.operations.Entry;
 import org.eclipse.rcptt.ecl.operations.Eq;
+import org.eclipse.rcptt.ecl.operations.FindAll;
 import org.eclipse.rcptt.ecl.operations.Format;
 import org.eclipse.rcptt.ecl.operations.FormatTime;
 import org.eclipse.rcptt.ecl.operations.GetTime;
@@ -143,6 +144,7 @@
 			case OperationsPackage.SPLIT: return createSplit();
 			case OperationsPackage.PARSE_TIME: return createParseTime();
 			case OperationsPackage.THROW_ERROR: return createThrowError();
+			case OperationsPackage.FIND_ALL: return createFindAll();
 			default:
 				throw new IllegalArgumentException("The class '" + eClass.getName() + "' is not a valid classifier");
 		}
@@ -529,6 +531,16 @@
 	}
 
 	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public FindAll createFindAll() {
+		FindAllImpl findAll = new FindAllImpl();
+		return findAll;
+	}
+
+	/**
 	 * <!-- begin-user-doc --> <!-- end-user-doc -->
 	 * @generated
 	 */
diff --git a/ecl/plugins/org.eclipse.rcptt.ecl.operations/gen-src/org/eclipse/rcptt/ecl/operations/impl/OperationsPackageImpl.java b/ecl/plugins/org.eclipse.rcptt.ecl.operations/gen-src/org/eclipse/rcptt/ecl/operations/impl/OperationsPackageImpl.java
index df54242..56bd8ff 100644
--- a/ecl/plugins/org.eclipse.rcptt.ecl.operations/gen-src/org/eclipse/rcptt/ecl/operations/impl/OperationsPackageImpl.java
+++ b/ecl/plugins/org.eclipse.rcptt.ecl.operations/gen-src/org/eclipse/rcptt/ecl/operations/impl/OperationsPackageImpl.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2014 Xored Software Inc and others.
+ * Copyright (c) 2009, 2014, 2018 Xored Software Inc and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -32,6 +32,7 @@
 import org.eclipse.rcptt.ecl.operations.Emit;
 import org.eclipse.rcptt.ecl.operations.Entry;
 import org.eclipse.rcptt.ecl.operations.Eq;
+import org.eclipse.rcptt.ecl.operations.FindAll;
 import org.eclipse.rcptt.ecl.operations.Format;
 import org.eclipse.rcptt.ecl.operations.FormatTime;
 import org.eclipse.rcptt.ecl.operations.GetTime;
@@ -332,6 +333,13 @@
 	private EClass throwErrorEClass = null;
 
 	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	private EClass findAllEClass = null;
+
+	/**
 	 * <!-- begin-user-doc --> <!-- end-user-doc -->
 	 * @generated
 	 */
@@ -363,7 +371,7 @@
 
 	/**
 	 * Creates, registers, and initializes the <b>Package</b> for this model, and for any others upon which it depends.
-	 * 
+	 *
 	 * <p>This method is used to initialize {@link OperationsPackage#eINSTANCE} when that field is accessed.
 	 * Clients should not invoke it directly. Instead, they should simply access that field to obtain the package.
 	 * <!-- begin-user-doc
@@ -377,12 +385,14 @@
 		if (isInited) return (OperationsPackage)EPackage.Registry.INSTANCE.getEPackage(OperationsPackage.eNS_URI);
 
 		// Obtain or create and register package
-		OperationsPackageImpl theOperationsPackage = (OperationsPackageImpl)(EPackage.Registry.INSTANCE.get(eNS_URI) instanceof OperationsPackageImpl ? EPackage.Registry.INSTANCE.get(eNS_URI) : new OperationsPackageImpl());
+		Object registeredOperationsPackage = EPackage.Registry.INSTANCE.get(eNS_URI);
+		OperationsPackageImpl theOperationsPackage = registeredOperationsPackage instanceof OperationsPackageImpl ? (OperationsPackageImpl)registeredOperationsPackage : new OperationsPackageImpl();
 
 		isInited = true;
 
 		// Initialize simple dependencies
 		CorePackage.eINSTANCE.eClass();
+		EcorePackage.eINSTANCE.eClass();
 
 		// Create package meta-data objects
 		theOperationsPackage.createPackageContents();
@@ -393,7 +403,6 @@
 		// Mark meta-data to indicate it can't be changed
 		theOperationsPackage.freeze();
 
-  
 		// Update the registry and return the package
 		EPackage.Registry.INSTANCE.put(OperationsPackage.eNS_URI, theOperationsPackage);
 		return theOperationsPackage;
@@ -1187,6 +1196,33 @@
 	 * <!-- end-user-doc -->
 	 * @generated
 	 */
+	public EClass getFindAll() {
+		return findAllEClass;
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public EAttribute getFindAll_Str() {
+		return (EAttribute)findAllEClass.getEStructuralFeatures().get(0);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public EAttribute getFindAll_Regex() {
+		return (EAttribute)findAllEClass.getEStructuralFeatures().get(1);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
 	public EAttribute getParseTime_Input() {
 		return (EAttribute)parseTimeEClass.getEStructuralFeatures().get(0);
 	}
@@ -1381,6 +1417,10 @@
 
 		throwErrorEClass = createEClass(THROW_ERROR);
 		createEAttribute(throwErrorEClass, THROW_ERROR__MESSAGE);
+
+		findAllEClass = createEClass(FIND_ALL);
+		createEAttribute(findAllEClass, FIND_ALL__STR);
+		createEAttribute(findAllEClass, FIND_ALL__REGEX);
 	}
 
 	/**
@@ -1457,6 +1497,7 @@
 		splitEClass.getESuperTypes().add(theCorePackage.getCommand());
 		parseTimeEClass.getESuperTypes().add(theCorePackage.getCommand());
 		throwErrorEClass.getESuperTypes().add(theCorePackage.getCommand());
+		findAllEClass.getESuperTypes().add(theCorePackage.getCommand());
 
 		// Initialize classes and features; add operations and parameters
 		initEClass(eqEClass, Eq.class, "Eq", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS);
@@ -1600,6 +1641,10 @@
 		initEClass(throwErrorEClass, ThrowError.class, "ThrowError", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS);
 		initEAttribute(getThrowError_Message(), theEcorePackage.getEString(), "message", null, 1, 1, ThrowError.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
 
+		initEClass(findAllEClass, FindAll.class, "FindAll", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS);
+		initEAttribute(getFindAll_Str(), theEcorePackage.getEString(), "str", null, 0, 1, FindAll.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
+		initEAttribute(getFindAll_Regex(), theEcorePackage.getEString(), "regex", null, 0, 1, FindAll.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
+
 		// Create resource
 		createResource(eNS_URI);
 
@@ -1618,470 +1663,477 @@
 	 * @generated
 	 */
 	protected void createDocsAnnotations() {
-		String source = "http://www.eclipse.org/ecl/docs";	
+		String source = "http://www.eclipse.org/ecl/docs";
 		addAnnotation
-		  (eqEClass, 
-		   source, 
+		  (eqEClass,
+		   source,
 		   new String[] {
 			 "description", "Compares arguments on equality",
 			 "returns", "<code>true</code> when args are equal, <code>false</code> otherwise."
-		   });	
+		   });
 		addAnnotation
-		  (getEq_Left(), 
-		   source, 
+		  (getEq_Left(),
+		   source,
 		   new String[] {
 			 "description", "Left argument"
-		   });	
+		   });
 		addAnnotation
-		  (getEq_Right(), 
-		   source, 
+		  (getEq_Right(),
+		   source,
 		   new String[] {
 			 "description", "Right argument"
-		   });	
+		   });
 		addAnnotation
-		  (intEClass, 
-		   source, 
+		  (intEClass,
+		   source,
 		   new String[] {
 			 "description", "Converts its argument to int.",
 			 "returns", "Returns integer value or fails if value cannot be converted. <code>true</code> is converted to <code>1</code> and <code>false</code> is converted to <code>0</code>.",
 			 "example", "//verifies that the number of Stops it less then 3\nget-view \"Execution View\" | get-label -after [get-label \"Stops:\"] | get-text | int | lt 3 | verify-true"
-		   });	
+		   });
 		addAnnotation
-		  (longEClass, 
-		   source, 
+		  (longEClass,
+		   source,
 		   new String[] {
 			 "description", "Converts its argument to long.",
 			 "returns", "Returns long value or fails if value cannot be converted. <code>true</code> is converted to <code>1L</code> and <code>false</code> is converted to <code>0L</code>."
-		   });	
+		   });
 		addAnnotation
-		  (floatEClass, 
-		   source, 
+		  (floatEClass,
+		   source,
 		   new String[] {
 			 "description", "Converts its argument to float.",
 			 "returns", "<p>Returns float value or fails if value cannot be converted. <code>true</code> is converted to <code>1.0</code> and <code>false</code> is converted to <code>0</code>. This command uses <code>java.lang.Float.parseFloat</code> method, but also supports a few additional text values for infinity:</p>\n<ul>\n  <li><b>+inf</b> &ndash; returns <code>Float.POSITIVE_INFINITY</code></li>\n  <li><b>inf</b> &ndash; returns <code>Float.POSITIVE_INFINITY</code></li>\n  <li><b>-inf</b> &ndash; returns <code>Float.NEGATIVE_INFINITY</code></li>\n</ul>"
-		   });	
+		   });
 		addAnnotation
-		  (boolEClass, 
-		   source, 
+		  (boolEClass,
+		   source,
 		   new String[] {
 			 "description", "Converts its argument to boolean.",
 			 "returns", "Returns boolean value or fails if value cannot be converted. ",
 			 "example", "bool true | assert-true\nbool 1 | assert-true"
-		   });	
+		   });
 		addAnnotation
-		  (strEClass, 
-		   source, 
+		  (strEClass,
+		   source,
 		   new String[] {
 			 "description", "Converts its argument to string.",
 			 "returns", "Returns string value or fails if value cannot be converted. ",
 			 "example", "//Types \"2\" into log\ndiv 10 5 | str | log"
-		   });	
+		   });
 		addAnnotation
-		  (getConvert_Input(), 
-		   source, 
+		  (getConvert_Input(),
+		   source,
 		   new String[] {
 			 "description", "Argument to be converted."
-		   });	
+		   });
 		addAnnotation
-		  (assertTrueEClass, 
-		   source, 
+		  (assertTrueEClass,
+		   source,
 		   new String[] {
 			 "description", "If input is not true, fails",
 			 "returns", "Nothing",
 			 "example", "...get-tree | get-item Project | get-property childCount -raw | gt 3 | assert-true -message \"Child count is not greater then 3!\" "
-		   });	
+		   });
 		addAnnotation
-		  (getAssertTrue_Input(), 
-		   source, 
+		  (getAssertTrue_Input(),
+		   source,
 		   new String[] {
 			 "description", "Input value. Must be true."
-		   });	
+		   });
 		addAnnotation
-		  (getAssertTrue_Message(), 
-		   source, 
+		  (getAssertTrue_Message(),
+		   source,
 		   new String[] {
 			 "description", "Message to fail with when input is not true"
-		   });	
+		   });
 		addAnnotation
-		  (lengthEClass, 
-		   source, 
+		  (lengthEClass,
+		   source,
 		   new String[] {
 			 "description", "Returns count of objects got from input pipe",
 			 "returns", "Object count",
 			 "example", "emit 1 2 3 | length | equals 3 | verify-true\n\n// verifies that Project item has 10 children\nget-view \"Q7 Explorer\" | get-tree | get-item Project | get-items | length | equals 10 | verify-true"
-		   });	
+		   });
 		addAnnotation
-		  (getLength_Input(), 
-		   source, 
+		  (getLength_Input(),
+		   source,
 		   new String[] {
 			 "description", "List of objects to get the length for"
-		   });	
+		   });
 		addAnnotation
-		  (notEqEClass, 
-		   source, 
+		  (notEqEClass,
+		   source,
 		   new String[] {
 			 "description", "Compares arguments are different",
 			 "returns", "<code>false</code> when args are equal, <code>true</code> otherwise.",
 			 "example", " int 9 | not-eq 10 | verify-true"
-		   });	
+		   });
 		addAnnotation
-		  (getNotEq_Left(), 
-		   source, 
+		  (getNotEq_Left(),
+		   source,
 		   new String[] {
 			 "description", "Left argument"
-		   });	
+		   });
 		addAnnotation
-		  (getNotEq_Right(), 
-		   source, 
+		  (getNotEq_Right(),
+		   source,
 		   new String[] {
 			 "description", "Right argument"
-		   });	
+		   });
 		addAnnotation
-		  (gtEClass, 
-		   source, 
+		  (gtEClass,
+		   source,
 		   new String[] {
 			 "description", "Compares arguments on to one be greater then another",
 			 "returns", "<code>true</code> when left are greater then right, <code>false</code> otherwise.",
 			 "example", "plus 6 4 | gt 8 | verify-true"
-		   });	
+		   });
 		addAnnotation
-		  (ltEClass, 
-		   source, 
+		  (ltEClass,
+		   source,
 		   new String[] {
 			 "description", "Compares arguments one are less then another",
 			 "returns", "<code>true</code> when left is less then right, <code>false</code> otherwise.",
 			 "example", "plus 6 4 | lt 12 | verify-true"
-		   });	
+		   });
 		addAnnotation
-		  (notEClass, 
-		   source, 
+		  (notEClass,
+		   source,
 		   new String[] {
 			 "description", "Return !value",
 			 "returns", "<code>true</code> when value is false, <code>false</code> otherwise.",
 			 "example", "minus 10 7 | equals 2 | not | verify-true"
-		   });	
+		   });
 		addAnnotation
-		  (getNot_Left(), 
-		   source, 
+		  (getNot_Left(),
+		   source,
 		   new String[] {
 			 "description", "Left argument"
-		   });	
+		   });
 		addAnnotation
-		  (tryEClass, 
-		   source, 
+		  (tryEClass,
+		   source,
 		   new String[] {
 			 "description", "Try to execute command, retry times with delay if command are failed.\nExecute catch if all operations is not succesfull. Execute finally in anyway.",
 			 "returns", "return\'s -command output if command is successed.",
 			 "example", "try -times 10 -delay 100 -command {\r\n\t// some ECL scripts\r\n} -error [val errorObj] -catch {\r\n\tlog [$errorObj | get message]\n}"
-		   });	
+		   });
 		addAnnotation
-		  (getTry_Error(), 
-		   source, 
+		  (getTry_Error(),
+		   source,
 		   new String[] {
 			 "description", "A variable to store an error object in. Accessible from catch block."
-		   });	
+		   });
 		addAnnotation
-		  (formatEClass, 
-		   source, 
+		  (formatEClass,
+		   source,
 		   new String[] {
 			 "description", "Writes a formatted string to output pipe",
 			 "returns", "Formatted string",
 			 "example", "format \"string: %s, int: %d\" \"foo\" 5 | log"
-		   });	
+		   });
 		addAnnotation
-		  (getFormat_Format(), 
-		   source, 
+		  (getFormat_Format(),
+		   source,
 		   new String[] {
 			 "description", "Format string as in Java\'s <a href=\"http://docs.oracle.com/javase/6/docs/api/java/util/Formatter.html\">String.format</a>"
-		   });	
+		   });
 		addAnnotation
-		  (getFormat_Args(), 
-		   source, 
+		  (getFormat_Args(),
+		   source,
 		   new String[] {
 			 "description", "Arguments for format string"
-		   });	
+		   });
 		addAnnotation
-		  (emitEClass, 
-		   source, 
+		  (emitEClass,
+		   source,
 		   new String[] {
 			 "description", "Writes its arguments into output pipe. ",
 			 "returns", "List of arguments",
 			 "example", "emit \"hello\" \"world\" | foreach { log }"
-		   });	
+		   });
 		addAnnotation
-		  (repeatWithEClass, 
-		   source, 
+		  (repeatWithEClass,
+		   source,
 		   new String[] {
 			 "description", "Takes list of commands from input pipe and single command as argument and executes them in following order: \n<pre>\ncommand-from-input-1 | command-from-arg\ncommand-from-input-2 | command-from-arg\n...\n</pre>",
 			 "returns", "Aggregated output of command from argument",
 			 "example", "// executes commands:\r\n// echo 1 | gt 2\r\n// echo 2 | gt 2\r\n// echo 3 | gt 2\r\n// output: false, false, true\r\nemit { echo 1} { echo 2} { echo 3} | repeat-with { gt 2 } "
-		   });	
+		   });
 		addAnnotation
-		  (repeatEClass, 
-		   source, 
+		  (repeatEClass,
+		   source,
 		   new String[] {
 			 "description", "Execute specified command multiple times.",
 			 "returns", "Aggregated command output",
 			 "example", "//creates file0, file1, file2, file3, file4 \n\nrepeat [val index] -times 5 -command {\n\n\tget-view \"Q7 Explorer\" | get-tree | select \"Project/Folder\" | get-menu \"New/Other...\" | click\n\twith [get-window New] {\n    \t\tget-tree | select \"General/File\"\n    \t\tget-button \"Next >\" | click\n\t}\n\twith [get-window \"New File\"] {\n    \t\tget-editbox -after [get-label \"File name:\"] | set-text [concat \"file\" [$index | str]]\n    \t\tget-button Finish | click\n\t}\n}"
-		   });	
+		   });
 		addAnnotation
-		  (getRepeat_Index(), 
-		   source, 
+		  (getRepeat_Index(),
+		   source,
 		   new String[] {
 			 "description", "Optional value declaration to hold a current index"
-		   });	
+		   });
 		addAnnotation
-		  (assertEmptyEClass, 
-		   source, 
+		  (assertEmptyEClass,
+		   source,
 		   new String[] {
 			 "description", "Asserts that input pipe doesn\'t contain anything",
 			 "returns", "Nothing",
 			 "example", "find-in-workspace -path \"Project/nonexisting.file\" | assert-empty"
-		   });	
+		   });
 		addAnnotation
-		  (getAssertEmpty_Message(), 
-		   source, 
+		  (getAssertEmpty_Message(),
+		   source,
 		   new String[] {
 			 "description", "Message to fail with when input is not empty"
-		   });	
+		   });
 		addAnnotation
-		  (assertNonEmptyEClass, 
-		   source, 
+		  (assertNonEmptyEClass,
+		   source,
 		   new String[] {
 			 "description", "Asserts that input pipe contain something",
 			 "returns", "Nothing",
 			 "example", "find-in-workspace -path \"Project/.*\" | assert-non-empty"
-		   });	
+		   });
 		addAnnotation
-		  (getAssertNonEmpty_Message(), 
-		   source, 
+		  (getAssertNonEmpty_Message(),
+		   source,
 		   new String[] {
 			 "description", "Message to fail with when input is empty"
-		   });	
+		   });
 		addAnnotation
-		  (concatEClass, 
-		   source, 
+		  (concatEClass,
+		   source,
 		   new String[] {
 			 "description", "Concatenates strings passed as arguments",
 			 "returns", "Concatenated string value",
 			 "example", "concat \"Mess\" \"age\" | equals \"Message\" | assert-true"
-		   });	
+		   });
 		addAnnotation
-		  (orEClass, 
-		   source, 
+		  (orEClass,
+		   source,
 		   new String[] {
 			 "description", "Computes the result of logical Or operation for passed arguments.",
 			 "returns", "<code>true</code> or <code>false</code>.",
 			 "example", "with [get-view \"Q7 Explorer\" | get-tree] {\n  if [or[get-item Project | get-property caption -raw | eq Project][get-property itemCount -raw | eq 1]] {\n    log -message \"One of two verifications passed\"\n  }\n}"
-		   });	
+		   });
 		addAnnotation
-		  (getOr_Args(), 
-		   source, 
+		  (getOr_Args(),
+		   source,
 		   new String[] {
 			 "description", "Arguments to compute on."
-		   });	
+		   });
 		addAnnotation
-		  (andEClass, 
-		   source, 
+		  (andEClass,
+		   source,
 		   new String[] {
 			 "description", "Computes the result of logical And operation for passed arguments.",
 			 "returns", "<code>true</code> or <code>false</code>.",
 			 "example", "with [get-view \"Q7 Explorer\" | get-tree] {\n  if [and[get-item Project | get-property caption -raw | eq Project][get-property itemCount -raw | eq 1]] {\n    log -message \"Both verifications passed\"\n  }\n}"
-		   });	
+		   });
 		addAnnotation
-		  (getAnd_Args(), 
-		   source, 
+		  (getAnd_Args(),
+		   source,
 		   new String[] {
 			 "description", "Arguments to compute on."
-		   });	
+		   });
 		addAnnotation
-		  (getTimeEClass, 
-		   source, 
+		  (getTimeEClass,
+		   source,
 		   new String[] {
 			 "description", "Returns current time as a number of milliseconds since January, 1, 1970.",
 			 "returns", "Current time as long integer",
 			 "example", "get-time | format-time -format \"hh:mm:ss\" | log"
-		   });	
+		   });
 		addAnnotation
-		  (formatTimeEClass, 
-		   source, 
+		  (formatTimeEClass,
+		   source,
 		   new String[] {
 			 "description", "Reads timestamp value (as a number of milliseconds since January, 1, 1970) from input pipe and formats according to given format string. Format string is the same as used in <code>java.text.SimpleDateFormat</code>.",
 			 "returns", "String representation of given time",
 			 "example", "get-time | format-time -format \"dd.MM.yyyy\" | log\n// writes current date, month and year into log"
-		   });	
+		   });
 		addAnnotation
-		  (getBinaryOp_Left(), 
-		   source, 
+		  (getBinaryOp_Left(),
+		   source,
 		   new String[] {
 			 "description", "Left argument"
-		   });	
+		   });
 		addAnnotation
-		  (getBinaryOp_Right(), 
-		   source, 
+		  (getBinaryOp_Right(),
+		   source,
 		   new String[] {
 			 "description", "Right argument"
-		   });	
+		   });
 		addAnnotation
-		  (plusEClass, 
-		   source, 
+		  (plusEClass,
+		   source,
 		   new String[] {
 			 "description", "<p>returns <code>left + right</code></p>\n<p>Before performing an operation, arguments are converted to the widest type according to the following rules:</p>\n<ol>\n  <li><code>string</code> arguments converted to <code>long</code></li>\n  <li><code>boolean</code> arguments converted to <code>long</code> (1 for <code>true</code> and 0 for <code>false</code>)</li>\n  <li>If one of arguments is <code>double</code>, converts the other one to <code>double</code></li>\n  <li>If one of arguments is <code>float</code>, converts the other one to <code>float</code></li>\n  <li>If one of arguments is <code>long</code>, converts the other one to <code>long</code></li>\n  <li>Otherwise (in case of <code>byte</code>, <code>char</code>, or <code>short</code>) converts both arguments to <code>int</code></li>\n</ol>\n",
 			 "example", "plus 10 3 | equals 13 | verify-true\nint 8 | plus 2 | equals 10 | assert-true \"8 + 2 not equals 10!\""
-		   });	
+		   });
 		addAnnotation
-		  (minusEClass, 
-		   source, 
+		  (minusEClass,
+		   source,
 		   new String[] {
 			 "description", "<p>returns <code>left - right</code></p>\n<p>Before performing an operation, arguments are converted to the widest type according to the following rules:</p>\n<ol>\n  <li><code>string</code> arguments converted to <code>long</code></li>\n  <li><code>boolean</code> arguments converted to <code>long</code> (1 for <code>true</code> and 0 for <code>false</code>)</li>\n  <li>If one of arguments is <code>double</code>, converts the other one to <code>double</code></li>\n  <li>If one of arguments is <code>float</code>, converts the other one to <code>float</code></li>\n  <li>If one of arguments is <code>long</code>, converts the other one to <code>long</code></li>\n  <li>Otherwise (in case of <code>byte</code>, <code>char</code>, or <code>short</code>) converts both arguments to <code>int</code></li>\n</ol>\n",
 			 "example", "minus 8 5 | equals 3 | verify-true"
-		   });	
+		   });
 		addAnnotation
-		  (divEClass, 
-		   source, 
+		  (divEClass,
+		   source,
 		   new String[] {
 			 "description", "<p>returns <code>left / right</code></p>\n<p>Before performing an operation, arguments are converted to the widest type according to the following rules:</p>\n<ol>\n  <li><code>string</code> arguments converted to <code>long</code></li>\n  <li><code>boolean</code> arguments converted to <code>long</code> (1 for <code>true</code> and 0 for <code>false</code>)</li>\n  <li>If one of arguments is <code>double</code>, converts the other one to <code>double</code></li>\n  <li>If one of arguments is <code>float</code>, converts the other one to <code>float</code></li>\n  <li>If one of arguments is <code>long</code>, converts the other one to <code>long</code></li>\n  <li>Otherwise (in case of <code>byte</code>, <code>char</code>, or <code>short</code>) converts both arguments to <code>int</code></li>\n</ol>\n",
 			 "example", "div 10 5 | equals 2 | assert-true -message \"10/5 not equals 2!\""
-		   });	
+		   });
 		addAnnotation
-		  (multEClass, 
-		   source, 
+		  (multEClass,
+		   source,
 		   new String[] {
 			 "description", "<p>returns <code>left * right</code></p>\n<p>Before performing an operation, arguments are converted to the widest type according to the following rules:</p>\n<ol>\n  <li><code>string</code> arguments converted to <code>long</code></li>\n  <li><code>boolean</code> arguments converted to <code>long</code> (1 for <code>true</code> and 0 for <code>false</code>)</li>\n  <li>If one of arguments is <code>double</code>, converts the other one to <code>double</code></li>\n  <li>If one of arguments is <code>float</code>, converts the other one to <code>float</code></li>\n  <li>If one of arguments is <code>long</code>, converts the other one to <code>long</code></li>\n  <li>Otherwise (in case of <code>byte</code>, <code>char</code>, or <code>short</code>) converts both arguments to <code>int</code></li>\n</ol>\n",
 			 "example", "mult 5 7 | equals 35 | verify-true"
-		   });	
+		   });
 		addAnnotation
-		  (absEClass, 
-		   source, 
+		  (absEClass,
+		   source,
 		   new String[] {
 			 "description", "<p>returns <code>java.lang.Math.abs(arg)</code></p>\n<p>The return type of an operation is determined by the following rules:</p>\n<ol>\n  <li><code>string</code> arg is converted to <code>long</code></li>\n  <li><code>boolean</code> arg is converted to <code>long</code> (1 for <code>true</code> and 0 for <code>false</code>)</li>\n  <li><code>double</code>, <code>float</code>, <code>long</code> args retain its original type</li>\n  <li>Otherwise (in case of <code>byte</code>, <code>char</code>, or <code>short</code>) the returned value has type <code>int</code></li>\n</ol>\n",
 			 "example", " emit \"-10.6\" | int | abs | str | log (writes 10 to  log)"
-		   });	
+		   });
 		addAnnotation
-		  (modEClass, 
-		   source, 
+		  (modEClass,
+		   source,
 		   new String[] {
 			 "description", "<p>returns <code>left % right</code></p>\n<p>Before performing an operation, arguments are converted to the widest type according to the following rules:</p>\n<ol>\n  <li><code>string</code> arguments converted to <code>long</code></li>\n  <li><code>boolean</code> arguments converted to <code>long</code> (1 for <code>true</code> and 0 for <code>false</code>)</li>\n  <li>If one of arguments is <code>double</code>, converts the other one to <code>double</code></li>\n  <li>If one of arguments is <code>float</code>, converts the other one to <code>float</code></li>\n  <li>If one of arguments is <code>long</code>, converts the other one to <code>long</code></li>\n  <li>Otherwise (in case of <code>byte</code>, <code>char</code>, or <code>short</code>) converts both arguments to <code>int</code></li>\n</ol>\n",
 			 "example", "mod 11 3 | equals 2 | verify-true"
-		   });	
+		   });
 		addAnnotation
-		  (betweenEClass, 
-		   source, 
+		  (betweenEClass,
+		   source,
 		   new String[] {
 			 "description", "<p>returns <code>true</code> if <code>input</code> is greater than or equal to <code>left</code> and less than or equal to <code>right</code></p>\n\n<p>Before performing an operation, arguments are converted according to the following rules:</p>\n<ol>\n  <li><code>string</code> arguments converted to <code>long</code></li>\n  <li><code>boolean</code> arguments converted to <code>long</code> (1 for <code>true</code> and 0 for <code>false</code>)</li>\n  <li>If one of arguments is <code>double</code>, converts the other one to <code>double</code></li>\n  <li>If one of arguments is <code>float</code>, converts the other one to <code>float</code></li>\n  <li>If one of arguments is <code>long</code>, converts the other one to <code>long</code></li>\n  <li>Otherwise (in case of <code>byte</code>, <code>char</code>, or <code>short</code>) converts both arguments to <code>int</code></li>\n</ol>\n",
 			 "example", "int 10 | between 7 12 | verify-true"
-		   });	
+		   });
 		addAnnotation
-		  (entryEClass, 
-		   source, 
+		  (entryEClass,
+		   source,
 		   new String[] {
 			 "description", "Creates a new map entry. Can only be used as an argument for <a href=\"#map\">map</a> command."
-		   });	
+		   });
 		addAnnotation
-		  (mapEClass, 
-		   source, 
+		  (mapEClass,
+		   source,
 		   new String[] {
 			 "description", "Creates a new map. Also see <a href=\"#get\">get</a> command to find a value by key.",
 			 "example", "let [val myMap [map \n   [entry firstName \"Ivan\"]\n   [entry lastName \"Inozemtsev\"]]] {\n   log [format \"%s %s\" [$myMap | get firstName] [$myMap | get lastName]]\n}"
-		   });	
+		   });
 		addAnnotation
-		  (getMap_Entries(), 
-		   source, 
+		  (getMap_Entries(),
+		   source,
 		   new String[] {
 			 "description", "An arbitrary number of <a href=\"#entry\">entries</a>."
-		   });	
+		   });
 		addAnnotation
-		  (listEClass, 
-		   source, 
+		  (listEClass,
+		   source,
 		   new String[] {
 			 "description", "Creates a new list. Also see <a href=\"#get\">get</a> command to find an element by index.",
 			 "example", "list January Febuary March | get 1 | equals \"Febuary\" | verify-true"
-		   });	
+		   });
 		addAnnotation
-		  (loopEClass, 
-		   source, 
+		  (loopEClass,
+		   source,
 		   new String[] {
 			 "description", "Executes recursive looping of a body. Allows to emulate \'while\' and \'for\' loops while preserving variable immutability. The idea is taken from Clojure\'s <a href=\"http://clojure.org/functional_programming#Functional%20Programming--Recursive%20Looping\">loop/recur</a> approach. Also see <a href=\"#recur\">recur</a> command.",
 			 "example", "// Example 1. returns how many times a 81 is divisible by 3\nloop [val count 0] [val n 81] {\n    if [mod $n 3 | eq 0] {\n        recur [$count | plus 1] [$n | div 3]\n    } -else {\n        log [format \"The answer is %d\" $count] //prints \'The answer is 4\'\n    }\n}\n\n\n// Example 2. deletes all elements from a tree\nproc \"get-my-tree\" { get-view \"My View\" | get-tree }\n\nproc \"has-elements\" {\n    get-my-tree | get-property itemCount -raw | int | gt 0\n}\n\nloop {\n    if [has-elements] {\n        // Selects a first top-level item and invokes \"Delete\" from context menu\n        get-my-tree | select \".*\" | get-menu \"Delete\" | click\n        // Confirms a removal in popup dialog\n        get-window \"Confirm Delete\" | get-button OK | click\n        // Continues execution from the beginning of loop body\n        recur\n    }\n}"
-		   });	
+		   });
 		addAnnotation
-		  (getLoop_Vals(), 
-		   source, 
+		  (getLoop_Vals(),
+		   source,
 		   new String[] {
 			 "description", "Valus which are going to be modified during iterations. All initial values must be set."
-		   });	
+		   });
 		addAnnotation
-		  (getLoop_Body(), 
-		   source, 
+		  (getLoop_Body(),
+		   source,
 		   new String[] {
 			 "description", "A script to execute. Whenever script invokes <a href=\"#recur\">recur</a> command, an execution jumps to the beginning of loop body script."
-		   });	
+		   });
 		addAnnotation
-		  (recurEClass, 
-		   source, 
+		  (recurEClass,
+		   source,
 		   new String[] {
 			 "description", "Returns an execution to the beginning of <a href=\"#loop\">loop</a> command. Cannot be used outside of a loop.",
 			 "example", "// calc and show a sum of ints from 3 to 10\n\nloop [val result 0] [val i 3] {\n    if [$i | eq 10] {\n        show-alert [str [$result | plus $i]]\n    } -else {\n        recur [$result | plus $i] [$i | plus 1]\n    }\n}"
-		   });	
+		   });
 		addAnnotation
-		  (getRecur_Values(), 
-		   source, 
+		  (getRecur_Values(),
+		   source,
 		   new String[] {
 			 "description", "A list of new values for variables, declared in <code>loop</code> command. Value count must exactly match to corresponding val count of a <code>loop</code> command."
-		   });	
+		   });
 		addAnnotation
-		  (toListEClass, 
-		   source, 
+		  (toListEClass,
+		   source,
 		   new String[] {
 			 "description", "Loads whole input pipe and returns a single EclList object, containing it.",
 			 "example", "emit 1 2 3 | to-list // same as list 1 2 3\nemit 1 2 3 | to-list | to-list // same as list [list 1 2 3]"
-		   });	
+		   });
 		addAnnotation
-		  (eachEClass, 
-		   source, 
+		  (eachEClass,
+		   source,
 		   new String[] {
 			 "description", "Iterates over <a href=\"#list\">list</a> or <a href=\"#map\">map</a>. Accepts one or two variable declarations, when only one variable given, it will be hold list elements or map values. A second variable, if provided, used for map keys or list element indices.",
 			 "example", "// Iterate over elements.\nlist 1 2 3 | each [val element] {\n    log [format \"%d\" $element]\n}\n\n// Iterate over elements with indices\nlist 1 2 3 | each [val element] [val index] {\n    log [format \"list[%d] = %d\" $index $element]\n}\n\n// Iterate over map values\nmap [entry \"one\" 1] [entry \"two\" 2] | each [val value] { log [str $value] }\n\n// Iterate over map values with keys\nmap [entry \"one\" 1] [entry \"two\" 2] | each [val v] [val k] { log [concat $k \" = \" [str $v]] }"
-		   });	
+		   });
 		addAnnotation
-		  (getEach_Input(), 
-		   source, 
+		  (getEach_Input(),
+		   source,
 		   new String[] {
 			 "description", "Map or List"
-		   });	
+		   });
 		addAnnotation
-		  (splitEClass, 
-		   source, 
+		  (splitEClass,
+		   source,
 		   new String[] {
 			 "description", "",
 			 "example", "str \"1, 2, 3, 4, 5\" | split -sep \",\" -trimResults | foreach [val item]{\n\t$item | log\n}\n"
-		   });	
+		   });
 		addAnnotation
-		  (parseTimeEClass, 
-		   source, 
+		  (parseTimeEClass,
+		   source,
 		   new String[] {
 			 "description", "Reads a string from input pipe and parses it accoridng to a given format string.",
 			 "returns", "Timestamp value (as a number of milliseconds since January, 1, 1970)"
-		   });	
+		   });
 		addAnnotation
-		  (getParseTime_Input(), 
-		   source, 
+		  (getParseTime_Input(),
+		   source,
 		   new String[] {
 			 "description", "String representation of date."
-		   });	
+		   });
 		addAnnotation
-		  (throwErrorEClass, 
-		   source, 
+		  (throwErrorEClass,
+		   source,
 		   new String[] {
 			 "description", "Fails with specified error message",
 			 "example", "throw-error \"Test Case has one or more failed verifications\""
-		   });	
+		   });
 		addAnnotation
-		  (getThrowError_Message(), 
-		   source, 
+		  (getThrowError_Message(),
+		   source,
 		   new String[] {
 			 "description", "Error message"
 		   });
+		addAnnotation
+		  (findAllEClass,
+		   source,
+		   new String[] {
+			 "description", "",
+			 "example", ""
+		   });
 	}
 
 	/**
@@ -2090,70 +2142,75 @@
 	 * @generated
 	 */
 	protected void createInputAnnotations() {
-		String source = "http://www.eclipse.org/ecl/input";	
+		String source = "http://www.eclipse.org/ecl/input";
 		addAnnotation
-		  (getEq_Left(), 
-		   source, 
+		  (getEq_Left(),
+		   source,
 		   new String[] {
-		   });	
+		   });
 		addAnnotation
-		  (getConvert_Input(), 
-		   source, 
+		  (getConvert_Input(),
+		   source,
 		   new String[] {
-		   });	
+		   });
 		addAnnotation
-		  (getAssertTrue_Input(), 
-		   source, 
+		  (getAssertTrue_Input(),
+		   source,
 		   new String[] {
-		   });	
+		   });
 		addAnnotation
-		  (getLength_Input(), 
-		   source, 
+		  (getLength_Input(),
+		   source,
 		   new String[] {
-		   });	
+		   });
 		addAnnotation
-		  (getNotEq_Left(), 
-		   source, 
+		  (getNotEq_Left(),
+		   source,
 		   new String[] {
-		   });	
+		   });
 		addAnnotation
-		  (getNot_Left(), 
-		   source, 
+		  (getNot_Left(),
+		   source,
 		   new String[] {
-		   });	
+		   });
 		addAnnotation
-		  (getRepeatWith_Commands(), 
-		   source, 
+		  (getRepeatWith_Commands(),
+		   source,
 		   new String[] {
-		   });	
+		   });
 		addAnnotation
-		  (getBinaryOp_Left(), 
-		   source, 
+		  (getBinaryOp_Left(),
+		   source,
 		   new String[] {
-		   });	
+		   });
 		addAnnotation
-		  (getAbs_Arg(), 
-		   source, 
+		  (getAbs_Arg(),
+		   source,
 		   new String[] {
-		   });	
+		   });
 		addAnnotation
-		  (getBetween_Input(), 
-		   source, 
+		  (getBetween_Input(),
+		   source,
 		   new String[] {
-		   });	
+		   });
 		addAnnotation
-		  (getEach_Input(), 
-		   source, 
+		  (getEach_Input(),
+		   source,
 		   new String[] {
-		   });	
+		   });
 		addAnnotation
-		  (getSplit_Str(), 
-		   source, 
+		  (getSplit_Str(),
+		   source,
 		   new String[] {
-		   });	
+		   });
 		addAnnotation
-		  (getParseTime_Input(), 
-		   source, 
+		  (getParseTime_Input(),
+		   source,
+		   new String[] {
+		   });
+		addAnnotation
+		  (getFindAll_Str(),
+		   source,
 		   new String[] {
 		   });
 	}
@@ -2165,10 +2222,10 @@
 	 * @generated
 	 */
 	protected void createInternalAnnotations() {
-		String source = "http://www.eclipse.org/ecl/internal";	
+		String source = "http://www.eclipse.org/ecl/internal";
 		addAnnotation
-		  (convertEClass, 
-		   source, 
+		  (convertEClass,
+		   source,
 		   new String[] {
 		   });
 	}
diff --git a/ecl/plugins/org.eclipse.rcptt.ecl.operations/gen-src/org/eclipse/rcptt/ecl/operations/util/OperationsAdapterFactory.java b/ecl/plugins/org.eclipse.rcptt.ecl.operations/gen-src/org/eclipse/rcptt/ecl/operations/util/OperationsAdapterFactory.java
index e89d798..eb73903 100644
--- a/ecl/plugins/org.eclipse.rcptt.ecl.operations/gen-src/org/eclipse/rcptt/ecl/operations/util/OperationsAdapterFactory.java
+++ b/ecl/plugins/org.eclipse.rcptt.ecl.operations/gen-src/org/eclipse/rcptt/ecl/operations/util/OperationsAdapterFactory.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2014 Xored Software Inc and others.
+ * Copyright (c) 2009, 2014, 2018 Xored Software Inc and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -30,6 +30,7 @@
 import org.eclipse.rcptt.ecl.operations.Emit;
 import org.eclipse.rcptt.ecl.operations.Entry;
 import org.eclipse.rcptt.ecl.operations.Eq;
+import org.eclipse.rcptt.ecl.operations.FindAll;
 import org.eclipse.rcptt.ecl.operations.Format;
 import org.eclipse.rcptt.ecl.operations.FormatTime;
 import org.eclipse.rcptt.ecl.operations.GetTime;
@@ -284,6 +285,10 @@
 				return createThrowErrorAdapter();
 			}
 			@Override
+			public Adapter caseFindAll(FindAll object) {
+				return createFindAllAdapter();
+			}
+			@Override
 			public Adapter caseCommand(Command object) {
 				return createCommandAdapter();
 			}
@@ -898,6 +903,20 @@
 	}
 
 	/**
+	 * Creates a new adapter for an object of class '{@link org.eclipse.rcptt.ecl.operations.FindAll <em>Find All</em>}'.
+	 * <!-- begin-user-doc -->
+	 * This default implementation returns null so that we can easily ignore cases;
+	 * it's useful to ignore a case when inheritance will catch all the cases anyway.
+	 * <!-- end-user-doc -->
+	 * @return the new adapter.
+	 * @see org.eclipse.rcptt.ecl.operations.FindAll
+	 * @generated
+	 */
+	public Adapter createFindAllAdapter() {
+		return null;
+	}
+
+	/**
 	 * Creates a new adapter for an object of class ' {@link org.eclipse.rcptt.ecl.operations.BinaryOp <em>Binary Op</em>}'.
 	 * <!--
 	 * begin-user-doc --> This default implementation returns null so that we
diff --git a/ecl/plugins/org.eclipse.rcptt.ecl.operations/gen-src/org/eclipse/rcptt/ecl/operations/util/OperationsSwitch.java b/ecl/plugins/org.eclipse.rcptt.ecl.operations/gen-src/org/eclipse/rcptt/ecl/operations/util/OperationsSwitch.java
index 9441c1d..0fb561b 100644
--- a/ecl/plugins/org.eclipse.rcptt.ecl.operations/gen-src/org/eclipse/rcptt/ecl/operations/util/OperationsSwitch.java
+++ b/ecl/plugins/org.eclipse.rcptt.ecl.operations/gen-src/org/eclipse/rcptt/ecl/operations/util/OperationsSwitch.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2014 Xored Software Inc and others.
+ * Copyright (c) 2009, 2014, 2018 Xored Software Inc and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -30,6 +30,7 @@
 import org.eclipse.rcptt.ecl.operations.Emit;
 import org.eclipse.rcptt.ecl.operations.Entry;
 import org.eclipse.rcptt.ecl.operations.Eq;
+import org.eclipse.rcptt.ecl.operations.FindAll;
 import org.eclipse.rcptt.ecl.operations.Format;
 import org.eclipse.rcptt.ecl.operations.FormatTime;
 import org.eclipse.rcptt.ecl.operations.GetTime;
@@ -440,6 +441,13 @@
 				if (result == null) result = defaultCase(theEObject);
 				return result;
 			}
+			case OperationsPackage.FIND_ALL: {
+				FindAll findAll = (FindAll)theEObject;
+				T result = caseFindAll(findAll);
+				if (result == null) result = caseCommand(findAll);
+				if (result == null) result = defaultCase(theEObject);
+				return result;
+			}
 			default: return defaultCase(theEObject);
 		}
 	}
@@ -1076,6 +1084,21 @@
 	}
 
 	/**
+	 * Returns the result of interpreting the object as an instance of '<em>Find All</em>'.
+	 * <!-- begin-user-doc -->
+	 * This implementation returns null;
+	 * returning a non-null result will terminate the switch.
+	 * <!-- end-user-doc -->
+	 * @param object the target of the switch.
+	 * @return the result of interpreting the object as an instance of '<em>Find All</em>'.
+	 * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject)
+	 * @generated
+	 */
+	public T caseFindAll(FindAll object) {
+		return null;
+	}
+
+	/**
 	 * Returns the result of interpreting the object as an instance of '<em>Binary Op</em>'.
 	 * <!-- begin-user-doc --> This implementation returns
 	 * null; returning a non-null result will terminate the switch. <!--
diff --git a/ecl/plugins/org.eclipse.rcptt.ecl.operations/model/operations.ecore b/ecl/plugins/org.eclipse.rcptt.ecl.operations/model/operations.ecore
index 52d95b1..91fc368 100644
--- a/ecl/plugins/org.eclipse.rcptt.ecl.operations/model/operations.ecore
+++ b/ecl/plugins/org.eclipse.rcptt.ecl.operations/model/operations.ecore
@@ -475,4 +475,15 @@
       </eAnnotations>
     </eStructuralFeatures>
   </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="FindAll" eSuperTypes="../../org.eclipse.rcptt.ecl.core/model/ecl.ecore#//Command">
+    <eAnnotations source="http://www.eclipse.org/ecl/docs">
+      <details key="description" value="Returns all non-overlapping matches of regex in str with substrings captured by the groups"/>
+      <details key="example" value="find-all &quot;one 1 two 2 three 3&quot; &quot;(\\w+)\\W+(\\d+)&quot; | to-list | each [val groups] {&#xA;&#x9;$groups | get 0 | log&#xA;}"/>
+      <details key="returns" value="Lists of the match for a regex and substrings captured by the groups"/>
+    </eAnnotations>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="str" eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EString">
+      <eAnnotations source="http://www.eclipse.org/ecl/input"/>
+    </eStructuralFeatures>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="regex" eType="ecore:EDataType platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore#//EString"/>
+  </eClassifiers>
 </ecore:EPackage>
diff --git a/ecl/plugins/org.eclipse.rcptt.ecl.operations/model/operations.genmodel b/ecl/plugins/org.eclipse.rcptt.ecl.operations/model/operations.genmodel
index 266847d..a1792d9 100644
--- a/ecl/plugins/org.eclipse.rcptt.ecl.operations/model/operations.genmodel
+++ b/ecl/plugins/org.eclipse.rcptt.ecl.operations/model/operations.genmodel
@@ -40,6 +40,8 @@
       <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference operations.ecore#//Try/finally"/>
       <genFeatures createChild="false" ecoreFeature="ecore:EAttribute operations.ecore#//Try/times"/>
       <genFeatures createChild="false" ecoreFeature="ecore:EAttribute operations.ecore#//Try/delay"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute operations.ecore#//Try/noScreenshot"/>
+      <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference operations.ecore#//Try/error"/>
     </genClasses>
     <genClasses ecoreClass="operations.ecore#//Format">
       <genFeatures createChild="false" ecoreFeature="ecore:EAttribute operations.ecore#//Format/format"/>
@@ -128,5 +130,12 @@
       <genFeatures createChild="false" ecoreFeature="ecore:EAttribute operations.ecore#//ParseTime/input"/>
       <genFeatures createChild="false" ecoreFeature="ecore:EAttribute operations.ecore#//ParseTime/format"/>
     </genClasses>
+    <genClasses ecoreClass="operations.ecore#//ThrowError">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute operations.ecore#//ThrowError/message"/>
+    </genClasses>
+    <genClasses ecoreClass="operations.ecore#//FindAll">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute operations.ecore#//FindAll/str"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute operations.ecore#//FindAll/regex"/>
+    </genClasses>
   </genPackages>
 </genmodel:GenModel>
diff --git a/ecl/plugins/org.eclipse.rcptt.ecl.operations/plugin.xml b/ecl/plugins/org.eclipse.rcptt.ecl.operations/plugin.xml
index f35eb46..f4751b5 100644
--- a/ecl/plugins/org.eclipse.rcptt.ecl.operations/plugin.xml
+++ b/ecl/plugins/org.eclipse.rcptt.ecl.operations/plugin.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <?eclipse version="3.4"?>
 <!--
-    Copyright (c) 2009, 2016 Xored Software Inc and others.
+    Copyright (c) 2009, 2016, 2018 Xored Software Inc and others.
     All rights reserved. This program and the accompanying materials
     are made available under the terms of the Eclipse Public License v1.0
     which accompanies this distribution, and is available at
@@ -231,6 +231,11 @@
             name="ThrowError"
             namespace="http://www.eclipse.org/ecl/operations.ecore">
       </scriptlet>
+      <scriptlet
+            class="org.eclipse.rcptt.ecl.operations.internal.commands.FindAllService"
+            name="FindAll"
+            namespace="http://www.eclipse.org/ecl/operations.ecore">
+      </scriptlet>
    </extension>
    <extension
          point="org.eclipse.rcptt.ecl.dispatch.scriptletExtension">
diff --git a/ecl/plugins/org.eclipse.rcptt.ecl.operations/src/org/eclipse/rcptt/ecl/operations/internal/commands/FindAllService.java b/ecl/plugins/org.eclipse.rcptt.ecl.operations/src/org/eclipse/rcptt/ecl/operations/internal/commands/FindAllService.java
new file mode 100644
index 0000000..5ab2dec
--- /dev/null
+++ b/ecl/plugins/org.eclipse.rcptt.ecl.operations/src/org/eclipse/rcptt/ecl/operations/internal/commands/FindAllService.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2018 Xored Software Inc and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Xored Software Inc - initial API and implementation and/or initial documentation
+ *******************************************************************************/
+package org.eclipse.rcptt.ecl.operations.internal.commands;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.rcptt.ecl.core.Command;
+import org.eclipse.rcptt.ecl.core.CoreFactory;
+import org.eclipse.rcptt.ecl.core.EclList;
+import org.eclipse.rcptt.ecl.operations.FindAll;
+import org.eclipse.rcptt.ecl.runtime.BoxedValues;
+import org.eclipse.rcptt.ecl.runtime.ICommandService;
+import org.eclipse.rcptt.ecl.runtime.IProcess;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import static org.eclipse.rcptt.ecl.operations.internal.OperationsPlugin.createErr;
+
+public class FindAllService implements ICommandService {
+	@Override
+	public IStatus service(Command command, IProcess context) throws InterruptedException, CoreException {
+		if (!(command instanceof FindAll)) {
+			return Status.CANCEL_STATUS;
+		}
+
+		final FindAll findAll = (FindAll) command;
+		final String input = findAll.getStr();
+		final String regex = findAll.getRegex();
+
+		int regexLength = regex.length();
+		if (regexLength == 0) {
+			throw new CoreException(createErr("Empty regex is not allowed"));
+		}
+		final Pattern pattern = Pattern.compile(regex);
+		final Matcher matcher = pattern.matcher(input);
+
+		while (matcher.find()) {
+			final EclList result = CoreFactory.eINSTANCE.createEclList();
+
+			for (int i = 0; i <= matcher.groupCount(); ++i) {
+				result.getElements().add(BoxedValues.box(matcher.group(i)));
+			}
+
+			context.getOutput().write(result);
+		}
+
+		return Status.OK_STATUS;
+	}
+}
diff --git a/ecl/tests/org.eclipse.rcptt.ecl.operations.tests/src/org/eclipse/rcptt/ecl/operations/tests/FindAllTest.java b/ecl/tests/org.eclipse.rcptt.ecl.operations.tests/src/org/eclipse/rcptt/ecl/operations/tests/FindAllTest.java
new file mode 100644
index 0000000..f94148b
--- /dev/null
+++ b/ecl/tests/org.eclipse.rcptt.ecl.operations.tests/src/org/eclipse/rcptt/ecl/operations/tests/FindAllTest.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2018 Xored Software Inc and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Xored Software Inc - initial API and implementation and/or initial documentation
+ *******************************************************************************/
+package org.eclipse.rcptt.ecl.operations.tests;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.rcptt.ecl.parser.test.TestWithSession;
+import org.junit.Test;
+
+public class FindAllTest extends TestWithSession {
+
+	@Test
+	public void testMatchedSubstring() throws CoreException {
+		runScript("find-all \"one 1 two 2 three 3\" -regex \"(\\w+)\\W+(\\d+)\" | to-list | get 1 | get 0 | eq \"two 2\" | assert-true");
+	}
+
+	@Test
+	public void testGroups() throws CoreException {
+		runScript("find-all \"one 1 two 2 three 3\" -regex \"(\\w+)\\W+(\\d+)\" | to-list | get 2 | get 2 | eq \"3\" | assert-true");
+	}
+
+	@Test
+	public void testFindAllFail() {
+		try {
+			runScript("find-all \"one 1 two 2 three 3\" -regex \"\" | to-list | get 2 | get 2");
+		} catch (CoreException e) {
+			assertEquals("Empty regex is not allowed", e.getStatus().getMessage());
+			return;
+		}
+		fail();
+	}
+
+}