private bool evalIsExpression_WithAliases(IsExpression isExpression, AbstractType typeToCheck)
		{
			/*
			 * Note: It's needed to let the abstract ast scanner also scan through IsExpressions etc.
			 * in order to find aliases and/or specified template parameters!
			 */

			var expectedTemplateParams = new TemplateParameter[isExpression.TemplateParameterList.Length + 1];
			expectedTemplateParams [0] = isExpression.ArtificialFirstSpecParam;
			if(expectedTemplateParams.Length > 1)
				isExpression.TemplateParameterList.CopyTo (expectedTemplateParams, 1);

			var tpl_params = new DeducedTypeDictionary(expectedTemplateParams);


			var tpd = new TemplateParameterDeduction(tpl_params, ctxt);
			bool retTrue = false;

			if (isExpression.EqualityTest) // 6.
			{
				// a)
				if (isExpression.TypeSpecialization != null)
				{
					tpd.EnforceTypeEqualityWhenDeducing = true;
					retTrue = tpd.Handle(isExpression.ArtificialFirstSpecParam, typeToCheck);
					tpd.EnforceTypeEqualityWhenDeducing = false;
				}
				else // b)
				{
					var r = evalIsExpression_EvalSpecToken(isExpression, typeToCheck, true);
					retTrue = r.Item1;
					tpl_params[isExpression.TypeAliasIdentifierHash] = new TemplateParameterSymbol(null, r.Item2);
				}
			}
			else // 5.
				retTrue = tpd.Handle(isExpression.ArtificialFirstSpecParam, typeToCheck);

			if (retTrue && isExpression.TemplateParameterList != null)
				foreach (var p in isExpression.TemplateParameterList)
					if (!tpd.Handle(p, tpl_params[p.NameHash] != null ? tpl_params[p.NameHash].Base : null))
						return false;

			//TODO: Put all tpl_params results into the resolver context or make a new scope or something! 

			return retTrue;
		}
		ISemantic E(PostfixExpression_MethodCall call, bool returnBaseTypeOnly=true)
		{
			// Deduce template parameters later on
			AbstractType[] baseExpression;
			ISymbolValue baseValue;
			TemplateInstanceExpression tix;
			
			GetRawCallOverloads(call, out baseExpression, out baseValue, out tix);

			var methodOverloads = new List<AbstractType>();

			#region Search possible methods, opCalls or delegates that could be called
			bool requireStaticItems = true; //TODO: What if there's an opCall and a foreign method at the same time? - and then this variable would be bullshit
			IEnumerable<AbstractType> scanResults = DResolver.StripAliasSymbols(baseExpression);
			var nextResults = new List<AbstractType>();

			while (scanResults != null)
			{
				foreach (var b in scanResults)
				{
					if (b is MemberSymbol)
					{
						var mr = (MemberSymbol)b;

						if (mr.Definition is DMethod)
						{
							methodOverloads.Add(mr);
							continue;
						}
						else if (mr.Definition is DVariable)
						{
							// If we've got a variable here, get its base type/value reference
							if (eval)
							{
								var dgVal = ValueProvider[(DVariable)mr.Definition] as DelegateValue;

								if (dgVal != null)
								{
									nextResults.Add(dgVal.Definition);
									continue;
								}
								else{
									EvalError(call, "Variable must be a delegate, not anything else", mr);
									return null;
								}
							}
							else
							{
								var bt = DResolver.StripAliasSymbol(mr.Base ?? TypeDeclarationResolver.ResolveSingle(mr.Definition.Type, ctxt));

								// Must be of type delegate
								if (bt is DelegateType)
								{
									//TODO: Ensure that there's no further overload - inform the user elsewise

									if (returnBaseTypeOnly)
										return bt;
									else
										return new MemberSymbol(mr.Definition, bt, mr.DeclarationOrExpressionBase);
								}
								else
								{
									/*
									 * If mr.Node is not a method, so e.g. if it's a variable
									 * pointing to a delegate
									 * 
									 * class Foo
									 * {
									 *	string opCall() {  return "asdf";  }
									 * }
									 * 
									 * Foo f=new Foo();
									 * f(); -- calls opCall, opCall is not static
									 */
									nextResults.Add(bt);
									requireStaticItems = false;
								}
								//TODO: Can other types work as function/are callable?
							}
						}
					}
					else if (b is DelegateType)
					{
						var dg = (DelegateType)b;

						/*
						 * int a = delegate(x) { return x*2; } (12); // a is 24 after execution
						 * auto dg=delegate(x) {return x*3;};
						 * int b = dg(4);
						 */

						if (dg.IsFunctionLiteral)
							methodOverloads.Add(dg);
						else
						{
							// If it's just wanted to pass back the delegate's return type, skip the remaining parts of this method.
							if (eval) {
								EvalError(call, "TODO", dg);
								return null;
							}
							//TODO
							//if(returnBaseTypeOnly)
							//TODO: Check for multiple definitions. Also, make a parameter-argument check to inform the user about wrong arguments.
							return dg;
						}
					}
					else if (b is ClassType || b is StructType)
					{
						var tit = (TemplateIntermediateType)b;
						/*
						 * auto a = MyStruct(); -- opCall-Overloads can be used
						 */
						var classDef = tit.Definition;

						if (classDef == null)
							continue;

						foreach (var i in GetOpCalls(tit, requireStaticItems))
								methodOverloads.Add(TypeDeclarationResolver.HandleNodeMatch(i, ctxt, b, call) as MemberSymbol);

						/*
						 * Every struct can contain a default ctor:
						 * 
						 * struct S { int a; bool b; }
						 * 
						 * auto s = S(1,true); -- ok
						 * auto s2= new S(2,false); -- error, no constructor found!
						 */
						if (b is StructType && methodOverloads.Count == 0)
						{
							//TODO: Deduce parameters
							return b;
						}
					}

					/*
					 * If the overload is a template, it quite exclusively means that we'll handle a method that is the only
					 * child inside a template + that is named as the template.
					 */
					else if (b is TemplateType)
						methodOverloads.Add(b);
				}

				scanResults = nextResults.Count == 0 ? null : nextResults.ToArray();
				nextResults.Clear();
			}
			#endregion

			if (methodOverloads.Count == 0)
				return null;

			// Get all arguments' types
			var callArguments = new List<ISemantic>();
			bool hasNonFinalArgs = false;

			if (call.Arguments != null)
				foreach (var arg in call.Arguments)
					callArguments.Add(E(arg));

			#region If explicit template type args were given, try to associate them with each overload
			if (tix != null)
			{
				var args = TemplateInstanceHandler.PreResolveTemplateArgs(tix, ctxt, out hasNonFinalArgs);
				var deducedOverloads = TemplateInstanceHandler.DeduceParamsAndFilterOverloads(methodOverloads, args, true, ctxt, hasNonFinalArgs);
				methodOverloads.Clear();
				if(deducedOverloads != null)
					methodOverloads.AddRange(deducedOverloads);
			}
			#endregion

			#region Filter by parameter-argument comparison
			var argTypeFilteredOverloads = new List<AbstractType>();
			bool hasHandledUfcsResultBefore = false;
			
			foreach (var ov in methodOverloads)
			{
				if (ov is MemberSymbol)
				{
					var ms = ov as MemberSymbol;
					var dm = ms.Definition as DMethod;

					if (dm != null)
					{
						// In the case of an ufcs, insert the first argument into the CallArguments list
						if (ms.IsUFCSResult && !hasHandledUfcsResultBefore)
						{
							callArguments.Insert(0, eval ? baseValue as ISemantic : ((MemberSymbol)baseExpression[0]).FirstArgument);
							hasHandledUfcsResultBefore = true;
						}
						else if (!ms.IsUFCSResult && hasHandledUfcsResultBefore) // In the rare case of having a ufcs result occuring _after_ a normal member result, remove the initial arg again
						{
							callArguments.RemoveAt(0);
							hasHandledUfcsResultBefore = false;
						}
						
						var deducedTypeDict = new DeducedTypeDictionary(ms);
						if(dm.TemplateParameters != null)
							foreach(var tpar in dm.TemplateParameters)
								if(!deducedTypeDict.ContainsKey(tpar.NameHash))
									deducedTypeDict[tpar.NameHash] = null;
						var templateParamDeduction = new TemplateParameterDeduction(deducedTypeDict, ctxt);

						int currentArg = 0;
						bool add = true;
						if (callArguments.Count > 0 || dm.Parameters.Count > 0)
							for (int i=0; i< dm.Parameters.Count; i++)
							{
								var paramType = dm.Parameters[i].Type;

								// Handle the usage of tuples: Tuples may only be used as as-is, so not as an array, pointer or in a modified way..
								if (paramType is IdentifierDeclaration &&
									TryHandleMethodArgumentTuple(ref add, callArguments, dm, deducedTypeDict, i, ref currentArg))
									continue;
								else if (currentArg < callArguments.Count)
								{
									if (!templateParamDeduction.HandleDecl(null, paramType, callArguments[currentArg++]))
									{
										add = false;
										break;
									}
								}
								else
								{
									// If there are more parameters than arguments given, check if the param has default values
									if (!(dm.Parameters[i] is DVariable) || (dm.Parameters[i] as DVariable).Initializer == null)
									{
										add = false;
										break;
									}
									// Assume that all further method parameters do have default values - and don't check further parameters
									break;
								}
							}

						// If type params were unassigned, try to take the defaults
						if (add && dm.TemplateParameters != null)
						{
							foreach (var tpar in dm.TemplateParameters)
							{
								if (deducedTypeDict[tpar.NameHash] == null)
								{
									add = templateParamDeduction.Handle(tpar, null);
									if (!add)
									{
										if (hasNonFinalArgs)
										{
											deducedTypeDict[tpar.NameHash] = new TemplateParameterSymbol(tpar, null);
											add = true;
										}
										else
											break;
									}
								}
							}
						}

						if (add && (deducedTypeDict.AllParamatersSatisfied || hasNonFinalArgs))
						{
							ms.DeducedTypes = deducedTypeDict.ToReadonly();
							ctxt.CurrentContext.IntroduceTemplateParameterTypes(ms);

							var bt=ms.Base ?? TypeDeclarationResolver.GetMethodReturnType(dm, ctxt);

							ctxt.CurrentContext.RemoveParamTypesFromPreferredLocals(ms);

							if(eval || !returnBaseTypeOnly)
								argTypeFilteredOverloads.Add(ms.Base == null ? new MemberSymbol(dm, bt, ms.DeclarationOrExpressionBase, ms.DeducedTypes) : ms);
							else
								argTypeFilteredOverloads.Add(bt);
						}
					}
				}
				else if(ov is DelegateType)
				{
					var dg = (DelegateType)ov;
					var bt = TypeDeclarationResolver.GetMethodReturnType(dg, ctxt);

					//TODO: Param-Arg check
						
					if (!eval || returnBaseTypeOnly)
						argTypeFilteredOverloads.Add(bt);
					else
						argTypeFilteredOverloads.Add(new DelegateType(bt, dg.DeclarationOrExpressionBase as FunctionLiteral, dg.Parameters));
				}
			}
			#endregion

			if (eval)
			{
				// Convert ISemantic[] to ISymbolValue[]
				var args = new List<ISymbolValue>(callArguments.Count);

				foreach (var a in callArguments)
					args.Add(a as ISymbolValue);

				// Execute/Evaluate the variable contents etc.
				return TryDoCTFEOrGetValueRefs(argTypeFilteredOverloads.ToArray(), call.PostfixForeExpression, true, args.ToArray());
			}
			else
			{
				// Check if one overload remains and return that one.
				ctxt.CheckForSingleResult(argTypeFilteredOverloads.ToArray(), call);
				return argTypeFilteredOverloads.Count != 0 ? argTypeFilteredOverloads[0] : null;
			}
		}