/*******************************************************************************
 * Copyright (c) 2014 itemis AG (http://www.itemis.eu) 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
 *******************************************************************************/
package org.eclipse.xtext.formatting2.regionaccess.internal;

import java.util.List;

import org.eclipse.emf.ecore.EObject;
import org.eclipse.xtext.formatting2.regionaccess.IAstRegion;
import org.eclipse.xtext.formatting2.regionaccess.IEObjectRegion;
import org.eclipse.xtext.formatting2.regionaccess.IHiddenRegion;
import org.eclipse.xtext.formatting2.regionaccess.ISemanticRegion;
import org.eclipse.xtext.formatting2.regionaccess.ISemanticRegionFinder;
import org.eclipse.xtext.formatting2.regionaccess.ISemanticRegionsFinder;
import org.eclipse.xtext.formatting2.regionaccess.ISequentialRegion;
import org.eclipse.xtext.formatting2.regionaccess.ITextRegionAccess;

import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;

/**
 * @author Moritz Eysholdt - Initial contribution and API
 */
public abstract class AbstractEObjectRegion extends AbstractTextSegment implements IEObjectRegion {
	private final ITextRegionAccess access;
	private final List<IAstRegion> children = Lists.newArrayList();
	private EObject grammarElement;
	private IHiddenRegion nextHidden;
	private IHiddenRegion previousHidden;
	private EObject semanticElement;

	public AbstractEObjectRegion(AbstractRegionAccess access) {
		super();
		this.access = access;
	}

	protected void addChild(IAstRegion astRegion) {
		this.children.add(astRegion);
	}

	@Override
	public ISemanticRegionsFinder getAllRegionsFor() {
		return new SemanticRegionInIterableFinder(getAllSemanticRegions());
	}

	@Override
	public Iterable<ISemanticRegion> getAllSemanticRegions() {
		ISemanticRegion first = previousHidden.getNextSemanticRegion();
		ISemanticRegion last = nextHidden.getPreviousSemanticRegion();
		return new SemanticRegionIterable(first, last);
	}

	@Override
	public Iterable<IAstRegion> getAstRegions() {
		return children;
	}

	@Override
	public EObject getGrammarElement() {
		return grammarElement;
	}

	public IHiddenRegion getLeadingHiddenRegion() {
		return previousHidden;
	}

	@Override
	public int getLength() {
		return nextHidden.getOffset() - getOffset();
	}

	@Override
	public IHiddenRegion getNextHiddenRegion() {
		return nextHidden;
	}

	@Override
	public ISemanticRegion getNextSemanticRegion() {
		return nextHidden.getNextSemanticRegion();
	}

	@Override
	public ISequentialRegion getNextSequentialRegion() {
		return nextHidden;
	}

	@Override
	public int getOffset() {
		return previousHidden.getEndOffset();
	}

	@Override
	public IHiddenRegion getPreviousHiddenRegion() {
		return previousHidden;
	}

	@Override
	public ISemanticRegion getPreviousSemanticRegion() {
		return previousHidden.getPreviousSemanticRegion();
	}

	@Override
	public ISequentialRegion getPreviousSequentialRegion() {
		return previousHidden;
	}

	@Override
	public ISemanticRegionsFinder getRegionFor() {
		return new SemanticRegionInIterableFinder(getSemanticRegions());
	}

	@Override
	public EObject getSemanticElement() {
		return semanticElement;
	}

	@Override
	public Iterable<ISemanticRegion> getSemanticRegions() {
		return Iterables.filter(children, ISemanticRegion.class);
	}

	@Override
	public ITextRegionAccess getTextRegionAccess() {
		return access;
	}

	public IHiddenRegion getTrailingHiddenRegion() {
		return nextHidden;
	}

	@Override
	public ISemanticRegionFinder immediatelyFollowing() {
		return new SemanticRegionMatcher(getNextSemanticRegion());
	}

	@Override
	public ISemanticRegionFinder immediatelyPreceding() {
		return new SemanticRegionMatcher(getPreviousSemanticRegion());
	}

	protected void setGrammarElement(EObject grammarElement) {
		this.grammarElement = grammarElement;
	}

	protected void setLeadingHiddenRegion(IHiddenRegion leading) {
		this.previousHidden = leading;
	}

	protected void setSemanticElement(EObject semanticElement) {
		this.semanticElement = semanticElement;
	}

	protected void setTrailingHiddenRegion(IHiddenRegion trailing) {
		this.nextHidden = trailing;
	}

}
@@ -1736,32 +1736,29 @@
 cess;%0A%09%7D%0A%0A%09p
-rotected
+ublic
  void addChi

make AbstractEObjectRegion.addChild(IAstRegion) public