/*=============================================================================#
 # Copyright (c) 2008, 2020 Stephan Wahlbrink and others.
 # 
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License 2.0 which is available at
 # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
 # which is available at https://www.apache.org/licenses/LICENSE-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 # 
 # Contributors:
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.r.core.model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;

import com.ibm.icu.text.Collator;

import org.eclipse.statet.jcommons.lang.NonNull;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.jcommons.text.core.input.StringParserInput;

import org.eclipse.statet.ltk.core.ElementName;
import org.eclipse.statet.r.core.RSymbolComparator;
import org.eclipse.statet.r.core.data.RValueFormatter;
import org.eclipse.statet.r.core.rlang.RTerminal;
import org.eclipse.statet.r.core.rsource.RLexer;


/**
 * Base class for R element names
 * 
 * Defines type constants and provides static utility methods.
 */
@NonNullByDefault
public abstract class RElementName implements ElementName {
	
	
	public static final int RESOURCE=                       0x0_0f;
	
	public static final int MAIN_OTHER=                     0x0_10;
	public static final int MAIN_DEFAULT=                   0x0_11;
	public static final int MAIN_CLASS=                     0x0_15;
	
	public static final int SUB_NAMEDSLOT=                  0x0_19;
	public static final int SUB_NAMEDPART=                  0x0_1a;
	public static final int SUB_INDEXED_S=                  0x0_1b;
	public static final int SUB_INDEXED_D=                  0x0_1c;
	
	public static final int SCOPE_NS=                       0x0_21;
	public static final int SCOPE_NS_INT=                   0x0_22;
	
	public static final int SCOPE_SEARCH_ENV=               0x0_25;
	public static final int SCOPE_PACKAGE=                  0x0_26;
	public static final int SCOPE_SYSFRAME=                 0x0_27;
	public static final int SCOPE_PROJECT=                  0x0_29;
	
	public static final int ANONYMOUS=                      0x0_30;
	
	public static final int DISPLAY_FQN=                    1 << 0;
	public static final int DISPLAY_EXACT=                  1 << 1;
	
	
	public static boolean isMainType(final int type) {
		return (type >= MAIN_OTHER && type < SUB_NAMEDSLOT);
	}
	
	public static boolean isRegularMainType(final int type) {
		return (type > MAIN_OTHER && type < SUB_NAMEDSLOT);
	}
	
	public static boolean isScopeType(final int type) {
		return ((type & 0x0_F0) == 0x0_20);
	}
	
	public static boolean isNamespaceScopeType(final int type) {
		return (type >= SCOPE_NS && type < SCOPE_SEARCH_ENV);
	}
	
	public static boolean isSearchScopeType(final int type) {
		return (type >= SCOPE_SEARCH_ENV && type < ANONYMOUS);
	}
	
	public static boolean isPackageFacetScopeType(final int type) {
		switch (type) {
		case SCOPE_NS:
		case SCOPE_NS_INT:
		case SCOPE_PACKAGE:
			return true;
		default:
			return false;
		}
	}
	
	
	/**
	 * Element names providing the exact index as number (for SUB_INDEXED_D).
	 */
	public static interface IndexElementName extends ElementName {
		
		int getIndex();
		
	}
	
	@Deprecated // use #getDisplayName(int)
	public static @Nullable String createDisplayName(RElementName elementName, final int options) {
		if (elementName == null) {
			throw new NullPointerException("elementName"); //$NON-NLS-1$
		}
		RValueFormatter sb= null;
		
		if ((options & DISPLAY_FQN) != 0) {
			RElementName scopeName= elementName.getScope();
			if (scopeName == null && isScopeType(elementName.getType())) {
				scopeName= elementName;
				elementName= elementName.getNextSegment();
			}
			if (scopeName != null) {
				if (elementName != null && elementName.getType() != MAIN_DEFAULT) {
					return null;
				}
				sb= new RValueFormatter();
				if (!printScopeFQ(scopeName, sb, options, elementName != null)) {
					return null;
				}
				if (elementName != null) {
					final String name= elementName.getSegmentName();
					if (name != null) {
						appendSymbol(sb, name);
					}
					elementName= elementName.getNextSegment();
				}
			}
		}
		if (sb == null) {
			String firstName;
			final int type= elementName.getType();
			switch (type) {
			case MAIN_DEFAULT:
			case MAIN_CLASS:
			case SUB_NAMEDPART:
			case SUB_NAMEDSLOT:
				firstName= elementName.getSegmentName();
				if (firstName != null) {
					sb= appendSymbol(sb, firstName);
				}
				else if ((options & DISPLAY_EXACT) == 0) {
					firstName= ""; //$NON-NLS-1$
				}
				else {
					return null;
				}
				elementName= elementName.getNextSegment();
				if (elementName == null) {
					return (sb != null) ? sb.getString() : firstName;
				}
				if (sb == null) {
					sb= new RValueFormatter();
					sb.append(firstName);
				}
				break;
			case SCOPE_NS:
				if (elementName.getNextSegment() == null) {
					return printScopeUI("namespace:", elementName.getSegmentName(), options); //$NON-NLS-1$
				}
				else {
					printScopeFQ(elementName, sb, options, true);
					break;
				}
			case SCOPE_NS_INT:
				if (elementName.getNextSegment() == null) {
					return printScopeUI("namespace-env:", elementName.getSegmentName(), options); //$NON-NLS-1$
				}
				else {
					printScopeFQ(elementName, sb, options, true);
					break;
				}
			case SCOPE_SEARCH_ENV:
				if (elementName.getNextSegment() == null) {
					firstName= elementName.getSegmentName();
					if (firstName != null) {
						return firstName;
					}
				}
				return null;
			case SCOPE_SYSFRAME:
				if (elementName.getNextSegment() == null) {
					return printScopeUI("frame:", elementName.getSegmentName(), options); //$NON-NLS-1$
				}
				else {
					return null;
				}
			case SCOPE_PACKAGE:
				if (elementName.getNextSegment() == null) {
					return printScopeUI("package:", elementName.getSegmentName(), options); //$NON-NLS-1$
				}
				else {
					return null;
				}
			case SCOPE_PROJECT:
				if (elementName.getNextSegment() == null) {
					return printScopeUI("project:", elementName.getSegmentName(), options); //$NON-NLS-1$
				}
				else {
					return null;
				}
			case SUB_INDEXED_D:
				if (elementName instanceof DefaultImpl) {
					sb= new RValueFormatter();
					sb.append("[["); //$NON-NLS-1$
					sb.append(elementName.getSegmentName());
					sb.append("]]"); //$NON-NLS-1$
					elementName= elementName.getNextSegment();
					break;
				}
				return null;
			case RESOURCE:
			case MAIN_OTHER:
				return elementName.getSegmentName();
			case ANONYMOUS:
				if ((options & DISPLAY_EXACT) == 0) {
					return "<anonymous>"; //$NON-NLS-1$
				}
				else {
					return null;
				}
			default:
				return null;
			}
		}
		
		APPEND_SUB : while (elementName != null) {
			String name;
			switch (elementName.getType()) {
			case MAIN_DEFAULT:
			case MAIN_CLASS:
			case SUB_NAMEDPART:
				if (((options & DISPLAY_EXACT) != 0) && elementName instanceof IndexElementName) {
					sb.append("[["); //$NON-NLS-1$
					sb.appendInt(((IndexElementName) elementName).getIndex());
					sb.append("L]]"); //$NON-NLS-1$
				}
				else {
					sb.append('$');
					name= elementName.getSegmentName();
					if (name != null) {
						appendSymbol(sb, name);
					}
				}
				elementName= elementName.getNextSegment();
				continue APPEND_SUB;
			case SUB_NAMEDSLOT:
				sb.append('@');
				name= elementName.getSegmentName();
				if (name != null) {
					appendSymbol(sb, name);
				}
				elementName= elementName.getNextSegment();
				continue APPEND_SUB;
			case SUB_INDEXED_S:
				if (((options & DISPLAY_EXACT) == 0)) {
					sb.append("[…]"); //$NON-NLS-1$
					break APPEND_SUB;
				}
				else {
					return null;
				}
			case SUB_INDEXED_D:
				if (elementName instanceof DefaultImpl) {
					sb.append("[["); //$NON-NLS-1$
					sb.append(elementName.getSegmentName());
					sb.append("]]"); //$NON-NLS-1$
					elementName= elementName.getNextSegment();
					continue APPEND_SUB;
				}
				else if ((options & DISPLAY_EXACT) == 0) {
					sb.append("[[…]]"); //$NON-NLS-1$
					elementName= elementName.getNextSegment();
					continue APPEND_SUB;
				}
				else {
					return null;
				}
			default:
				if (((options & DISPLAY_EXACT) == 0)) {
					sb.append(" …"); //$NON-NLS-1$
					break APPEND_SUB;
				}
				return null;
			}
		}
		return sb.getString();
	}
	
	private static boolean isValidSymbol(final String name) {
		final int l= name.length();
		if (l == 0) {
			return false;
		}
		final char c0= name.charAt(0);
		int check;
		if (Character.isLetter(c0)) {
			check= 1;
		}
		else if (c0 == '.') {
			if (l == 1) {
				check= 1;
			}
			else {
				final char c1= name.charAt(1);
				if (c1 == '.' || c1 == '_' || Character.isLetter(c1)) {
					check= 2;
				}
				else {
					return false;
				}
			}
		}
		else {
			return false;
		}
		for (; check < l; check++) {
			final char cn= name.charAt(check);
			if ((cn < 'a' || cn > 'z') && cn != '.' && cn != '_'  && !Character.isLetterOrDigit(cn)) {
				return false;
			}
		}
		return true;
	}
	
	private static @Nullable RValueFormatter appendSymbol(@Nullable RValueFormatter sb, final String name) {
		if (isValidSymbol(name)) {
			if (sb != null) {
				sb.append(name);
			}
			return sb;
		}
		if (sb == null) {
			sb= new RValueFormatter();
		}
		if (name.isEmpty()) {
			sb.append("``"); //$NON-NLS-1$
		}
		else {
			sb.appendName(name, true);
		}
		return sb;
	}
	
	private static @Nullable String printScopeUI(final String itemPrefix, @Nullable String segmentName,
			final int options) {
		if (segmentName == null) {
			if ((options & DISPLAY_EXACT) == 0) {
				segmentName= "<unknown>"; //$NON-NLS-1$
			}
			else {
				return null;
			}
		}
		final StringBuilder sb= new StringBuilder(itemPrefix.length() + segmentName.length());
		sb.append(itemPrefix);
		sb.append(segmentName);
		return sb.toString();
	}
	
	private static boolean printScopeFQ(final RElementName a, RValueFormatter sb,
			final int options, final boolean operator) {
		final String scopeName;
		switch (a.getType()) {
		case SCOPE_NS:
			scopeName= a.getSegmentName();
			if (scopeName == null) {
				return false;
			}
			if (operator) {
				appendSymbol(sb, scopeName);
				sb.append("::"); //$NON-NLS-1$
			}
			else {
				return false;
			}
			return true;
		case SCOPE_NS_INT:
			scopeName= a.getSegmentName();
			if (scopeName == null) {
				return false;
			}
			if (operator) {
				appendSymbol(sb, scopeName);
				sb.append(":::"); //$NON-NLS-1$
			}
			else {
				sb.append("getNamespace(\""); //$NON-NLS-1$
				sb.append(scopeName);
				sb.append("\")"); //$NON-NLS-1$
			}
			return true;
		case SCOPE_SEARCH_ENV:
			scopeName= a.getSegmentName();
			if (scopeName == null) {
				return false;
			}
			sb.append("as.environment(\""); //$NON-NLS-1$
			sb.append(scopeName);
			sb.append("\")"); //$NON-NLS-1$
			if (operator) {
				sb.append('$');
			}
			return true;
		case SCOPE_PACKAGE:
			scopeName= a.getSegmentName();
			if (scopeName == null) {
				return false;
			}
			sb.append("as.environment(\"package:"); //$NON-NLS-1$
			sb.append(scopeName);
			sb.append("\")"); //$NON-NLS-1$
			if (operator) {
				sb.append('$');
			}
			return true;
		case SCOPE_SYSFRAME:
			scopeName= a.getSegmentName();
			if (scopeName == null) {
				return false;
			}
			sb.append("sys.frame("); //$NON-NLS-1$
			sb.append(scopeName);
			sb.append(((options & DISPLAY_EXACT) != 0) ? "L)" : ")"); //$NON-NLS-1$ //$NON-NLS-2$
			if (operator) {
				sb.append('$');
			}
			return true;
		case SCOPE_PROJECT:
			sb= new RValueFormatter();
			sb.append(".GlobalEnv"); //$NON-NLS-1$
			if (operator) {
				sb.append('$');
			}
			return true;
		default:
			return false;
		}
	}
	
	
	private static final Collator NAME_COLLATOR= RSymbolComparator.R_NAMES_COLLATOR;
	
	public static final Comparator<ElementName> NAMEONLY_COMPARATOR= new Comparator<ElementName>() {
		
		@Override
		public int compare(ElementName o1, ElementName o2) {
			final String n1= o1.getSegmentName();
			final String n2= o2.getSegmentName();
			if (n1 != null) {
				if (n2 != null) {
					final int diff= NAME_COLLATOR.compare(n1, n2);
					if (diff != 0) {
						return diff;
					}
				}
				else {
					return Integer.MIN_VALUE;
				}
			}
			else if (n2 != null) {
				return Integer.MAX_VALUE;
			}
			
			o1= o1.getNextSegment();
			o2= o2.getNextSegment();
			if (o1 != null) {
				if (o2 != null) {
					final int diff= o1.getType() - o2.getType();
					if (diff != 0) {
						return diff;
					}
					return compare(o1, o2);
				}
				else {
					return Integer.MIN_VALUE + 100;
				}
			}
			else if (n2 != null) {
				return Integer.MAX_VALUE - 100;
			}
			return 0;
		}
	};
	
	
	private static boolean equals(final @Nullable String s1, final @Nullable String s2) {
		return (s1 == s2)
				|| (s1 != null && s2 != null && s1.hashCode() == s2.hashCode() && s1.equals(s2) );
	}
	
	
	private static class DefaultImpl extends RElementName implements Serializable {
		
		
		private static final long serialVersionUID= 315497720879434929L;
		
		
		private final int type;
		private final @Nullable String segmentName;
		private @Nullable RElementName scope;
		private @Nullable RElementName nextSegment;
		
		
		public DefaultImpl(final int type,
				final @Nullable String segmentName) {
			this.type= type;
			this.segmentName= segmentName;
			this.nextSegment= null;
		}
		
		public DefaultImpl(final int type, final @Nullable RElementName scope,
				final @Nullable String segmentName,
				final @Nullable RElementName next) {
			this.type= type;
			this.segmentName= segmentName;
			this.scope= scope;
			this.nextSegment= next;
		}
		
		public DefaultImpl(final int type,
				final @Nullable String segmentName,
				final @Nullable RElementName next) {
			this.type= type;
			this.segmentName= segmentName;
			this.nextSegment= next;
		}
		
		
		@Override
		public int getType() {
			return this.type;
		}
		
		@Override
		public @Nullable String getSegmentName() {
			return this.segmentName;
		}
		
		@Override
		public @Nullable RElementName getScope() {
			return this.scope;
		}
		
		@Override
		public @Nullable RElementName getNextSegment() {
			return this.nextSegment;
		}
		
	}
	
	private static class DualImpl extends DefaultImpl implements IndexElementName {
		
		private static final long serialVersionUID= 7040207683623992047L;
		
		private final int idx;
		
		public DualImpl(final int type,
				final @Nullable String segmentName, final int idx) {
			super(type, segmentName);
			this.idx= idx;
		}
		
		public DualImpl(final int type,
				final @Nullable String segmentName, final int idx,
				final @Nullable RElementName next) {
			super(type, segmentName, next);
			this.idx= idx;
		}
		
		
		@Override
		protected boolean isDefaultImpl() {
			return (getClass() == DualImpl.class);
		}
		
		@Override
		protected DefaultImpl cloneSegment0(final @Nullable RElementName next) {
			return new DualImpl(getType(), getSegmentName(), this.idx, next);
		}
		
		
		@Override
		public int getIndex() {
			return this.idx;
		}
		
	}
	
	
	private static DefaultImpl checkSegment(final RElementName name, final @Nullable RElementName next) {
		return (name.isDefaultImpl() && name.getNextSegment() == next) ?
				(DefaultImpl) name :
				name.cloneSegment0(next);
	}
	
	public static RElementName create(final int type, final @Nullable String segmentName) {
		return new DefaultImpl(type, segmentName);
	}
	
	public static RElementName create(final int type, final @Nullable String segmentName,
			final int idx) {
		if (!(type == SUB_NAMEDPART || type == SUB_INDEXED_D)) {
			throw new IllegalArgumentException();
		}
		return new DualImpl(type, segmentName, idx);
	}
	
	public static @Nullable RElementName create(final List<RElementName> segments) {
		if (segments.isEmpty()) {
			return null;
		}
		if (segments.size() == 1) {
			return checkSegment(segments.get(0), null);
		}
		int first= 0;
		RElementName scopeName= segments.get(0);
		if (isScopeType(scopeName.getType())) {
			scopeName= checkSegment(scopeName, null);
			first= 1;
		}
		else {
			scopeName= null;
		}
		RElementName next= null;
		for (int i= segments.size() - 1; i > first; i--) {
			next= checkSegment(segments.get(i), next);
		}
		next= new DefaultImpl(segments.get(first).getType(), scopeName,
				segments.get(first).getSegmentName(), next );
		return next;
	}
	
	/**
	 * Creates a copy of segments of the specified element. The copy starts with the first element
	 * of the element name and ends at the specified end segment (exclusive).
	 * 
	 * @param name the element name to copy
	 * @param end the end segment (exlusive) or <code>null</code>, to copy the complete name
	 * @param withScope to include the scope in the copy, if available
	 * @return the copy of the element name
	 */
	public static @Nullable RElementName create(final @Nullable RElementName name,
			final @Nullable RElementName end, final boolean withScope) {
		if (name == null) {
			return null;
		}
		final List<RElementName> segments= new ArrayList<>();
		if (withScope && name.getScope() != null) {
			segments.add(name.getScope());
		}
		addSegments(segments, name, end);
		return create(segments);
	}
	
	
	private static final int PARSE_OP= -1;
	private static final int PARSE_EXIT= -3;
	
	public static @Nullable RElementName parseDefault(final String code) {
		final RLexer lexer= new RLexer((RLexer.DEFAULT |
						RLexer.SKIP_WHITESPACE | RLexer.SKIP_LINEBREAK | RLexer.SKIP_COMMENT ));
		lexer.reset(new StringParserInput(code).init());
		
		int mode= MAIN_DEFAULT;
		DefaultImpl main= null;
		DefaultImpl last= null;
		while (mode != PARSE_EXIT) {
			DefaultImpl tmp= null;
			RTerminal type= lexer.next();
			if (type == null || type == RTerminal.EOF) {
				if (mode < 0) {
					return main;
				}
				tmp= new DefaultImpl(mode, ""); //$NON-NLS-1$
				mode= PARSE_EXIT;
			}
			else {
				switch (type) {
				case IF:
				case ELSE:
				case FOR:
				case IN:
				case WHILE:
				case REPEAT:
				case NEXT:
				case BREAK:
				case FUNCTION:
				case TRUE:
				case FALSE:
				case NA:
				case NA_INT:
				case NA_REAL:
				case NA_CPLX:
				case NA_CHAR:
				case NULL:
				case NAN:
				case INF:
					if (mode != MAIN_DEFAULT
							&& mode != SUB_NAMEDPART && mode != SUB_NAMEDSLOT) {
						return null;
					}
					tmp= new DefaultImpl(mode, type.text);
					type= lexer.next();
					if (type != null && type != RTerminal.EOF) {
						return null;
					}
					mode= PARSE_EXIT; // valid prefix
					break;
				case SYMBOL:
				case SYMBOL_G:
					if (mode != MAIN_DEFAULT
							&& mode != SUB_NAMEDPART && mode != SUB_NAMEDSLOT) {
						return null;
					}
					tmp= new DefaultImpl(mode, lexer.getText());
					mode= PARSE_OP;
					break;
				case STRING_S:
				case STRING_D:
					if (mode != MAIN_DEFAULT
							&& mode != SUB_NAMEDPART && mode != SUB_NAMEDSLOT) {
						return null;
					}
					tmp= new DefaultImpl(mode, lexer.getText());
					mode= PARSE_OP;
					break;
				case NUM_INT:
				case NUM_NUM:
					if (mode != SUB_INDEXED_S && mode != SUB_INDEXED_D) {
						return null;
					}
					tmp= new DefaultImpl(mode, lexer.getText());
					type= lexer.next();
					if (type != RTerminal.SUB_INDEXED_CLOSE) {
						return null;
					}
					if (mode == SUB_INDEXED_D) {
						type= lexer.next();
						if (type != RTerminal.SUB_INDEXED_CLOSE) {
							return null;
						}
					}
					mode= PARSE_OP;
					break;
				case SUB_NAMED_PART:
					if (main == null || mode >= 0) {
						return null;
					}
					mode= SUB_NAMEDPART;
					continue;
				case SUB_NAMED_SLOT:
					if (main == null || mode >= 0) {
						return null;
					}
					mode= SUB_NAMEDSLOT;
					continue;
				case SUB_INDEXED_S_OPEN:
					if (main == null || mode >= 0) {
						return null;
					}
					mode= SUB_INDEXED_S;
					continue;
				case SUB_INDEXED_D_OPEN:
					if (main == null || mode >= 0) {
						return null;
					}
					mode= SUB_INDEXED_D;
					continue;
//				case SUB_INDEXED_CLOSE:
//					return null;
				case NS_GET:
					if (main == null || main != last || mode >= 0) {
						return null;
					}
					if (main.getType() == MAIN_DEFAULT) {
						main= new DefaultImpl(SCOPE_NS, main.getSegmentName());
					}
					else {
						return null;
					}
					
					mode= MAIN_DEFAULT;
					continue;
				case NS_GET_INT:
					if (main == null || main != last || mode >= 0) {
						return null;
					}
					if (main.getType() == MAIN_DEFAULT) {
						main= new DefaultImpl(SCOPE_NS_INT, main.getSegmentName());
					}
					else {
						return null;
					}
					
					mode= MAIN_DEFAULT;
					continue;
				default:
					return null;
				}
				
			}
			
			if (main == null) {
				main= last= tmp;
			}
			else if (isScopeType(main.getType())) {
				tmp.scope= main;
				main= last= tmp;
			}
			else {
				last.nextSegment= tmp;
				last= tmp;
			}
		}
		return main;
	}
	
	
	/**
	 * Creates a copy of the specified element name.
	 * 
	 * @param name the element name to copy
	 * @param withScope to include the scope in the copy, if available
	 * @return the copy of the element name
	 */
	public static @Nullable RElementName cloneName(@Nullable RElementName name,
			final boolean withScope) {
		if (name == null) {
			return null;
		}
		RElementName scopeName= (withScope) ? name.getScope() : null;
		if (scopeName != null) {
			scopeName= new DefaultImpl(scopeName.getType(), scopeName.getSegmentName(), null);
		}
		final DefaultImpl main= new DefaultImpl(name.getType(), scopeName, name.getSegmentName(), null);
		DefaultImpl last= main;
		name= name.getNextSegment();
		while (name != null) {
			final DefaultImpl copy= name.cloneSegment0(null);
			last.nextSegment= copy;
			last= copy;
			name= name.getNextSegment();
		}
		return main;
	}
	
	/**
	 * Creates a copy of the first segment of the specified element name.
	 * 
	 * @param name the element name to copy
	 * @return the copy of the element name
	 */
	public static RElementName cloneSegment(final RElementName name) {
		return name.cloneSegment0(null);
	}
	
	public static RElementName addScope(final RElementName name, final RElementName scope) {
		if (!isScopeType(scope.getType())) {
			throw new IllegalArgumentException("scope.type= " + scope.getType()); //$NON-NLS-1$
		}
		return new DefaultImpl(name.getType(),
				checkSegment(scope, null),
				name.getSegmentName(), name.getNextSegment() );
	}
	
	public static RElementName removeScope(final RElementName name) {
		final RElementName scope= name.getScope();
		if (scope == null) {
			return name;
		}
		if (!isScopeType(scope.getType())) {
			throw new IllegalArgumentException("scope.type= " + scope.getType()); //$NON-NLS-1$
		}
		return new DefaultImpl(name.getType(), scope, name.getSegmentName(), name.getNextSegment());
	}
	
	public static RElementName normalize(final RElementName name) {
		if (name != null && name.getScope() == null && isScopeType(name.getType())
				&& name.getNextSegment() != null) {
			return addScope(name.getNextSegment(), name);
		}
		return name;
	}
	
	public static void addSegments(final Collection<? super RElementName> segments,
			@Nullable RElementName name) {
		while (name != null) {
			segments.add(name);
			name= name.getNextSegment();
		}
	}
	
	public static void addSegments(final Collection<? super RElementName> segments,
			@Nullable RElementName name, final @Nullable RElementName end) {
		while (name != null && name != end) {
			segments.add(name);
			name= name.getNextSegment();
		}
	}
	
	protected RElementName() {
	}
	
	
	public abstract @Nullable RElementName getScope();
	@Override
	public abstract @Nullable RElementName getNextSegment();
	
	@Override
	public RElementName getLastSegment() {
		@NonNull RElementName lastSegment;
		RElementName nextSegment= this;
		do {
			lastSegment= nextSegment;
		} while ((nextSegment= nextSegment.getNextSegment()) != null);
		return lastSegment;
	}
	
	
	@Override
	public String getDisplayName() {
		return createDisplayName(this, 0);
	}
	
	public @Nullable String getDisplayName(final int options) {
		return createDisplayName(this, options);
	}
	
	@Override
	public int[] correctDisplayNameRegions(final int[] regions, final int offset) {
		final String segmentName= getSegmentName();
		if (segmentName != null && !isValidSymbol(segmentName)) {
			new RValueFormatter().correctNameRegions(regions, segmentName, true, offset);
		}
		return regions;
	}
	
	
	protected boolean isDefaultImpl() {
		return (getClass() == DefaultImpl.class);
	}
	
	protected RElementName.DefaultImpl cloneSegment0(final @Nullable RElementName next) {
		return new DefaultImpl(getType(), getSegmentName(), next);
	}
	
	@Override
	public final int hashCode() {
		final String name= getSegmentName();
		final ElementName next= getNextSegment();
		if (next != null) {
			return getType() * ((name != null) ? name.hashCode() : 1) * (next.hashCode() + 7);
		}
		else {
			return getType() * ((name != null) ? name.hashCode() : 1);
		}
	}
	
	@Override
	public final boolean equals(final @Nullable Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj instanceof RElementName) {
			final ElementName other= (RElementName) obj;
			return ((getType() == other.getType())
					&& equals(getSegmentName(), other.getSegmentName())
					&& Objects.equals(getNextSegment(), other.getNextSegment()) );
		}
		return false;
	}
	
	@Override
	public String toString() {
		return getDisplayName();
	}
	
}
