public boolean resolveArguments(ActivityExecutor executor,
			Map<String, Object> argumentValues,
			Location resultLocation,
			int startIndex) {
		boolean sync = true;

		List<RuntimeArgument> runtimeArguments = this.getActivity().getRuntimeArguments();
		int argumentCount = runtimeArguments.size();

		if (argumentCount == 0)
			return sync;

		ActivityContext resolutionContext = new ActivityContext(this, executor);

		for (int i = startIndex; i < argumentCount; i++) {
			RuntimeArgument argument = runtimeArguments.get(i);

			Object value = null;
			if (argumentValues != null)
				value = argumentValues.get(argument.getName());

			// try fast-path
			if (!argument.tryPopuateValue(this.getEnvironment(), this, resolutionContext, value, resultLocation)) {
				sync = false;
				int next = i + 1;
				// if have one more argument, should resume argument resolution after current expression scheduled
				if (next < runtimeArguments.size()) {
					ResolveNextArgumentWorkItem workItem = executor.ResolveNextArgumentWorkItemPool.acquire();
					// NOTE looks confused that still pass resultLocation,
					// but only used when resultArgument and the activtiy must be activityWithResult
					workItem.initialize(this, next, argumentValues, resultLocation);
					executor.scheduleItem(workItem);
				}
				// schedule argument expression
				executor.scheduleExpression(
						argument.getBoundArgument().getExpression(),
						this,
						resolutionContext.getEnvironment(),
						// FIXME should not direct use real Location, use Referencelocation
						this.getEnvironment().getLocation(argument.getId()));
				// must break, different from variables
				break;
			}
		}

		if (sync && startIndex == 0)
			this.subState = SubState.ResolvingVariables;

		return sync;
	}