@Override
	public DbSession getDbSession() {
		log.debug("Requesting db TX manager session");

		final DbJtxTransaction jtx = (DbJtxTransaction) jtxTxManager.getTransaction();

		if (jtx == null) {
			throw new DbSqlException(
					"No transaction is in progress and DbSession can't be provided. " +
					"It seems that transaction manager is not used to begin a transaction.");
		}

		return jtx.requestResource();
	}

Returns session from JTX transaction manager and started transaction.

Returns session from JTX transaction manager and started transaction .


protected T[] convertToSingleElementArray(final Object value) {
		T[] singleElementArray = createArray(1);

		singleElementArray[0] = convertType(value);

		return singleElementArray;
	}

protected T [ ] convertToSingleElementArray ( final Object value ) { T [ ] singleElementArray = createArray ( 1 ) ; singleElementArray [ 0 ] = convertType ( value ) ; return singleElementArray ; }


public Map<String, String> parseSignatureForGenerics(final String signature, final boolean isInterface) {

		if (signature == null) {
			return Collections.emptyMap();
		}

		final Map<String, String> genericsMap = new HashMap<>();

		SignatureReader sr = new SignatureReader(signature);
		StringBuilder sb = new StringBuilder();
		TraceSignatureVisitor v = new TraceSignatureVisitor(sb, isInterface) {
			String genericName;

			@Override
			public void visitFormalTypeParameter(final String name) {
				genericName = name;
				super.visitFormalTypeParameter(name);
			}

			@Override
			public void visitClassType(final String name) {
				if (genericName != null) {
					genericsMap.put(genericName, 'L' + name + ';');
					genericName = null;
				}
				super.visitClassType(name);
			}

		};
		sr.accept(v);

		return genericsMap;
	}

public Map < String , String > parseSignatureForGenerics ( final String signature , final boolean isInterface ) { if ( signature == null ) { return Collections . emptyMap ( ) ; } final Map < String , String > genericsMap = new HashMap <> ( ) ; SignatureReader sr = new SignatureReader ( signature ) ; StringBuilder sb = new StringBuilder ( ) ; TraceSignatureVisitor v = new TraceSignatureVisitor ( sb , isInterface ) { String genericName ; @ Override public void visitFormalTypeParameter ( final String name ) { genericName = name ; super . visitFormalTypeParameter ( name ) ; } @ Override public void visitClassType ( final String name ) { if ( genericName != null ) { genericsMap . put ( genericName , ' ' + name + ' ' ) ; genericName = null ; } super . visitClassType ( name ) ; } } ; sr . accept ( v ) ; return genericsMap ; }

Parses signature for generic information and returns a map where key is generic name
and value is raw type. Returns an empty map if signature does not define any generics.

Parses signature for generic information and returns a map where key is generic name and value is raw type . Returns an empty map if signature does not define any generics .


public SetInjectionPoint[] resolve(final Class type, final boolean autowire) {
		ClassDescriptor cd = ClassIntrospector.get().lookup(type);
		List<SetInjectionPoint> list = new ArrayList<>();

		PropertyDescriptor[] allProperties = cd.getAllPropertyDescriptors();

		for (PropertyDescriptor propertyDescriptor : allProperties) {

			if (propertyDescriptor.isGetterOnly()) {
				continue;
			}

			Class propertyType = propertyDescriptor.getType();
			if (!ClassUtil.isTypeOf(propertyType, Collection.class)) {
				continue;
			}

			MethodDescriptor writeMethodDescriptor = propertyDescriptor.getWriteMethodDescriptor();
			FieldDescriptor fieldDescriptor = propertyDescriptor.getFieldDescriptor();

			PetiteInject ref = null;

			if (writeMethodDescriptor != null) {
				ref = writeMethodDescriptor.getMethod().getAnnotation(PetiteInject.class);
			}
			if (ref == null && fieldDescriptor != null) {
				ref = fieldDescriptor.getField().getAnnotation(PetiteInject.class);
			}

			if ((!autowire) && (ref == null)) {
				continue;
			}

			list.add(new SetInjectionPoint(propertyDescriptor));
		}

		SetInjectionPoint[] fields;

		if (list.isEmpty()) {
			fields = SetInjectionPoint.EMPTY;
		} else {
			fields = list.toArray(new SetInjectionPoint[0]);
		}
		return fields;
	}

public SetInjectionPoint [ ] resolve ( final Class type , final boolean autowire ) { ClassDescriptor cd = ClassIntrospector . get ( ) . lookup ( type ) ; List < SetInjectionPoint > list = new ArrayList <> ( ) ; PropertyDescriptor [ ] allProperties = cd . getAllPropertyDescriptors ( ) ; for ( PropertyDescriptor propertyDescriptor : allProperties ) { if ( propertyDescriptor . isGetterOnly ( ) ) { continue ; } Class propertyType = propertyDescriptor . getType ( ) ; if ( ! ClassUtil . isTypeOf ( propertyType , Collection . class ) ) { continue ; } MethodDescriptor writeMethodDescriptor = propertyDescriptor . getWriteMethodDescriptor ( ) ; FieldDescriptor fieldDescriptor = propertyDescriptor . getFieldDescriptor ( ) ; PetiteInject ref = null ; if ( writeMethodDescriptor != null ) { ref = writeMethodDescriptor . getMethod ( ) . getAnnotation ( PetiteInject . class ) ; } if ( ref == null && fieldDescriptor != null ) { ref = fieldDescriptor . getField ( ) . getAnnotation ( PetiteInject . class ) ; } if ( ( ! autowire ) && ( ref == null ) ) { continue ; } list . add ( new SetInjectionPoint ( propertyDescriptor ) ) ; } SetInjectionPoint [ ] fields ; if ( list . isEmpty ( ) ) { fields = SetInjectionPoint . EMPTY ; } else { fields = list . toArray ( new SetInjectionPoint [ 0 ] ) ; } return fields ; }

Resolves all collections for given type.

Resolves all collections for given type .


public boolean matchIgnoredPropertyTypes(final Class propertyType, final boolean excludeMaps, final boolean include) {
		if (!include) {
			return false;
		}

		if (propertyType != null) {
			if (!jsonSerializer.deep) {
				ClassDescriptor propertyTypeClassDescriptor = ClassIntrospector.get().lookup(propertyType);

				if (propertyTypeClassDescriptor.isArray()) {
					return false;
				}
				if (propertyTypeClassDescriptor.isCollection()) {
					return false;
				}
				if (excludeMaps) {
					if (propertyTypeClassDescriptor.isMap()) {
						return false;
					}
				}
			}

			// still not excluded, continue with excluded types and type names

			// + excluded types

			if (jsonSerializer.excludedTypes != null) {
				for (Class excludedType : jsonSerializer.excludedTypes) {
					if (ClassUtil.isTypeOf(propertyType, excludedType)) {
						return false;
					}
				}
			}

			// + exclude type names

			final String propertyTypeName = propertyType.getName();

			if (jsonSerializer.excludedTypeNames != null) {
				for (String excludedTypeName : jsonSerializer.excludedTypeNames) {
					if (Wildcard.match(propertyTypeName, excludedTypeName)) {
						return false;
					}
				}
			}
		}

		return true;
	}

Matches property types that are ignored by default.

Matches property types that are ignored by default .


protected void openConnectionForQuery() {
		if (connection == null) {
			connection = connectionProvider.getConnection();
			txActive = false;	// txAction should already be false
			try {
				connection.setAutoCommit(true);
			} catch (SQLException sex) {
				throw new DbSqlException("Failed to open non-TX connection", sex);
			}
		}
	}

protected
void
openConnectionForQuery
(
)
{
if
(
connection
==
)
{
connection
=
connectionProvider
.
getConnection
(
)
;
txActive
=
false
;
// txAction should already be false
try
{
connection
.
setAutoCommit
(
true
)
;
}
catch
(
SQLException
sex
)
{
throw
new
DbSqlException
(
"Failed to open non-TX connection"
,
sex
)
;
}
}
}

Opens connection in auto-commit mode, if already not opened.

Opens connection in auto - commit mode if already not opened .


protected void openTx() {
		if (connection == null) {
			connection = connectionProvider.getConnection();
		}
		txActive = true;
		try {
			connection.setAutoCommit(false);
			if (txMode.getIsolation() != DbTransactionMode.ISOLATION_DEFAULT) {
				connection.setTransactionIsolation(txMode.getIsolation());
			}
			connection.setReadOnly(txMode.isReadOnly());
		} catch (SQLException sex) {
			throw new DbSqlException("Open TX failed", sex);
		}
	}

protected
void
openTx
(
)
{
if
(
connection
==
)
{
connection
=
connectionProvider
.
getConnection
(
)
;
}
txActive
=
true
;
try
{
connection
.
setAutoCommit
(
false
)
;
if
(
txMode
.
getIsolation
(
)
!=
DbTransactionMode
.
ISOLATION_DEFAULT
)
{
connection
.
setTransactionIsolation
(
txMode
.
getIsolation
(
)
)
;
}
connection
.
setReadOnly
(
txMode
.
isReadOnly
(
)
)
;
}
catch
(
SQLException
sex
)
{
throw
new
DbSqlException
(
"Open TX failed"
,
sex
)
;
}
}


protected void closeTx() {
		txActive = false;
		try {
			connection.setAutoCommit(true);
		} catch (SQLException sex) {
			throw new DbSqlException("Close TX failed", sex);
		}
	}

protected
void
closeTx
(
)
{
txActive
=
false
;
try
{
connection
.
setAutoCommit
(
true
)
;
}
catch
(
SQLException
sex
)
{
throw
new
DbSqlException
(
"Close TX failed"
,
sex
)
;
}
}


public void commitTransaction() {
		log.debug("Committing transaction");

		assertTxIsActive();
		try {
			connection.commit();
		} catch (SQLException sex) {
			throw new DbSqlException("Commit TX failed", sex);
		} finally {
			closeTx();
		}
	}

public
void
commitTransaction
(
)
{
log
.
debug
(
"Committing transaction"
)
;
assertTxIsActive
(
)
;
try
{
connection
.
commit
(
)
;
}
catch
(
SQLException
sex
)
{
throw
new
DbSqlException
(
"Commit TX failed"
,
sex
)
;
}
finally
{
closeTx
(
)
;
}
}

Commit the current transaction, writing any unflushed changes to the database.
Transaction mode is closed.

Commit the current transaction writing any unflushed changes to the database . Transaction mode is closed .


public void rollbackTransaction() {
		log.debug("Rolling-back transaction");

		assertTxIsActive();

		try {
			connection.rollback();
		} catch (SQLException sex) {
			throw new DbSqlException("Rollback TX failed", sex);
		} finally {
			closeTx();
		}
	}

public
void
rollbackTransaction
(
)
{
log
.
debug
(
"Rolling-back transaction"
)
;
assertTxIsActive
(
)
;
try
{
connection
.
rollback
(
)
;
}
catch
(
SQLException
sex
)
{
throw
new
DbSqlException
(
"Rollback TX failed"
,
sex
)
;
}
finally
{
closeTx
(
)
;
}
}

Roll back the current transaction. Transaction mode is closed.

Roll back the current transaction . Transaction mode is closed .


public static Properties createFromFile(final File file) throws IOException {
		Properties prop = new Properties();
		loadFromFile(prop, file);
		return prop;
	}

public static Properties createFromFile ( final File file ) throws IOException { Properties prop = new Properties ( ) ; loadFromFile ( prop , file ) ; return prop ; }

Create properties from the file.

@param file properties file to load


public static Properties createFromString(final String data) throws IOException {
		Properties p = new Properties();
		loadFromString(p, data);
		return p;
	}

public static Properties createFromString ( final String data ) throws IOException { Properties p = new Properties ( ) ; loadFromString ( p , data ) ; return p ; }


public static void loadFromString(final Properties p, final String data) throws IOException {
		try (ByteArrayInputStream is = new ByteArrayInputStream(data.getBytes(StringPool.ISO_8859_1))) {
			p.load(is);
		}
	}

public static void loadFromString ( final Properties p , final String data ) throws IOException { try ( ByteArrayInputStream is = new ByteArrayInputStream ( data . getBytes ( StringPool . ISO_8859_1 ) ) ) { p . load ( is ) ; } }


public static Properties subset(final Properties p, String prefix, final boolean stripPrefix) {
		if (StringUtil.isBlank(prefix)) {
			return p;
		}
		if (!prefix.endsWith(StringPool.DOT)) {
			prefix += '.';
		}
		Properties result = new Properties();
		int baseLen = prefix.length();
		for (Object o : p.keySet()) {
			String key = (String) o;
			if (key.startsWith(prefix)) {
				result.setProperty(stripPrefix ? key.substring(baseLen) : key, p.getProperty(key));
			}
		}
		return result;
	}

public static Properties subset ( final Properties p , String prefix , final boolean stripPrefix ) { if ( StringUtil . isBlank ( prefix ) ) { return p ; } if ( ! prefix . endsWith ( StringPool . DOT ) ) { prefix += ' ' ; } Properties result = new Properties ( ) ; int baseLen = prefix . length ( ) ; for ( Object o : p . keySet ( ) ) { String key = ( String ) o ; if ( key . startsWith ( prefix ) ) { result . setProperty ( stripPrefix ? key . substring ( baseLen ) : key , p . getProperty ( key ) ) ; } } return result ; }

Creates new Properties object from the original one, by copying
those properties that have specified first part of the key name.
Prefix may be optionally stripped during this process.

@param p         source properties, from which new object will be created
@param prefix    key names prefix

@return subset properties

Creates new Properties object from the original one by copying those properties that have specified first part of the key name . Prefix may be optionally stripped during this process .


public static Properties createFromClasspath(final String... rootTemplate) {
		Properties p = new Properties();
		return loadFromClasspath(p, rootTemplate);
	}

public static Properties createFromClasspath ( final String ... rootTemplate ) { Properties p = new Properties ( ) ; return loadFromClasspath ( p , rootTemplate ) ; }


public static String getProperty(final Map map, final String key, final String defaultValue) {
		Object val = map.get(key);
		return (val instanceof String) ? (String) val : defaultValue;
	}

public static String getProperty ( final Map map , final String key , final String defaultValue ) { Object val = map . get ( key ) ; return ( val instanceof String ) ? ( String ) val : defaultValue ; }

Returns String property from a map.
@see #getProperty(java.util.Map, String)


public static void resolveAllVariables(final Properties prop) {
		for (Object o : prop.keySet()) {
			String key = (String) o;
			String value = resolveProperty(prop, key);
			prop.setProperty(key, value);
		}
	}

public static void resolveAllVariables ( final Properties prop ) { for ( Object o : prop . keySet ( ) ) { String key = ( String ) o ; String value = resolveProperty ( prop , key ) ; prop . setProperty ( key , value ) ; } }


public static String resolveProperty(final Map map, final String key) {
		String value = getProperty(map, key);
		if (value == null) {
			return null;
		}
		value = stp.parse(value, macroName -> getProperty(map, macroName));

		return value;
	}

public static String resolveProperty ( final Map map , final String key ) { String value = getProperty ( map , key ) ; if ( value == null ) { return null ; } value = stp . parse ( value , macroName -> getProperty ( map , macroName ) ) ; return value ; }

Returns property with resolved variables.

Returns property with resolved variables .


public String resolveScope(final Class type, final String methodName) {
		if (scopePattern == null) {
			return null;
		}
		String ctx = scopePattern;
		ctx = StringUtil.replace(ctx, JTXCTX_PATTERN_CLASS, type.getName());
		ctx = StringUtil.replace(ctx, JTXCTX_PATTERN_METHOD, methodName);
		return ctx;
	}

public String resolveScope ( final Class type , final String methodName ) { if ( scopePattern == null ) { return null ; } String ctx = scopePattern ; ctx = StringUtil . replace ( ctx , JTXCTX_PATTERN_CLASS , type . getName ( ) ) ; ctx = StringUtil . replace ( ctx , JTXCTX_PATTERN_METHOD , methodName ) ; return ctx ; }


public synchronized JtxTransactionMode getTxMode(final Class type, final String methodName, final Class[] methodArgTypes, final String unique) {
		String signature = type.getName() + '#' + methodName + '%' + unique;
		JtxTransactionMode txMode = txmap.get(signature);
		if (txMode == null) {
			if (!txmap.containsKey(signature)) {

				final Method m;
				try {
					m = type.getMethod(methodName, methodArgTypes);
				} catch (NoSuchMethodException nsmex) {
					throw new ProxettaException(nsmex);
				}

				final TransactionAnnotationValues txAnn = readTransactionAnnotation(m);
				if (txAnn != null) {
					txMode = new JtxTransactionMode(
						txAnn.propagation(),
						txAnn.isolation(),
						txAnn.readOnly(),
						txAnn.timeout()
					);
				} else {
					txMode = defaultTransactionMode;
				}
				txmap.put(signature, txMode);
			}
		}
		return txMode;
	}

public synchronized JtxTransactionMode getTxMode ( final Class type , final String methodName , final Class [ ] methodArgTypes , final String unique ) { String signature = type . getName ( ) + ' ' + methodName + ' ' + unique ; JtxTransactionMode txMode = txmap . get ( signature ) ; if ( txMode == null ) { if ( ! txmap . containsKey ( signature ) ) { final Method m ; try { m = type . getMethod ( methodName , methodArgTypes ) ; } catch ( NoSuchMethodException nsmex ) { throw new ProxettaException ( nsmex ) ; } final TransactionAnnotationValues txAnn = readTransactionAnnotation ( m ) ; if ( txAnn != null ) { txMode = new JtxTransactionMode ( txAnn . propagation ( ) , txAnn . isolation ( ) , txAnn . readOnly ( ) , txAnn . timeout ( ) ) ; } else { txMode = defaultTransactionMode ; } txmap . put ( signature , txMode ) ; } } return txMode ; }

Reads transaction mode from method annotation. Annotations are cached for better performances.
@param type target class
@param methodName target method name over which the transaction should be wrapped
@param methodArgTypes types of arguments, used to find the method
@param unique unique method fingerprint that contains return and arguments type information

Reads transaction mode from method annotation . Annotations are cached for better performances .


@SuppressWarnings( {"unchecked"})
	public void registerAnnotations(final Class<? extends Annotation>[] annotations) {
		this.annotations = annotations;

		this.annotationParsers = new AnnotationParser[annotations.length];

		for (int i = 0; i < annotations.length; i++) {
			annotationParsers[i] = TransactionAnnotationValues.parserFor(annotations[i]);
		}
	}

@ SuppressWarnings ( { "unchecked" } ) public void registerAnnotations ( final Class < ? extends Annotation > [ ] annotations ) { this . annotations = annotations ; this . annotationParsers = new AnnotationParser [ annotations . length ] ; for ( int i = 0 ; i < annotations . length ; i ++ ) { annotationParsers [ i ] = TransactionAnnotationValues . parserFor ( annotations [ i ] ) ; } }


protected TransactionAnnotationValues readTransactionAnnotation(final Method method) {
		for (AnnotationParser annotationParser : annotationParsers) {
			TransactionAnnotationValues tad = TransactionAnnotationValues.of(annotationParser, method);
			if (tad != null) {
				return tad;
			}
		}
		return null;
	}

protected TransactionAnnotationValues readTransactionAnnotation ( final Method method ) { for ( AnnotationParser annotationParser : annotationParsers ) { TransactionAnnotationValues tad = TransactionAnnotationValues . of ( annotationParser , method ) ; if ( tad != null ) { return tad ; } } return null ; }


@Override
	public boolean accept(final Node node) {
		// match element name with node name
		if (!matchElement(node)) {
			return false;
		}

		// match attributes
		int totalSelectors = selectorsCount();
		for (int i = 0; i < totalSelectors; i++) {
			Selector selector = getSelector(i);

			// just attr name existence
			switch (selector.getType()) {
				case ATTRIBUTE:
					if (!((AttributeSelector) selector).accept(node)) {
						return false;
					}
					break;
				case PSEUDO_CLASS:
					if (!((PseudoClassSelector) selector).accept(node)) {
						return false;
					}
					break;
				case PSEUDO_FUNCTION:
					if (!((PseudoFunctionSelector) selector).accept(node)) {
						return false;
					}
					break;
			}
		}
		return true;
	}

@
Override
public
boolean
accept
(
final
Node
node
)
{
// match element name with node name
if
(
!
matchElement
(
node
)
)
{
return
false
;
}
// match attributes
int
totalSelectors
=
selectorsCount
(
)
;
for
(
int
i
=
0
;
i
<
totalSelectors
;
i
++
)
{
Selector
selector
=
getSelector
(
i
)
;
// just attr name existence
switch
(
selector
.
getType
(
)
)
{
case
ATTRIBUTE
:
if
(
!
(
(
AttributeSelector
)
selector
)
.
accept
(
node
)
)
{
return
false
;
}
break
;
case
PSEUDO_CLASS
:
if
(
!
(
(
PseudoClassSelector
)
selector
)
.
accept
(
node
)
)
{
return
false
;
}
break
;
case
PSEUDO_FUNCTION
:
if
(
!
(
(
PseudoFunctionSelector
)
selector
)
.
accept
(
node
)
)
{
return
false
;
}
break
;
}
}
return
true
;
}


protected boolean matchElement(final Node node) {
		if (node.getNodeType() != Node.NodeType.ELEMENT) {
			return false;
		}
		String element = getElement();
		String nodeName = node.getNodeName();
		return element.equals(StringPool.STAR) || element.equals(nodeName);
	}

protected boolean matchElement ( final Node node ) { if ( node . getNodeType ( ) != Node . NodeType . ELEMENT ) { return false ; } String element = getElement ( ) ; String nodeName = node . getNodeName ( ) ; return element . equals ( StringPool . STAR ) || element . equals ( nodeName ) ; }

Matches element to css selector. All non-element types are ignored.

Matches element to css selector . All non - element types are ignored .


public boolean accept(final List<Node> currentResults, final Node node, final int index) {
		// match attributes
		int totalSelectors = selectorsCount();
		for (int i = 0; i < totalSelectors; i++) {
			Selector selector = getSelector(i);

			// just attr name existence
			switch (selector.getType()) {
				case PSEUDO_FUNCTION:
					if (!((PseudoFunctionSelector) selector).accept(currentResults, node, index)) {
						return false;
					}
					break;
				case PSEUDO_CLASS:
					if (!((PseudoClassSelector) selector).accept(currentResults, node, index)) {
						return false;
					}
					break;
				default:
			}
		}
		return true;
	}

public
boolean
accept
(
final
List
<
Node
>
currentResults
,
final
Node
node
,
final
int
index
)
{
// match attributes
int
totalSelectors
=
selectorsCount
(
)
;
for
(
int
i
=
0
;
i
<
totalSelectors
;
i
++
)
{
Selector
selector
=
getSelector
(
i
)
;
// just attr name existence
switch
(
selector
.
getType
(
)
)
{
case
PSEUDO_FUNCTION
:
if
(
!
(
(
PseudoFunctionSelector
)
selector
)
.
accept
(
currentResults
,
node
,
index
)
)
{
return
false
;
}
break
;
case
PSEUDO_CLASS
:
if
(
!
(
(
PseudoClassSelector
)
selector
)
.
accept
(
currentResults
,
node
,
index
)
)
{
return
false
;
}
break
;
default
:
}
}
return
true
;
}


protected String unescape(final String value) {
		if (value.indexOf('\\') == -1) {
			return value;
		}

		return StringUtil.remove(value, '\\');
	}

protected String unescape ( final String value ) { if ( value . indexOf ( ' ' ) == - 1 ) { return value ; } return StringUtil . remove ( value , ' ' ) ; }

Unescapes CSS string by removing all backslash characters from it.

Unescapes CSS string by removing all backslash characters from it .


private String[] buildJrePackages(final int javaVersionNumber) {
		final ArrayList<String> packages = new ArrayList<>();

		switch (javaVersionNumber) {
			case 9:
			case 8:
			case 7:
			case 6:
			case 5:
				// in Java1.5, the apache stuff moved
				packages.add("com.sun.org.apache");
				// fall through...
			case 4:
				if (javaVersionNumber == 4) {
					packages.add("org.apache.crimson");
					packages.add("org.apache.xalan");
					packages.add("org.apache.xml");
					packages.add("org.apache.xpath");
				}
				packages.add("org.ietf.jgss");
				packages.add("org.w3c.dom");
				packages.add("org.xml.sax");
				// fall through...
			case 3:
				packages.add("org.omg");
				packages.add("com.sun.corba");
				packages.add("com.sun.jndi");
				packages.add("com.sun.media");
				packages.add("com.sun.naming");
				packages.add("com.sun.org.omg");
				packages.add("com.sun.rmi");
				packages.add("sunw.io");
				packages.add("sunw.util");
				// fall through...
			case 2:
				packages.add("com.sun.java");
				packages.add("com.sun.image");
				// fall through...
			case 1:
			default:
				// core stuff
				packages.add("sun");
				packages.add("java");
				packages.add("javax");
				break;
		}

		return packages.toArray(new String[0]);
	}

private
String
[
]
buildJrePackages
(
final
int
javaVersionNumber
)
{
final
ArrayList
<
String
>
packages
=
new
ArrayList
<>
(
)
;
switch
(
javaVersionNumber
)
{
case
9
:
case
8
:
case
7
:
case
6
:
case
5
:
// in Java1.5, the apache stuff moved
packages
.
add
(
"com.sun.org.apache"
)
;
// fall through...
case
4
:
if
(
javaVersionNumber
==
4
)
{
packages
.
add
(
"org.apache.crimson"
)
;
packages
.
add
(
"org.apache.xalan"
)
;
packages
.
add
(
"org.apache.xml"
)
;
packages
.
add
(
"org.apache.xpath"
)
;
}
packages
.
add
(
"org.ietf.jgss"
)
;
packages
.
add
(
"org.w3c.dom"
)
;
packages
.
add
(
"org.xml.sax"
)
;
// fall through...
case
3
:
packages
.
add
(
"org.omg"
)
;
packages
.
add
(
"com.sun.corba"
)
;
packages
.
add
(
"com.sun.jndi"
)
;
packages
.
add
(
"com.sun.media"
)
;
packages
.
add
(
"com.sun.naming"
)
;
packages
.
add
(
"com.sun.org.omg"
)
;
packages
.
add
(
"com.sun.rmi"
)
;
packages
.
add
(
"sunw.io"
)
;
packages
.
add
(
"sunw.util"
)
;
// fall through...
case
2
:
packages
.
add
(
"com.sun.java"
)
;
packages
.
add
(
"com.sun.image"
)
;
// fall through...
case
1
:
default
:
// core stuff
packages
.
add
(
"sun"
)
;
packages
.
add
(
"java"
)
;
packages
.
add
(
"javax"
)
;
break
;
}
return
packages
.
toArray
(
new
String
[
0
]
)
;
}


protected <T extends Node> T cloneTo(final T dest) {
//		dest.nodeValue = nodeValue;		// already  in clone implementations!
		dest.parentNode = parentNode;

		if (attributes != null) {
			dest.attributes = new ArrayList<>(attributes.size());
			for (int i = 0, attributesSize = attributes.size(); i < attributesSize; i++) {
				Attribute attr = attributes.get(i);
				dest.attributes.add(attr.clone());
			}
		}

		if (childNodes != null) {
			dest.childNodes = new ArrayList<>(childNodes.size());
			for (int i = 0, childNodesSize = childNodes.size(); i < childNodesSize; i++) {
				Node child = childNodes.get(i);
				Node childClone = child.clone();

				childClone.parentNode = dest;    // fix parent!
				dest.childNodes.add(childClone);
			}
		}

		return dest;
	}

Copies all non-final values to the empty cloned object.
Cache-related values are not copied.

Copies all non - final values to the empty cloned object . Cache - related values are not copied .


public void detachFromParent() {
		if (parentNode == null) {
			return;
		}
		if (parentNode.childNodes != null) {
			parentNode.childNodes.remove(siblingIndex);
			parentNode.reindexChildren();
		}
		parentNode = null;
	}

public void detachFromParent ( ) { if ( parentNode == null ) { return ; } if ( parentNode . childNodes != null ) { parentNode . childNodes . remove ( siblingIndex ) ; parentNode . reindexChildren ( ) ; } parentNode = null ; }


public void addChild(final Node... nodes) {
		if (nodes.length == 0) {
			return;	// nothing to add
		}
		for (Node node : nodes) {
			node.detachFromParent();
			node.parentNode = this;
			initChildNodes(node);
			childNodes.add(node);
		}
		reindexChildrenOnAdd(nodes.length);
	}

public
void
addChild
(
final
Node
...
nodes
)
{
if
(
nodes
.
length
==
0
)
{
return
;
// nothing to add
}
for
(
Node
node
:
nodes
)
{
node
.
detachFromParent
(
)
;
node
.
parentNode
=
this
;
initChildNodes
(
node
)
;
childNodes
.
add
(
node
)
;
}
reindexChildrenOnAdd
(
nodes
.
length
)
;
}

Appends several child nodes at once.
Reindex is done only once, after all children are added.

Appends several child nodes at once . Reindex is done only once after all children are added .


public void insertChild(final Node node, final int index) {
		node.detachFromParent();
		node.parentNode = this;
		try {
			initChildNodes(node);
			childNodes.add(index, node);
		} catch (IndexOutOfBoundsException ignore) {
			throw new LagartoDOMException("Invalid node index: " + index);
		}
		reindexChildren();
	}

public
void
insertChild
(
final
Node
node
,
final
int
index
)
{
node
.
detachFromParent
(
)
;
node
.
parentNode
=
this
;
try
{
initChildNodes
(
node
)
;
childNodes
.
add
(
index
,
node
)
;
}
catch
(
IndexOutOfBoundsException
ignore
)
{
throw
new
LagartoDOMException
(
"Invalid node index: "
+
index
)
;
}
reindexChildren
(
)
;
}


public void insertBefore(final Node newChild, final Node refChild) {
		int siblingIndex = refChild.getSiblingIndex();
		refChild.parentNode.insertChild(newChild, siblingIndex);
	}

public void insertBefore ( final Node newChild , final Node refChild ) { int siblingIndex = refChild . getSiblingIndex ( ) ; refChild . parentNode . insertChild ( newChild , siblingIndex ) ; }


public void insertBefore(final Node[] newChilds, final Node refChild) {
		if (newChilds.length == 0) {
			return;
		}
		int siblingIndex = refChild.getSiblingIndex();
		refChild.parentNode.insertChild(newChilds, siblingIndex);
	}

public void insertBefore ( final Node [ ] newChilds , final Node refChild ) { if ( newChilds . length == 0 ) { return ; } int siblingIndex = refChild . getSiblingIndex ( ) ; refChild . parentNode . insertChild ( newChilds , siblingIndex ) ; }

Inserts several child nodes before provided node.

Inserts several child nodes before provided node .


public void insertAfter(final Node newChild, final Node refChild) {
		int siblingIndex = refChild.getSiblingIndex() + 1;
		if (siblingIndex == refChild.parentNode.getChildNodesCount()) {
			refChild.parentNode.addChild(newChild);
		} else {
			refChild.parentNode.insertChild(newChild, siblingIndex);
		}
	}

public void insertAfter ( final Node newChild , final Node refChild ) { int siblingIndex = refChild . getSiblingIndex ( ) + 1 ; if ( siblingIndex == refChild . parentNode . getChildNodesCount ( ) ) { refChild . parentNode . addChild ( newChild ) ; } else { refChild . parentNode . insertChild ( newChild , siblingIndex ) ; } }


public void insertAfter(final Node[] newChilds, final Node refChild) {
		if (newChilds.length == 0) {
			return;
		}

		int siblingIndex = refChild.getSiblingIndex() + 1;
		if (siblingIndex == refChild.parentNode.getChildNodesCount()) {
			refChild.parentNode.addChild(newChilds);
		} else {
			refChild.parentNode.insertChild(newChilds, siblingIndex);
		}
	}

public void insertAfter ( final Node [ ] newChilds , final Node refChild ) { if ( newChilds . length == 0 ) { return ; } int siblingIndex = refChild . getSiblingIndex ( ) + 1 ; if ( siblingIndex == refChild . parentNode . getChildNodesCount ( ) ) { refChild . parentNode . addChild ( newChilds ) ; } else { refChild . parentNode . insertChild ( newChilds , siblingIndex ) ; } }

Inserts several child nodes after referent node.

Inserts several child nodes after referent node .


public void removeAllChilds() {
		List<Node> removedNodes = childNodes;
		childNodes = null;
		childElementNodes = null;
		childElementNodesCount = 0;

		if (removedNodes != null) {
			for (int i = 0, removedNodesSize = removedNodes.size(); i < removedNodesSize; i++) {
				Node removedNode = removedNodes.get(i);
				removedNode.detachFromParent();
			}
		}
	}

public void removeAllChilds ( ) { List < Node > removedNodes = childNodes ; childNodes = null ; childElementNodes = null ; childElementNodesCount = 0 ; if ( removedNodes != null ) { for ( int i = 0 , removedNodesSize = removedNodes . size ( ) ; i < removedNodesSize ; i ++ ) { Node removedNode = removedNodes . get ( i ) ; removedNode . detachFromParent ( ) ; } } }

Removes all child nodes. Each child node will be detached from this parent.

Removes all child nodes . Each child node will be detached from this parent .


public Node findChildNodeWithName(final String name) {
		if (childNodes == null) {
			return null;
		}
		for (final Node childNode : childNodes) {
			if (childNode.getNodeName().equals(name)) {
				return childNode;
			}
		}
		return null;
	}

public Node findChildNodeWithName ( final String name ) { if ( childNodes == null ) { return null ; } for ( final Node childNode : childNodes ) { if ( childNode . getNodeName ( ) . equals ( name ) ) { return childNode ; } } return null ; }

Finds the first child node with given node name.

Finds the first child node with given node name .


public Node[] filterChildNodes(final Predicate<Node> nodePredicate) {
		if (childNodes == null) {
			return new Node[0];
		}
		return childNodes.stream()
			.filter(nodePredicate)
			.toArray(Node[]::new);
	}

public Node [ ] filterChildNodes ( final Predicate < Node > nodePredicate ) { if ( childNodes == null ) { return new Node [ 0 ] ; } return childNodes . stream ( ) . filter ( nodePredicate ) . toArray ( Node [ ] :: new ) ; }


public boolean check() {

		if (childNodes == null) {
			return true;
		}

		// children
		int siblingElementIndex = 0;
		for (int i = 0, childNodesSize = childNodes.size(); i < childNodesSize; i++) {
			Node childNode = childNodes.get(i);

			if (childNode.siblingIndex != i) {
				return false;
			}

			if (childNode.getNodeType() == NodeType.ELEMENT) {
				if (childNode.siblingElementIndex != siblingElementIndex) {
					return false;
				}
				siblingElementIndex++;
			}
		}

		if (childElementNodesCount != siblingElementIndex) {
			return false;
		}

		// child element nodes
		if (childElementNodes != null) {
			if (childElementNodes.length != childElementNodesCount) {
				return false;
			}

			int childCount = getChildNodesCount();
			for (int i = 0; i < childCount; i++) {
				Node child = getChild(i);
				if (child.siblingElementIndex >= 0) {
					if (childElementNodes[child.siblingElementIndex] != child) {
						return false;
					}
				}
			}
		}

		// sibling names
		if (siblingNameIndex != -1) {
			List<Node> siblings = parentNode.childNodes;
			int index = 0;
			for (int i = 0, siblingsSize = siblings.size(); i < siblingsSize; i++) {
				Node sibling = siblings.get(i);
				if (sibling.siblingNameIndex == -1
						&& nodeType == NodeType.ELEMENT
						&& nodeName.equals(sibling.getNodeName())) {
					if (sibling.siblingNameIndex != index++) {
						return false;
					}
				}
			}
		}

		// process children
		for (Node childNode : childNodes) {
			if (!childNode.check()) {
				return false;
			}
		}
		return true;
	}

public
boolean
check
(
)
{
if
(
childNodes
==
)
{
return
true
;
}
// children
int
siblingElementIndex
=
0
;
for
(
int
i
=
0
,
childNodesSize
=
childNodes
.
size
(
)
;
i
<
childNodesSize
;
i
++
)
{
Node
childNode
=
childNodes
.
get
(
i
)
;
if
(
childNode
.
siblingIndex
!=
i
)
{
return
false
;
}
if
(
childNode
.
getNodeType
(
)
==
NodeType
.
ELEMENT
)
{
if
(
childNode
.
siblingElementIndex
!=
siblingElementIndex
)
{
return
false
;
}
siblingElementIndex
++
;
}
}
if
(
childElementNodesCount
!=
siblingElementIndex
)
{
return
false
;
}
// child element nodes
if
(
childElementNodes
!=
)
{
if
(
childElementNodes
.
length
!=
childElementNodesCount
)
{
return
false
;
}
int
childCount
=
getChildNodesCount
(
)
;
for
(
int
i
=
0
;
i
<
childCount
;
i
++
)
{
Node
child
=
getChild
(
i
)
;
if
(
child
.
siblingElementIndex
>=
0
)
{
if
(
childElementNodes
[
child
.
siblingElementIndex
]
!=
child
)
{
return
false
;
}
}
}
}
// sibling names
if
(
siblingNameIndex
!=
1
)
{
List
<
Node
>
siblings
=
parentNode
.
childNodes
;
int
index
=
0
;
for
(
int
i
=
0
,
siblingsSize
=
siblings
.
size
(
)
;
i
<
siblingsSize
;
i
++
)
{
Node
sibling
=
siblings
.
get
(
i
)
;
if
(
sibling
.
siblingNameIndex
==
1
&&
nodeType
==
NodeType
.
ELEMENT
&&
nodeName
.
equals
(
sibling
.
getNodeName
(
)
)
)
{
if
(
sibling
.
siblingNameIndex
!=
index
++
)
{
return
false
;
}
}
}
}
// process children
for
(
Node
childNode
:
childNodes
)
{
if
(
!
childNode
.
check
(
)
)
{
return
false
;
}
}
return
true
;
}

Checks the health of child nodes. Useful during complex tree manipulation,
to check if everything is OK. Not optimized for speed, should be used just
for testing purposes.

Checks the health of child nodes . Useful during complex tree manipulation to check if everything is OK . Not optimized for speed should be used just for testing purposes .


protected void initChildElementNodes() {
		if (childElementNodes == null) {
			childElementNodes = new Element[childElementNodesCount];

			int childCount = getChildNodesCount();
			for (int i = 0; i < childCount; i++) {
				Node child = getChild(i);
				if (child.siblingElementIndex >= 0) {
					childElementNodes[child.siblingElementIndex] = (Element) child;
				}
			}
		}
	}

protected void initChildElementNodes ( ) { if ( childElementNodes == null ) { childElementNodes = new Element [ childElementNodesCount ] ; int childCount = getChildNodesCount ( ) ; for ( int i = 0 ; i < childCount ; i ++ ) { Node child = getChild ( i ) ; if ( child . siblingElementIndex >= 0 ) { childElementNodes [ child . siblingElementIndex ] = ( Element ) child ; } } } }


protected void initSiblingNames() {
		if (siblingNameIndex == -1) {
			List<Node> siblings = parentNode.childNodes;
			int index = 0;
			for (int i = 0, siblingsSize = siblings.size(); i < siblingsSize; i++) {
				Node sibling = siblings.get(i);
				if (sibling.siblingNameIndex == -1
						&& nodeType == NodeType.ELEMENT
						&& nodeName.equals(sibling.getNodeName())) {
					sibling.siblingNameIndex = index++;
				}
			}
		}
	}

protected void initSiblingNames ( ) { if ( siblingNameIndex == - 1 ) { List < Node > siblings = parentNode . childNodes ; int index = 0 ; for ( int i = 0 , siblingsSize = siblings . size ( ) ; i < siblingsSize ; i ++ ) { Node sibling = siblings . get ( i ) ; if ( sibling . siblingNameIndex == - 1 && nodeType == NodeType . ELEMENT && nodeName . equals ( sibling . getNodeName ( ) ) ) { sibling . siblingNameIndex = index ++ ; } } } }

Initializes siblings elements of the same name.

Initializes siblings elements of the same name .


protected void initChildNodes(final Node newNode) {
		if (childNodes == null) {
			childNodes = new ArrayList<>();
		}
		if (ownerDocument != null) {
			if (newNode.ownerDocument != ownerDocument) {
				changeOwnerDocument(newNode, ownerDocument);
			}
		}
	}

protected void initChildNodes ( final Node newNode ) { if ( childNodes == null ) { childNodes = new ArrayList <> ( ) ; } if ( ownerDocument != null ) { if ( newNode . ownerDocument != ownerDocument ) { changeOwnerDocument ( newNode , ownerDocument ) ; } } }

Initializes child nodes list when needed.
Also fix owner document for new node, if needed.

Initializes child nodes list when needed . Also fix owner document for new node if needed .


protected void changeOwnerDocument(final Node node, final Document ownerDocument) {
		node.ownerDocument = ownerDocument;

		int childCount = node.getChildNodesCount();
		for (int i = 0; i < childCount; i++) {
			Node child = node.getChild(i);
			changeOwnerDocument(child, ownerDocument);
		}
	}

protected void changeOwnerDocument ( final Node node , final Document ownerDocument ) { node . ownerDocument = ownerDocument ; int childCount = node . getChildNodesCount ( ) ; for ( int i = 0 ; i < childCount ; i ++ ) { Node child = node . getChild ( i ) ; changeOwnerDocument ( child , ownerDocument ) ; } }

Changes owner document for given node and all its children.

Changes owner document for given node and all its children .


public Node getPreviousSiblingName() {
		if (nodeName == null) {
			return null;
		}
		initSiblingNames();
		int index = siblingNameIndex -1;
		for (int i = siblingIndex; i >= 0; i--) {
			Node sibling = parentNode.childNodes.get(i);
			if ((index == sibling.siblingNameIndex) && nodeName.equals(sibling.getNodeName())) {
				return sibling;
			}
		}
		return null;
	}

public Node getPreviousSiblingName ( ) { if ( nodeName == null ) { return null ; } initSiblingNames ( ) ; int index = siblingNameIndex - 1 ; for ( int i = siblingIndex ; i >= 0 ; i -- ) { Node sibling = parentNode . childNodes . get ( i ) ; if ( ( index == sibling . siblingNameIndex ) && nodeName . equals ( sibling . getNodeName ( ) ) ) { return sibling ; } } return null ; }

Returns this node's previous sibling element with the same name.

Returns this node s previous sibling element with the same name .


public String getTextContent() {
		StringBuilder sb = new StringBuilder(getChildNodesCount() + 1);
		appendTextContent(sb);
		return sb.toString();
	}

public String getTextContent ( ) { StringBuilder sb = new StringBuilder ( getChildNodesCount ( ) + 1 ) ; appendTextContent ( sb ) ; return sb . toString ( ) ; }

Returns the text content of this node and its descendants.
@see #appendTextContent(Appendable)

Returns the text content of this node and its descendants .


public String getHtml() {
		LagartoDomBuilderConfig lagartoDomBuilderConfig;
		if (ownerDocument == null) {
			lagartoDomBuilderConfig = ((Document) this).getConfig();
		} else {
			lagartoDomBuilderConfig = ownerDocument.getConfig();
		}

		LagartoHtmlRenderer lagartoHtmlRenderer =
				lagartoDomBuilderConfig.getLagartoHtmlRenderer();

		return lagartoHtmlRenderer.toHtml(this, new StringBuilder());
	}

public String getHtml ( ) { LagartoDomBuilderConfig lagartoDomBuilderConfig ; if ( ownerDocument == null ) { lagartoDomBuilderConfig = ( ( Document ) this ) . getConfig ( ) ; } else { lagartoDomBuilderConfig = ownerDocument . getConfig ( ) ; } LagartoHtmlRenderer lagartoHtmlRenderer = lagartoDomBuilderConfig . getLagartoHtmlRenderer ( ) ; return lagartoHtmlRenderer . toHtml ( this , new StringBuilder ( ) ) ; }


public String getInnerHtml() {
		LagartoDomBuilderConfig lagartoDomBuilderConfig;
		if (ownerDocument == null) {
			lagartoDomBuilderConfig = ((Document) this).getConfig();
		} else {
			lagartoDomBuilderConfig = ownerDocument.getConfig();
		}

		LagartoHtmlRenderer lagartoHtmlRenderer =
				lagartoDomBuilderConfig.getLagartoHtmlRenderer();

		return lagartoHtmlRenderer.toInnerHtml(this, new StringBuilder());
	}

public String getInnerHtml ( ) { LagartoDomBuilderConfig lagartoDomBuilderConfig ; if ( ownerDocument == null ) { lagartoDomBuilderConfig = ( ( Document ) this ) . getConfig ( ) ; } else { lagartoDomBuilderConfig = ownerDocument . getConfig ( ) ; } LagartoHtmlRenderer lagartoHtmlRenderer = lagartoDomBuilderConfig . getLagartoHtmlRenderer ( ) ; return lagartoHtmlRenderer . toInnerHtml ( this , new StringBuilder ( ) ) ; }


protected void visitChildren(final NodeVisitor nodeVisitor) {
		if (childNodes != null) {
			for (int i = 0, childNodesSize = childNodes.size(); i < childNodesSize; i++) {
				Node childNode = childNodes.get(i);
				childNode.visit(nodeVisitor);
			}
		}
	}

protected void visitChildren ( final NodeVisitor nodeVisitor ) { if ( childNodes != null ) { for ( int i = 0 , childNodesSize = childNodes . size ( ) ; i < childNodesSize ; i ++ ) { Node childNode = childNodes . get ( i ) ; childNode . visit ( nodeVisitor ) ; } } }


public String getCssPath() {
		StringBuilder path = new StringBuilder();

		Node node = this;
		while (node != null) {
			String nodeName = node.getNodeName();
			if (nodeName != null) {
				StringBuilder sb = new StringBuilder();
				sb.append(' ').append(nodeName);
				String id = node.getAttribute("id");
				if (id != null) {
					sb.append('#').append(id);
				}
				path.insert(0, sb);
			}
			node = node.getParentNode();
		}

		if (path.charAt(0) == ' ') {
			return path.substring(1);
		}
		return path.toString();
	}

public String getCssPath ( ) { StringBuilder path = new StringBuilder ( ) ; Node node = this ; while ( node != null ) { String nodeName = node . getNodeName ( ) ; if ( nodeName != null ) { StringBuilder sb = new StringBuilder ( ) ; sb . append ( ' ' ) . append ( nodeName ) ; String id = node . getAttribute ( "id" ) ; if ( id != null ) { sb . append ( ' ' ) . append ( id ) ; } path . insert ( 0 , sb ) ; } node = node . getParentNode ( ) ; } if ( path . charAt ( 0 ) == ' ' ) { return path . substring ( 1 ) ; } return path . toString ( ) ; }

Returns CSS path to this node from document root.

Returns CSS path to this node from document root .


protected void onDecoraTag(final Tag tag) {
		String tagName = tag.getName().toString();

		if (tag.getType() == TagType.SELF_CLOSING) {
			checkNestedDecoraTags();
			decoraTagName = tagName.substring(7);
			decoraTagStart = tag.getTagPosition();
			decoraTagEnd = tag.getTagPosition() + tag.getTagLength();
			defineDecoraTag();
			return;
		}

		if (tag.getType() == TagType.START) {
			checkNestedDecoraTags();
			decoraTagName = tagName.substring(7);
			decoraTagStart = tag.getTagPosition();
			decoraTagDefaultValueStart = tag.getTagPosition() + tag.getTagLength();
			return;
		}

		// closed tag type
		decoraTagEnd = tag.getTagPosition() + tag.getTagLength();
		decoraTagDefaultValueEnd = tag.getTagPosition();
		defineDecoraTag();
	}

protected
void
onDecoraTag
(
final
Tag
tag
)
{
String
tagName
=
tag
.
getName
(
)
.
toString
(
)
;
if
(
tag
.
getType
(
)
==
TagType
.
SELF_CLOSING
)
{
checkNestedDecoraTags
(
)
;
decoraTagName
=
tagName
.
substring
(
7
)
;
decoraTagStart
=
tag
.
getTagPosition
(
)
;
decoraTagEnd
=
tag
.
getTagPosition
(
)
+
tag
.
getTagLength
(
)
;
defineDecoraTag
(
)
;
return
;
}
if
(
tag
.
getType
(
)
==
TagType
.
START
)
{
checkNestedDecoraTags
(
)
;
decoraTagName
=
tagName
.
substring
(
7
)
;
decoraTagStart
=
tag
.
getTagPosition
(
)
;
decoraTagDefaultValueStart
=
tag
.
getTagPosition
(
)
+
tag
.
getTagLength
(
)
;
return
;
}
// closed tag type
decoraTagEnd
=
tag
.
getTagPosition
(
)
+
tag
.
getTagLength
(
)
;
decoraTagDefaultValueEnd
=
tag
.
getTagPosition
(
)
;
defineDecoraTag
(
)
;
}


protected void onIdAttrStart(final Tag tag) {
		String id = tag.getId().toString().substring(7);
		String tagName;
		String idName;

		int dashIndex = id.indexOf('-');
		if (dashIndex == -1) {
			tagName = id;
			idName = null;
		} else {
			tagName = id.substring(0, dashIndex);
			idName = id.substring(dashIndex + 1);
		}

		if (tag.getType() == TagType.SELF_CLOSING) {
			checkNestedDecoraTags();
			decoraTagName = tagName;
			decoraIdName = idName;
			decoraTagStart = tag.getTagPosition();
			decoraTagEnd = tag.getTagPosition() + tag.getTagLength();
			defineDecoraTag();
			return;
		}

		if (tag.getType() == TagType.START) {
			checkNestedDecoraTags();
			decoraTagName = tagName;
			decoraIdName = idName;
			decoraTagStart = tag.getTagPosition();
			decoraTagDefaultValueStart = tag.getTagPosition() + tag.getTagLength();

			closingTagName = tag.getName().toString();
			closingTagDeepLevel = tag.getDeepLevel();
		}
	}

protected void onIdAttrStart ( final Tag tag ) { String id = tag . getId ( ) . toString ( ) . substring ( 7 ) ; String tagName ; String idName ; int dashIndex = id . indexOf ( ' ' ) ; if ( dashIndex == - 1 ) { tagName = id ; idName = null ; } else { tagName = id . substring ( 0 , dashIndex ) ; idName = id . substring ( dashIndex + 1 ) ; } if ( tag . getType ( ) == TagType . SELF_CLOSING ) { checkNestedDecoraTags ( ) ; decoraTagName = tagName ; decoraIdName = idName ; decoraTagStart = tag . getTagPosition ( ) ; decoraTagEnd = tag . getTagPosition ( ) + tag . getTagLength ( ) ; defineDecoraTag ( ) ; return ; } if ( tag . getType ( ) == TagType . START ) { checkNestedDecoraTags ( ) ; decoraTagName = tagName ; decoraIdName = idName ; decoraTagStart = tag . getTagPosition ( ) ; decoraTagDefaultValueStart = tag . getTagPosition ( ) + tag . getTagLength ( ) ; closingTagName = tag . getName ( ) . toString ( ) ; closingTagDeepLevel = tag . getDeepLevel ( ) ; } }

Handle open and empty ID attribute tags.

Handle open and empty ID attribute tags .


protected void defineDecoraTag() {
		DecoraTag decoraTag =
				decoraTagDefaultValueStart == 0 ?
					new DecoraTag(decoraTagName, decoraIdName, decoraTagStart, decoraTagEnd) :
					new DecoraTag(
							decoraTagName, decoraIdName,
							decoraTagStart, decoraTagEnd,
							decoraTagDefaultValueStart, decoraTagDefaultValueEnd - decoraTagDefaultValueStart);

		decoraTags.add(decoraTag);
		decoraTagName = null;
		decoraIdName = null;
		closingTagName = null;
		decoraTagDefaultValueStart = 0;
	}

protected void defineDecoraTag ( ) { DecoraTag decoraTag = decoraTagDefaultValueStart == 0 ? new DecoraTag ( decoraTagName , decoraIdName , decoraTagStart , decoraTagEnd ) : new DecoraTag ( decoraTagName , decoraIdName , decoraTagStart , decoraTagEnd , decoraTagDefaultValueStart , decoraTagDefaultValueEnd - decoraTagDefaultValueStart ) ; decoraTags . add ( decoraTag ) ; decoraTagName = null ; decoraIdName = null ; closingTagName = null ; decoraTagDefaultValueStart = 0 ; }

Defines Decora tag position inside decorator content.
Resets current Decora tag tracking.

Defines Decora tag position inside decorator content . Resets current Decora tag tracking .


@Override
	public JoyProxetta addProxyAspect(final ProxyAspect proxyAspect) {
		requireNotStarted(proxetta);
		this.proxyAspects.add(proxyAspect);
		return this;
	}

@ Override public JoyProxetta addProxyAspect ( final ProxyAspect proxyAspect ) { requireNotStarted ( proxetta ) ; this . proxyAspects . add ( proxyAspect ) ; return this ; }


public void addRootPackage(final String rootPackage, String mapping) {
		if (packages == null) {
			packages = new String[0];
		}
		if (mappings == null) {
			mappings = new String[0];
		}

		// fix mapping
		if (mapping.length() > 0) {
			// mapping must start with the slash
			if (!mapping.startsWith(StringPool.SLASH)) {
				mapping = StringPool.SLASH + mapping;
			}
			// mapping must NOT end with the slash
			if (mapping.endsWith(StringPool.SLASH)) {
				mapping = StringUtil.substring(mapping, 0, -1);
			}
		}

		// detect duplicates
		for (int i = 0; i < packages.length; i++) {
			if (packages[i].equals(rootPackage)) {
				if (mappings[i].equals(mapping)) {
					// both package and the mappings are the same
					return;
				}
				throw new MadvocException("Different mappings for the same root package: " + rootPackage);
			}
		}

		packages = ArraysUtil.append(packages, rootPackage);
		mappings = ArraysUtil.append(mappings, mapping);
	}

Adds root package and its path mapping. Duplicate root packages
are ignored, if mapping path is equals, otherwise exception is thrown.

Adds root package and its path mapping . Duplicate root packages are ignored if mapping path is equals otherwise exception is thrown .


public void addRootPackageOf(final Class actionClass, final String mapping) {
		addRootPackage(actionClass.getPackage().getName(), mapping);
	}

public void addRootPackageOf ( final Class actionClass , final String mapping ) { addRootPackage ( actionClass . getPackage ( ) . getName ( ) , mapping ) ; }

Sets root package to package of given class.

Sets root package to package of given class .


public String findRootPackageForActionPath(final String actionPath) {
		if (mappings == null) {
			return null;
		}

		int ndx = -1;
		int delta = Integer.MAX_VALUE;

		for (int i = 0; i < mappings.length; i++) {
			String mapping = mappings[i];

			boolean found = false;
			if (actionPath.equals(mapping)) {
				found = true;
			} else {
				mapping += StringPool.SLASH;
				if (actionPath.startsWith(mapping)) {
					found = true;
				}
			}

			if (found) {
				int distance = actionPath.length() - mapping.length();
				if (distance < delta) {
					ndx = i;
					delta = distance;
				}
			}
		}

		if (ndx == -1) {
			return null;
		}

		return packages[ndx];
	}

public String findRootPackageForActionPath ( final String actionPath ) { if ( mappings == null ) { return null ; } int ndx = - 1 ; int delta = Integer . MAX_VALUE ; for ( int i = 0 ; i < mappings . length ; i ++ ) { String mapping = mappings [ i ] ; boolean found = false ; if ( actionPath . equals ( mapping ) ) { found = true ; } else { mapping += StringPool . SLASH ; if ( actionPath . startsWith ( mapping ) ) { found = true ; } } if ( found ) { int distance = actionPath . length ( ) - mapping . length ( ) ; if ( distance < delta ) { ndx = i ; delta = distance ; } } } if ( ndx == - 1 ) { return null ; } return packages [ ndx ] ; }

Finds closest root package for the given action path.

Finds closest root package for the given action path .


public static String resolveValidationMessage(final HttpServletRequest request, final Violation violation) {
		ValidationConstraint vc = violation.getConstraint();
		String key = vc != null ? vc.getClass().getName() : violation.getName();
		String msg = LocalizationUtil.findMessage(request, key);
		if (msg != null) {
			return beanTemplateParser.parseWithBean(msg, violation);
		}
		return null;
	}

public static String resolveValidationMessage ( final HttpServletRequest request , final Violation violation ) { ValidationConstraint vc = violation . getConstraint ( ) ; String key = vc != null ? vc . getClass ( ) . getName ( ) : violation . getName ( ) ; String msg = LocalizationUtil . findMessage ( request , key ) ; if ( msg != null ) { return beanTemplateParser . parseWithBean ( msg , violation ) ; } return null ; }

Prepares validation messages.
Key is either validation constraint class name or violation name.

Prepares validation messages . Key is either validation constraint class name or violation name .


public BeanReferences removeDuplicateNames() {
		if (names.length < 2) {
			return this;
		}

		int nullCount = 0;

		for (int i = 1; i < names.length; i++) {
			String thisRef = names[i];

			if (thisRef == null) {
				nullCount++;
				continue;
			}

			for (int j = 0; j < i; j++) {
				if (names[j] == null) {
					continue;
				}
				if (thisRef.equals(names[j])) {
					names[i] = null;
					break;
				}
			}
		}

		if (nullCount == 0) {
			return this;
		}

		String[] newRefs = new String[names.length - nullCount];
		int ndx = 0;

		for (String name : names) {
			if (name == null) {
				continue;
			}
			newRefs[ndx] = name;
			ndx++;
		}

		return new BeanReferences(newRefs);
	}

public BeanReferences removeDuplicateNames ( ) { if ( names . length < 2 ) { return this ; } int nullCount = 0 ; for ( int i = 1 ; i < names . length ; i ++ ) { String thisRef = names [ i ] ; if ( thisRef == null ) { nullCount ++ ; continue ; } for ( int j = 0 ; j < i ; j ++ ) { if ( names [ j ] == null ) { continue ; } if ( thisRef . equals ( names [ j ] ) ) { names [ i ] = null ; break ; } } } if ( nullCount == 0 ) { return this ; } String [ ] newRefs = new String [ names . length - nullCount ] ; int ndx = 0 ; for ( String name : names ) { if ( name == null ) { continue ; } newRefs [ ndx ] = name ; ndx ++ ; } return new BeanReferences ( newRefs ) ; }

Removes later duplicated references in an array.
Returns new instance of BeanReferences if there was changes,
otherwise returns the same instance.

Removes later duplicated references in an array . Returns new instance of BeanReferences if there was changes otherwise returns the same instance .


@Override
	public JoyProps addPropsFile(final String namePattern) {
		requireNotStarted(props);
		this.propsNamePatterns.add(namePattern);
		return this;
	}

@ Override public JoyProps addPropsFile ( final String namePattern ) { requireNotStarted ( props ) ; this . propsNamePatterns . add ( namePattern ) ; return this ; }


public void forEachTarget(final Consumer<Target> targetConsumer) {
		for (final Target target : targets) {
			targetConsumer.accept(target);
		}
	}

public void forEachTarget ( final Consumer < Target > targetConsumer ) { for ( final Target target : targets ) { targetConsumer . accept ( target ) ; } }


public void forEachTargetAndIn(final MadvocScope scope, final BiConsumer<Target, InjectionPoint> biConsumer) {
		for (final Target target : targets) {
			final ScopeData scopeData = target.scopeData();

			if (scopeData.in() == null) {
				continue;
			}
			for (final InjectionPoint in : scopeData.in()) {
				if (in.scope() != scope) {
					continue;
				}
				biConsumer.accept(target, in);
			}
		}
	}

public void forEachTargetAndIn ( final MadvocScope scope , final BiConsumer < Target , InjectionPoint > biConsumer ) { for ( final Target target : targets ) { final ScopeData scopeData = target . scopeData ( ) ; if ( scopeData . in ( ) == null ) { continue ; } for ( final InjectionPoint in : scopeData . in ( ) ) { if ( in . scope ( ) != scope ) { continue ; } biConsumer . accept ( target , in ) ; } } }

Iterates all targets and for each target iterates all IN injection points of given scope.

Iterates all targets and for each target iterates all IN injection points of given scope .


public void forEachTargetAndOut(final MadvocScope scope, final BiConsumer<Target, InjectionPoint> biConsumer) {
		for (final Target target : targets) {
			final ScopeData scopeData = target.scopeData();

			if (scopeData.out() == null) {
				continue;
			}
			for (final InjectionPoint out : scopeData.out()) {
				if (out.scope() != scope) {
					continue;
				}
				biConsumer.accept(target, out);
			}
		}
	}

public void forEachTargetAndOut ( final MadvocScope scope , final BiConsumer < Target , InjectionPoint > biConsumer ) { for ( final Target target : targets ) { final ScopeData scopeData = target . scopeData ( ) ; if ( scopeData . out ( ) == null ) { continue ; } for ( final InjectionPoint out : scopeData . out ( ) ) { if ( out . scope ( ) != scope ) { continue ; } biConsumer . accept ( target , out ) ; } } }

Iterates all targets and for each target iterates all OUT injection points of given scope.

Iterates all targets and for each target iterates all OUT injection points of given scope .


public Object[] extractParametersValues() {
		final Object[] values = new Object[targets.length - 1];

		for (int i = 1; i < targets.length; i++) {
			values[i - 1] = targets[i].value();
		}

		return values;
	}

public Object [ ] extractParametersValues ( ) { final Object [ ] values = new Object [ targets . length - 1 ] ; for ( int i = 1 ; i < targets . length ; i ++ ) { values [ i - 1 ] = targets [ i ] . value ( ) ; } return values ; }

Collects all parameters from target into an array.

Collects all parameters from target into an array .


protected Target[] makeTargets(final Target actionTarget, final MethodParam[] methodParams) {
		if (methodParams == null) {
			// action does not have method parameters, so there is just one target
			return new Target[]{actionTarget};
		}

		// action has method arguments, so there is more then one target
		final Target[] target = new Target[methodParams.length + 1];
		target[0] = actionTarget;

		final Object action = actionTarget.value();

		for (int i = 0; i < methodParams.length; i++) {
			final MethodParam methodParam = methodParams[i];
			final Class paramType = methodParam.type();

			final Target paramTarget;

			if (methodParam.annotationType() == null) {
				// parameter is NOT annotated, create new value for the target
				// the class itself will be a base class, and should be scanned

				final ScopeData newScopeData = methodParam.scopeData().inspector().inspectClassScopesWithCache(paramType);
				paramTarget = Target.ofValue(createActionMethodArgument(paramType, action), newScopeData);
			}
			else if (methodParam.annotationType() == Out.class) {
				// parameter is annotated with *only* OUT annotation
				// create the output value now AND to save the type
				paramTarget = Target.ofMethodParam(methodParam, createActionMethodArgument(paramType, action));
			}
			else {
				// parameter is annotated with any IN annotation
				// create target with NO value, as the value will be created later
				paramTarget = Target.ofMethodParam(methodParam, type -> createActionMethodArgument(type, action));
			}

			target[i + 1] = paramTarget;
		}
		return target;
	}

Joins action and parameters into one single array of Targets.

Joins action and parameters into one single array of Targets .


@SuppressWarnings({"unchecked", "NullArgumentToVariableArgMethod"})
	protected Object createActionMethodArgument(final Class type, final Object action) {
		try {
			if (type.getEnclosingClass() == null || Modifier.isStatic(type.getModifiers())) {
				// regular or static class
				return ClassUtil.newInstance(type);
			} else {
				// member class
				Constructor ctor = type.getDeclaredConstructor(type.getDeclaringClass());
				ctor.setAccessible(true);
				return ctor.newInstance(action);
			}
		} catch (Exception ex) {
			throw new MadvocException(ex);
		}
	}

@
SuppressWarnings
(
{
"unchecked"
,
"NullArgumentToVariableArgMethod"
}
)
protected
Object
createActionMethodArgument
(
final
Class
type
,
final
Object
action
)
{
try
{
if
(
type
.
getEnclosingClass
(
)
==
||
Modifier
.
isStatic
(
type
.
getModifiers
(
)
)
)
{
// regular or static class
return
ClassUtil
.
newInstance
(
type
)
;
}
else
{
// member class
Constructor
ctor
=
type
.
getDeclaredConstructor
(
type
.
getDeclaringClass
(
)
)
;
ctor
.
setAccessible
(
true
)
;
return
ctor
.
newInstance
(
action
)
;
}
}
catch
(
Exception
ex
)
{
throw
new
MadvocException
(
ex
)
;
}
}


@Override
	public void sessionCreated(final HttpSessionEvent httpSessionEvent) {
		HttpSession session = httpSessionEvent.getSession();
		sessionMap.putIfAbsent(session.getId(), session);

		for (HttpSessionListener listener : listeners) {
			listener.sessionCreated(httpSessionEvent);
		}
	}

@ Override public void sessionCreated ( final HttpSessionEvent httpSessionEvent ) { HttpSession session = httpSessionEvent . getSession ( ) ; sessionMap . putIfAbsent ( session . getId ( ) , session ) ; for ( HttpSessionListener listener : listeners ) { listener . sessionCreated ( httpSessionEvent ) ; } }

Stores session in map and broadcasts event to registered listeners.

Stores session in map and broadcasts event to registered listeners .


@Override
	public void sessionDestroyed(final HttpSessionEvent httpSessionEvent) {
		HttpSession session = httpSessionEvent.getSession();
		sessionMap.remove(session.getId());

		for (HttpSessionListener listener : listeners) {
			listener.sessionDestroyed(httpSessionEvent);
		}
	}

@ Override public void sessionDestroyed ( final HttpSessionEvent httpSessionEvent ) { HttpSession session = httpSessionEvent . getSession ( ) ; sessionMap . remove ( session . getId ( ) ) ; for ( HttpSessionListener listener : listeners ) { listener . sessionDestroyed ( httpSessionEvent ) ; } }

Removes session from a map and broadcasts event to registered listeners.

Removes session from a map and broadcasts event to registered listeners .


public JsonArray add(Object value) {
		Objects.requireNonNull(value);

		value = JsonObject.resolveValue(value);

		list.add(value);
		return this;
	}

public JsonArray add ( Object value ) { Objects . requireNonNull ( value ) ; value = JsonObject . resolveValue ( value ) ; list . add ( value ) ; return this ; }


public JsonArray addAll(final JsonArray array) {
		Objects.requireNonNull(array);
		list.addAll(array.list);
		return this;
	}

public JsonArray addAll ( final JsonArray array ) { Objects . requireNonNull ( array ) ; list . addAll ( array . list ) ; return this ; }

Appends all of the elements in the specified array to the end of this JSON array.

Appends all of the elements in the specified array to the end of this JSON array .


public Object remove(final int pos) {
		Object removed = list.remove(pos);
		if (removed instanceof Map) {
			return new JsonObject((Map) removed);
		}
		if (removed instanceof ArrayList) {
			return new JsonArray((List) removed);
		}
		return removed;
	}

public Object remove ( final int pos ) { Object removed = list . remove ( pos ) ; if ( removed instanceof Map ) { return new JsonObject ( ( Map ) removed ) ; } if ( removed instanceof ArrayList ) { return new JsonArray ( ( List ) removed ) ; } return removed ; }

Removes the value at the specified position in the JSON array.

Removes the value at the specified position in the JSON array .


protected String resolveTarget(final ActionRequest actionRequest, final String resultValue) {
		String resultBasePath = actionRequest.getActionRuntime().getResultBasePath();

		ResultPath resultPath = resultMapper.resolveResultPath(resultBasePath, resultValue);

		String actionPath = resultPath.path();
		String path = actionPath;
		String value = resultPath.value();

		if (StringUtil.isEmpty(value)) {
			value = null;
		}

		String target;

		while (true) {

			// variant #1: with value
			if (value != null) {
				if (path == null) {
					// only value remains
					int lastSlashNdx = actionPath.lastIndexOf('/');
					if (lastSlashNdx != -1) {
						target = actionPath.substring(0, lastSlashNdx + 1) + value;
					} else {
						target = '/' + value;
					}
				} else {
					target = path + '.' + value;
				}

				target = locateTarget(actionRequest, target);

				if (target != null) {
						break;
				}
			}

			if (path != null) {
				// variant #2: without value

				target = locateTarget(actionRequest, path);

				if (target != null) {
					break;
				}
			}

			// continue

			if (path == null) {
				// path not found
				return null;
			}

			int dotNdx = MadvocUtil.lastIndexOfDotAfterSlash(path);
			if (dotNdx == -1) {
				path = null;
			} else {
				path = path.substring(0, dotNdx);
			}
		}
		return target;
	}

protected
String
resolveTarget
(
final
ActionRequest
actionRequest
,
final
String
resultValue
)
{
String
resultBasePath
=
actionRequest
.
getActionRuntime
(
)
.
getResultBasePath
(
)
;
ResultPath
resultPath
=
resultMapper
.
resolveResultPath
(
resultBasePath
,
resultValue
)
;
String
actionPath
=
resultPath
.
path
(
)
;
String
path
=
actionPath
;
String
value
=
resultPath
.
value
(
)
;
if
(
StringUtil
.
isEmpty
(
value
)
)
{
value
=
;
}
String
target
;
while
(
true
)
{
// variant #1: with value
if
(
value
!=
)
{
if
(
path
==
)
{
// only value remains
int
lastSlashNdx
=
actionPath
.
lastIndexOf
(
'
'
)
;
if
(
lastSlashNdx
!=
1
)
{
target
=
actionPath
.
substring
(
0
,
lastSlashNdx
+
1
)
+
value
;
}
else
{
target
=
'
'
+
value
;
}
}
else
{
target
=
path
+
'
'
+
value
;
}
target
=
locateTarget
(
actionRequest
,
target
)
;
if
(
target
!=
)
{
break
;
}
}
if
(
path
!=
)
{
// variant #2: without value
target
=
locateTarget
(
actionRequest
,
path
)
;
if
(
target
!=
)
{
break
;
}
}
// continue
if
(
path
==
)
{
// path not found
return
;
}
int
dotNdx
=
MadvocUtil
.
lastIndexOfDotAfterSlash
(
path
)
;
if
(
dotNdx
==
1
)
{
path
=
;
}
else
{
path
=
path
.
substring
(
0
,
dotNdx
)
;
}
}
return
target
;
}

Locates the target file from action path and the result value.

Locates the target file from action path and the result value .


protected void targetNotFound(final ActionRequest actionRequest, final String actionAndResultPath) throws IOException {
		final HttpServletResponse response = actionRequest.getHttpServletResponse();

		if (!response.isCommitted()) {
			response.sendError(SC_NOT_FOUND, "Result not found: " + actionAndResultPath);
		}
	}

protected
void
targetNotFound
(
final
ActionRequest
actionRequest
,
final
String
actionAndResultPath
)
throws
IOException
{
final
HttpServletResponse
response
=
actionRequest
.
getHttpServletResponse
(
)
;
if
(
!
response
.
isCommitted
(
)
)
{
response
.
sendError
(
SC_NOT_FOUND
,
"Result not found: "
+
actionAndResultPath
)
;
}
}

Called when target not found. By default sends 404 to the response.

Called when target not found . By default sends 404 to the response .


protected String valueToString(final String name, final Object valueObject) {
		if (!valueObject.getClass().isArray()) {
			return valueObject.toString();
		}

		// array
		String[] array = (String[]) valueObject;

		if (valueNameIndexes == null) {
			valueNameIndexes = new HashMap<>();
		}

		MutableInteger index = valueNameIndexes.get(name);
		if (index == null) {
			index = new MutableInteger(0);
			valueNameIndexes.put(name, index);
		}

		if (index.value >= array.length) {
			return null;
		}

		String result = array[index.value];

		index.value++;

		return result;
	}

protected
String
valueToString
(
final
String
name
,
final
Object
valueObject
)
{
if
(
!
valueObject
.
getClass
(
)
.
isArray
(
)
)
{
return
valueObject
.
toString
(
)
;
}
// array
String
[
]
array
=
(
String
[
]
)
valueObject
;
if
(
valueNameIndexes
==
)
{
valueNameIndexes
=
new
HashMap
<>
(
)
;
}
MutableInteger
index
=
valueNameIndexes
.
get
(
name
)
;
if
(
index
==
)
{
index
=
new
MutableInteger
(
0
)
;
valueNameIndexes
.
put
(
name
,
index
)
;
}
if
(
index
.
value
>=
array
.
length
)
{
return
;
}
String
result
=
array
[
index
.
value
]
;
index
.
value
++
;
return
result
;
}


@SuppressWarnings("unchecked")
	public <T extends ActionFilter> MadvocRouter filter(final Class<T> actionFilterClass) {
		filtersManager.resolve(actionFilterClass);
		return this;
	}

@ SuppressWarnings ( "unchecked" ) public < T extends ActionFilter > MadvocRouter filter ( final Class < T > actionFilterClass ) { filtersManager . resolve ( actionFilterClass ) ; return this ; }

Returns action filter instance for further configuration.

Returns action filter instance for further configuration .


public String getPseudoFunctionName() {
		String name = getClass().getSimpleName().toLowerCase();
		name = name.replace('_', '-');
		return name;
	}

public String getPseudoFunctionName ( ) { String name = getClass ( ) . getSimpleName ( ) . toLowerCase ( ) ; name = name . replace ( ' ' , ' ' ) ; return name ; }


public PropertyInjectionPoint[] resolve(Class type, final boolean autowire) {
		final List<PropertyInjectionPoint> list = new ArrayList<>();
		final Set<String> usedPropertyNames = new HashSet<>();

		// lookup fields
		while (type != Object.class) {

			final ClassDescriptor cd = ClassIntrospector.get().lookup(type);
			final PropertyDescriptor[] allPropertyDescriptors = cd.getAllPropertyDescriptors();

			for (PropertyDescriptor propertyDescriptor : allPropertyDescriptors) {

				if (propertyDescriptor.isGetterOnly()) {
					continue;
				}

				if (usedPropertyNames.contains(propertyDescriptor.getName())) {
					continue;
				}

				Class propertyType = propertyDescriptor.getType();
				if (ClassUtil.isTypeOf(propertyType, Collection.class)) {
					continue;
				}

				BeanReferences reference = referencesResolver.readReferenceFromAnnotation(propertyDescriptor);

				if (reference == null) {
					if (!autowire) {
						continue;
					} else {
						reference = referencesResolver.buildDefaultReference(propertyDescriptor);
					}
				}

				list.add(new PropertyInjectionPoint(propertyDescriptor, reference));

				usedPropertyNames.add(propertyDescriptor.getName());
			}

			// go to the supertype
			type = type.getSuperclass();
		}

		final PropertyInjectionPoint[] fields;

		if (list.isEmpty()) {
			fields = PropertyInjectionPoint.EMPTY;
		} else {
			fields = list.toArray(new PropertyInjectionPoint[0]);
		}

		return fields;
	}

public
PropertyInjectionPoint
[
]
resolve
(
Class
type
,
final
boolean
autowire
)
{
final
List
<
PropertyInjectionPoint
>
list
=
new
ArrayList
<>
(
)
;
final
Set
<
String
>
usedPropertyNames
=
new
HashSet
<>
(
)
;
// lookup fields
while
(
type
!=
Object
.
class
)
{
final
ClassDescriptor
cd
=
ClassIntrospector
.
get
(
)
.
lookup
(
type
)
;
final
PropertyDescriptor
[
]
allPropertyDescriptors
=
cd
.
getAllPropertyDescriptors
(
)
;
for
(
PropertyDescriptor
propertyDescriptor
:
allPropertyDescriptors
)
{
if
(
propertyDescriptor
.
isGetterOnly
(
)
)
{
continue
;
}
if
(
usedPropertyNames
.
contains
(
propertyDescriptor
.
getName
(
)
)
)
{
continue
;
}
Class
propertyType
=
propertyDescriptor
.
getType
(
)
;
if
(
ClassUtil
.
isTypeOf
(
propertyType
,
Collection
.
class
)
)
{
continue
;
}
BeanReferences
reference
=
referencesResolver
.
readReferenceFromAnnotation
(
propertyDescriptor
)
;
if
(
reference
==
)
{
if
(
!
autowire
)
{
continue
;
}
else
{
reference
=
referencesResolver
.
buildDefaultReference
(
propertyDescriptor
)
;
}
}
list
.
add
(
new
PropertyInjectionPoint
(
propertyDescriptor
,
reference
)
)
;
usedPropertyNames
.
add
(
propertyDescriptor
.
getName
(
)
)
;
}
// go to the supertype
type
=
type
.
getSuperclass
(
)
;
}
final
PropertyInjectionPoint
[
]
fields
;
if
(
list
.
isEmpty
(
)
)
{
fields
=
PropertyInjectionPoint
.
EMPTY
;
}
else
{
fields
=
list
.
toArray
(
new
PropertyInjectionPoint
[
0
]
)
;
}
return
fields
;
}

Resolves all properties for given type .


private Socket createSocks4ProxySocket(final String host, final int port) {
		Socket socket = null;
		final String proxyHost = proxy.getProxyAddress();
		final int proxyPort = proxy.getProxyPort();
		final String user = proxy.getProxyUsername();

		try {
			socket = Sockets.connect(proxyHost, proxyPort, connectionTimeout);

			final InputStream in = socket.getInputStream();
			final OutputStream out = socket.getOutputStream();

			socket.setTcpNoDelay(true);

			byte[] buf = new byte[1024];

			// 1) CONNECT

			int index = 0;
			buf[index++] = 4;
			buf[index++] = 1;

			buf[index++] = (byte) (port >>> 8);
			buf[index++] = (byte) (port & 0xff);

			InetAddress addr = InetAddress.getByName(host);
			byte[] byteAddress = addr.getAddress();
			for (byte byteAddres : byteAddress) {
				buf[index++] = byteAddres;
			}

			if (user != null) {
				System.arraycopy(user.getBytes(), 0, buf, index, user.length());
				index += user.length();
			}
			buf[index++] = 0;
			out.write(buf, 0, index);

			// 2) RESPONSE

			int len = 6;
			int s = 0;
			while (s < len) {
				int i = in.read(buf, s, len - s);
				if (i <= 0) {
					throw new HttpException(ProxyInfo.ProxyType.SOCKS4, "stream is closed");
				}
				s += i;
			}
			if (buf[0] != 0) {
				throw new HttpException(ProxyInfo.ProxyType.SOCKS4, "proxy returned VN " + buf[0]);
			}
			if (buf[1] != 90) {
				try {
					socket.close();
				} catch (Exception ignore) {
				}
				throw new HttpException(ProxyInfo.ProxyType.SOCKS4, "proxy returned CD " + buf[1]);
			}

			byte[] temp = new byte[2];
			in.read(temp, 0, 2);

			return socket;
		} catch (RuntimeException rtex) {
			closeSocket(socket);
			throw rtex;
		} catch (Exception ex) {
			closeSocket(socket);
			throw new HttpException(ProxyInfo.ProxyType.SOCKS4, ex.toString(), ex);
		}
	}

private
Socket
createSocks4ProxySocket
(
final
String
host
,
final
int
port
)
{
Socket
socket
=
;
final
String
proxyHost
=
proxy
.
getProxyAddress
(
)
;
final
int
proxyPort
=
proxy
.
getProxyPort
(
)
;
final
String
user
=
proxy
.
getProxyUsername
(
)
;
try
{
socket
=
Sockets
.
connect
(
proxyHost
,
proxyPort
,
connectionTimeout
)
;
final
InputStream
in
=
socket
.
getInputStream
(
)
;
final
OutputStream
out
=
socket
.
getOutputStream
(
)
;
socket
.
setTcpNoDelay
(
true
)
;
byte
[
]
buf
=
new
byte
[
1024
]
;
// 1) CONNECT
int
index
=
0
;
buf
[
index
++
]
=
4
;
buf
[
index
++
]
=
1
;
buf
[
index
++
]
=
(
byte
)
(
port
>>>
8
)
;
buf
[
index
++
]
=
(
byte
)
(
port
&
0xff
)
;
InetAddress
addr
=
InetAddress
.
getByName
(
host
)
;
byte
[
]
byteAddress
=
addr
.
getAddress
(
)
;
for
(
byte
byteAddres
:
byteAddress
)
{
buf
[
index
++
]
=
byteAddres
;
}
if
(
user
!=
)
{
System
.
arraycopy
(
user
.
getBytes
(
)
,
0
,
buf
,
index
,
user
.
length
(
)
)
;
index
+=
user
.
length
(
)
;
}
buf
[
index
++
]
=
0
;
out
.
write
(
buf
,
0
,
index
)
;
// 2) RESPONSE
int
len
=
6
;
int
s
=
0
;
while
(
s
<
len
)
{
int
i
=
in
.
read
(
buf
,
s
,
len
s
)
;
if
(
i
<=
0
)
{
throw
new
HttpException
(
ProxyInfo
.
ProxyType
.
SOCKS4
,
"stream is closed"
)
;
}
s
+=
i
;
}
if
(
buf
[
0
]
!=
0
)
{
throw
new
HttpException
(
ProxyInfo
.
ProxyType
.
SOCKS4
,
"proxy returned VN "
+
buf
[
0
]
)
;
}
if
(
buf
[
1
]
!=
90
)
{
try
{
socket
.
close
(
)
;
}
catch
(
Exception
ignore
)
{
}
throw
new
HttpException
(
ProxyInfo
.
ProxyType
.
SOCKS4
,
"proxy returned CD "
+
buf
[
1
]
)
;
}
byte
[
]
temp
=
new
byte
[
2
]
;
in
.
read
(
temp
,
0
,
2
)
;
return
socket
;
}
catch
(
RuntimeException
rtex
)
{
closeSocket
(
socket
)
;
throw
rtex
;
}
catch
(
Exception
ex
)
{
closeSocket
(
socket
)
;
throw
new
HttpException
(
ProxyInfo
.
ProxyType
.
SOCKS4
,
ex
.
toString
(
)
,
ex
)
;
}
}

Connects to the SOCKS4 proxy and returns proxified socket.

Connects to the SOCKS4 proxy and returns proxified socket .


final int getAttributeCount() {
    int count = 0;
    Attribute attribute = this;
    while (attribute != null) {
      count += 1;
      attribute = attribute.nextAttribute;
    }
    return count;
  }

final int getAttributeCount ( ) { int count = 0 ; Attribute attribute = this ; while ( attribute != null ) { count += 1 ; attribute = attribute . nextAttribute ; } return count ; }

Returns the number of attributes of the attribute list that begins with this attribute.

@return the number of attributes of the attribute list that begins with this attribute.

Returns the number of attributes of the attribute list that begins with this attribute .


public Set<ActionResult> getAllActionResults() {
		final Set<ActionResult> set = new HashSet<>(allResults.size());
		allResults.forEachValue(set::add);
		return set;
	}

public Set < ActionResult > getAllActionResults ( ) { final Set < ActionResult > set = new HashSet <> ( allResults . size ( ) ) ; allResults . forEachValue ( set :: add ) ; return set ; }


public static boolean equalsOne(final char c, final CharSequence match) {
		for (int i = 0; i < match.length(); i++) {
			char aMatch = match.charAt(i);
			if (c == aMatch) {
				return true;
			}
		}
		return false;
	}

public static boolean equalsOne ( final char c , final CharSequence match ) { for ( int i = 0 ; i < match . length ( ) ; i ++ ) { char aMatch = match . charAt ( i ) ; if ( c == aMatch ) { return true ; } } return false ; }

Match if one character equals to any of the given character.

@return true if characters match any character from given array,
otherwise false

Match if one character equals to any of the given character .


public static int findFirstEqual(final CharSequence source, final int index, final CharSequence match) {
		for (int i = index; i < source.length(); i++) {
			if (equalsOne(source.charAt(i), match)) {
				return i;
			}
		}
		return -1;
	}

public static int findFirstEqual ( final CharSequence source , final int index , final CharSequence match ) { for ( int i = index ; i < source . length ( ) ; i ++ ) { if ( equalsOne ( source . charAt ( i ) , match ) ) { return i ; } } return - 1 ; }

Finds index of the first character in given charsequence the matches any from the
given set of characters.

@return index of matched character or -1

Finds index of the first character in given charsequence the matches any from the given set of characters .


public static int findFirstEqual(final char[] source, final int index, final char match) {
		for (int i = index; i < source.length; i++) {
			if (source[i] == match) {
				return i;
			}
		}
		return -1;
	}

public static int findFirstEqual ( final char [ ] source , final int index , final char match ) { for ( int i = index ; i < source . length ; i ++ ) { if ( source [ i ] == match ) { return i ; } } return - 1 ; }

Finds index of the first character in given array the matches any from the
given set of characters.

@return index of matched character or -1

Finds index of the first character in given array the matches any from the given set of characters .


public CommandLine args(final String... arguments) {
		if (arguments != null && arguments.length > 0) {
			Collections.addAll(cmdLine, arguments);
		}

		return this;
	}

public CommandLine args ( final String ... arguments ) { if ( arguments != null && arguments . length > 0 ) { Collections . addAll ( cmdLine , arguments ) ; } return this ; }


public CommandLine env(final String key, final String value) {
		if (env == null) {
			env = new HashMap<>();
		}
		env.put(key, value);
		return this;
	}

public CommandLine env ( final String key , final String value ) { if ( env == null ) { env = new HashMap <> ( ) ; } env . put ( key , value ) ; return this ; }


public ProcessRunner.ProcessResult run() {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();

		out = err = baos;

		try {
			baos.write(StringUtil.join(cmdLine, ' ').getBytes());
			baos.write(StringPool.BYTES_NEW_LINE);
		}
		catch (IOException ignore) {
		}

		ProcessBuilder processBuilder = new ProcessBuilder();

		processBuilder.command(cmdLine);

		if (cleanEnvironment) {
			processBuilder.environment().clear();
		}
		if (env != null) {
			processBuilder.environment().putAll(env);
		}

		processBuilder.directory(workingDirectory);

		Process process = null;
		try {
			process = processBuilder.start();
		}
		catch (IOException ioex) {
			return writeException(baos, ioex);
		}

		StreamGobbler outputGobbler = new StreamGobbler(process.getInputStream(), out, outPrefix);
		StreamGobbler errorGobbler = new StreamGobbler(process.getErrorStream(), err, errPrefix);

		outputGobbler.start();
		errorGobbler.start();

		int result;

		try {
			result = process.waitFor();
		}
		catch (InterruptedException iex) {
			return writeException(baos, iex);
		}

		outputGobbler.waitFor();
		errorGobbler.waitFor();

		return new ProcessRunner.ProcessResult(result, baos.toString());
	}

public ProcessRunner . ProcessResult run ( ) { ByteArrayOutputStream baos = new ByteArrayOutputStream ( ) ; out = err = baos ; try { baos . write ( StringUtil . join ( cmdLine , ' ' ) . getBytes ( ) ) ; baos . write ( StringPool . BYTES_NEW_LINE ) ; } catch ( IOException ignore ) { } ProcessBuilder processBuilder = new ProcessBuilder ( ) ; processBuilder . command ( cmdLine ) ; if ( cleanEnvironment ) { processBuilder . environment ( ) . clear ( ) ; } if ( env != null ) { processBuilder . environment ( ) . putAll ( env ) ; } processBuilder . directory ( workingDirectory ) ; Process process = null ; try { process = processBuilder . start ( ) ; } catch ( IOException ioex ) { return writeException ( baos , ioex ) ; } StreamGobbler outputGobbler = new StreamGobbler ( process . getInputStream ( ) , out , outPrefix ) ; StreamGobbler errorGobbler = new StreamGobbler ( process . getErrorStream ( ) , err , errPrefix ) ; outputGobbler . start ( ) ; errorGobbler . start ( ) ; int result ; try { result = process . waitFor ( ) ; } catch ( InterruptedException iex ) { return writeException ( baos , iex ) ; } outputGobbler . waitFor ( ) ; errorGobbler . waitFor ( ) ; return new ProcessRunner . ProcessResult ( result , baos . toString ( ) ) ; }

Runs command and returns process result.

Runs command and returns process result .


public static void invoke(final Object listener, final Class listenerType) {
		if (listenerType == Init.class) {
			((Init) listener).init();
			return;
		}
		if (listenerType == Start.class) {
			((Start) listener).start();
			return;
		}
		if (listenerType == Ready.class) {
			((Ready) listener).ready();
			return;
		}
		if (listenerType == Stop.class) {
			((Stop) listener).stop();
			return;
		}
		throw new MadvocException("Invalid listener");
	}

public
static
void
invoke
(
final
Object
listener
,
final
Class
listenerType
)
{
if
(
listenerType
==
Init
.
class
)
{
(
(
Init
)
listener
)
.
init
(
)
;
return
;
}
if
(
listenerType
==
Start
.
class
)
{
(
(
Start
)
listener
)
.
start
(
)
;
return
;
}
if
(
listenerType
==
Ready
.
class
)
{
(
(
Ready
)
listener
)
.
ready
(
)
;
return
;
}
if
(
listenerType
==
Stop
.
class
)
{
(
(
Stop
)
listener
)
.
stop
(
)
;
return
;
}
throw
new
MadvocException
(
"Invalid listener"
)
;
}

Invoke the listener based on type.
Not very OOP, but works.

Invoke the listener based on type . Not very OOP but works .


final void copyFrom(final Frame frame) {
    inputLocals = frame.inputLocals;
    inputStack = frame.inputStack;
    outputStackStart = 0;
    outputLocals = frame.outputLocals;
    outputStack = frame.outputStack;
    outputStackTop = frame.outputStackTop;
    initializationCount = frame.initializationCount;
    initializations = frame.initializations;
  }

final void copyFrom ( final Frame frame ) { inputLocals = frame . inputLocals ; inputStack = frame . inputStack ; outputStackStart = 0 ; outputLocals = frame . outputLocals ; outputStack = frame . outputStack ; outputStackTop = frame . outputStackTop ; initializationCount = frame . initializationCount ; initializations = frame . initializations ; }

Sets this frame to the value of the given frame.

<p>WARNING: after this method is called the two frames share the same data structures. It is
recommended to discard the given frame to avoid unexpected side effects.

@param frame The new frame value.

Sets this frame to the value of the given frame .


static int getAbstractTypeFromApiFormat(final SymbolTable symbolTable, final Object type) {
    if (type instanceof Integer) {
      return CONSTANT_KIND | ((Integer) type).intValue();
    } else if (type instanceof String) {
      String descriptor = Type.getObjectType((String) type).getDescriptor();
      return getAbstractTypeFromDescriptor(symbolTable, descriptor, 0);
    } else {
      return UNINITIALIZED_KIND
          | symbolTable.addUninitializedType("", ((Label) type).bytecodeOffset);
    }
  }

static int getAbstractTypeFromApiFormat ( final SymbolTable symbolTable , final Object type ) { if ( type instanceof Integer ) { return CONSTANT_KIND | ( ( Integer ) type ) . intValue ( ) ; } else if ( type instanceof String ) { String descriptor = Type . getObjectType ( ( String ) type ) . getDescriptor ( ) ; return getAbstractTypeFromDescriptor ( symbolTable , descriptor , 0 ) ; } else { return UNINITIALIZED_KIND | symbolTable . addUninitializedType ( "" , ( ( Label ) type ) . bytecodeOffset ) ; } }

Returns the abstract type corresponding to the given public API frame element type.

@param symbolTable the type table to use to lookup and store type {@link Symbol}.
@param type a frame element type described using the same format as in {@link
MethodVisitor#visitFrame}, i.e. either {@link Opcodes#TOP}, {@link Opcodes#INTEGER}, {@link
Opcodes#FLOAT}, {@link Opcodes#LONG}, {@link Opcodes#DOUBLE}, {@link Opcodes#NULL}, or
{@link Opcodes#UNINITIALIZED_THIS}, or the internal name of a class, or a Label designating
a NEW instruction (for uninitialized types).
@return the abstract type corresponding to the given frame element type.

Returns the abstract type corresponding to the given public API frame element type .


private static int getAbstractTypeFromDescriptor(
      final SymbolTable symbolTable, final String buffer, final int offset) {
    String internalName;
    switch (buffer.charAt(offset)) {
      case 'V':
        return 0;
      case 'Z':
      case 'C':
      case 'B':
      case 'S':
      case 'I':
        return INTEGER;
      case 'F':
        return FLOAT;
      case 'J':
        return LONG;
      case 'D':
        return DOUBLE;
      case 'L':
        internalName = buffer.substring(offset + 1, buffer.length() - 1);
        return REFERENCE_KIND | symbolTable.addType(internalName);
      case '[':
        int elementDescriptorOffset = offset + 1;
        while (buffer.charAt(elementDescriptorOffset) == '[') {
          ++elementDescriptorOffset;
        }
        int typeValue;
        switch (buffer.charAt(elementDescriptorOffset)) {
          case 'Z':
            typeValue = BOOLEAN;
            break;
          case 'C':
            typeValue = CHAR;
            break;
          case 'B':
            typeValue = BYTE;
            break;
          case 'S':
            typeValue = SHORT;
            break;
          case 'I':
            typeValue = INTEGER;
            break;
          case 'F':
            typeValue = FLOAT;
            break;
          case 'J':
            typeValue = LONG;
            break;
          case 'D':
            typeValue = DOUBLE;
            break;
          case 'L':
            internalName = buffer.substring(elementDescriptorOffset + 1, buffer.length() - 1);
            typeValue = REFERENCE_KIND | symbolTable.addType(internalName);
            break;
          default:
            throw new IllegalArgumentException();
        }
        return ((elementDescriptorOffset - offset) << DIM_SHIFT) | typeValue;
      default:
        throw new IllegalArgumentException();
    }
  }

private static int getAbstractTypeFromDescriptor ( final SymbolTable symbolTable , final String buffer , final int offset ) { String internalName ; switch ( buffer . charAt ( offset ) ) { case ' ' : return 0 ; case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : return INTEGER ; case ' ' : return FLOAT ; case ' ' : return LONG ; case ' ' : return DOUBLE ; case ' ' : internalName = buffer . substring ( offset + 1 , buffer . length ( ) - 1 ) ; return REFERENCE_KIND | symbolTable . addType ( internalName ) ; case ' ' : int elementDescriptorOffset = offset + 1 ; while ( buffer . charAt ( elementDescriptorOffset ) == ' ' ) { ++ elementDescriptorOffset ; } int typeValue ; switch ( buffer . charAt ( elementDescriptorOffset ) ) { case ' ' : typeValue = BOOLEAN ; break ; case ' ' : typeValue = CHAR ; break ; case ' ' : typeValue = BYTE ; break ; case ' ' : typeValue = SHORT ; break ; case ' ' : typeValue = INTEGER ; break ; case ' ' : typeValue = FLOAT ; break ; case ' ' : typeValue = LONG ; break ; case ' ' : typeValue = DOUBLE ; break ; case ' ' : internalName = buffer . substring ( elementDescriptorOffset + 1 , buffer . length ( ) - 1 ) ; typeValue = REFERENCE_KIND | symbolTable . addType ( internalName ) ; break ; default : throw new IllegalArgumentException ( ) ; } return ( ( elementDescriptorOffset - offset ) << DIM_SHIFT ) | typeValue ; default : throw new IllegalArgumentException ( ) ; } }

Returns the abstract type corresponding to the given type descriptor.

@param symbolTable the type table to use to lookup and store type {@link Symbol}.
@param buffer a string ending with a type descriptor.
@param offset the start offset of the type descriptor in buffer.
@return the abstract type corresponding to the given type descriptor.

Returns the abstract type corresponding to the given type descriptor .


final void setInputFrameFromApiFormat(
      final SymbolTable symbolTable,
      final int numLocal,
      final Object[] local,
      final int numStack,
      final Object[] stack) {
    int inputLocalIndex = 0;
    for (int i = 0; i < numLocal; ++i) {
      inputLocals[inputLocalIndex++] = getAbstractTypeFromApiFormat(symbolTable, local[i]);
      if (local[i] == Opcodes.LONG || local[i] == Opcodes.DOUBLE) {
        inputLocals[inputLocalIndex++] = TOP;
      }
    }
    while (inputLocalIndex < inputLocals.length) {
      inputLocals[inputLocalIndex++] = TOP;
    }
    int numStackTop = 0;
    for (int i = 0; i < numStack; ++i) {
      if (stack[i] == Opcodes.LONG || stack[i] == Opcodes.DOUBLE) {
        ++numStackTop;
      }
    }
    inputStack = new int[numStack + numStackTop];
    int inputStackIndex = 0;
    for (int i = 0; i < numStack; ++i) {
      inputStack[inputStackIndex++] = getAbstractTypeFromApiFormat(symbolTable, stack[i]);
      if (stack[i] == Opcodes.LONG || stack[i] == Opcodes.DOUBLE) {
        inputStack[inputStackIndex++] = TOP;
      }
    }
    outputStackTop = 0;
    initializationCount = 0;
  }

final void setInputFrameFromApiFormat ( final SymbolTable symbolTable , final int numLocal , final Object [ ] local , final int numStack , final Object [ ] stack ) { int inputLocalIndex = 0 ; for ( int i = 0 ; i < numLocal ; ++ i ) { inputLocals [ inputLocalIndex ++ ] = getAbstractTypeFromApiFormat ( symbolTable , local [ i ] ) ; if ( local [ i ] == Opcodes . LONG || local [ i ] == Opcodes . DOUBLE ) { inputLocals [ inputLocalIndex ++ ] = TOP ; } } while ( inputLocalIndex < inputLocals . length ) { inputLocals [ inputLocalIndex ++ ] = TOP ; } int numStackTop = 0 ; for ( int i = 0 ; i < numStack ; ++ i ) { if ( stack [ i ] == Opcodes . LONG || stack [ i ] == Opcodes . DOUBLE ) { ++ numStackTop ; } } inputStack = new int [ numStack + numStackTop ] ; int inputStackIndex = 0 ; for ( int i = 0 ; i < numStack ; ++ i ) { inputStack [ inputStackIndex ++ ] = getAbstractTypeFromApiFormat ( symbolTable , stack [ i ] ) ; if ( stack [ i ] == Opcodes . LONG || stack [ i ] == Opcodes . DOUBLE ) { inputStack [ inputStackIndex ++ ] = TOP ; } } outputStackTop = 0 ; initializationCount = 0 ; }

Sets the input frame from the given public API frame description.

@param symbolTable the type table to use to lookup and store type {@link Symbol}.
@param numLocal the number of local variables.
@param local the local variable types, described using the same format as in {@link
MethodVisitor#visitFrame}.
@param numStack the number of operand stack elements.
@param stack the operand stack types, described using the same format as in {@link
MethodVisitor#visitFrame}.

Sets the input frame from the given public API frame description .


private int getLocal(final int localIndex) {
    if (outputLocals == null || localIndex >= outputLocals.length) {
      // If this local has never been assigned in this basic block, it is still equal to its value
      // in the input frame.
      return LOCAL_KIND | localIndex;
    } else {
      int abstractType = outputLocals[localIndex];
      if (abstractType == 0) {
        // If this local has never been assigned in this basic block, so it is still equal to its
        // value in the input frame.
        abstractType = outputLocals[localIndex] = LOCAL_KIND | localIndex;
      }
      return abstractType;
    }
  }

Returns the abstract type stored at the given local variable index in the output frame.

@param localIndex the index of the local variable whose value must be returned.
@return the abstract type stored at the given local variable index in the output frame.

Returns the abstract type stored at the given local variable index in the output frame .


private void setLocal(final int localIndex, final int abstractType) {
    // Create and/or resize the output local variables array if necessary.
    if (outputLocals == null) {
      outputLocals = new int[10];
    }
    int outputLocalsLength = outputLocals.length;
    if (localIndex >= outputLocalsLength) {
      int[] newOutputLocals = new int[Math.max(localIndex + 1, 2 * outputLocalsLength)];
      System.arraycopy(outputLocals, 0, newOutputLocals, 0, outputLocalsLength);
      outputLocals = newOutputLocals;
    }
    // Set the local variable.
    outputLocals[localIndex] = abstractType;
  }

Replaces the abstract type stored at the given local variable index in the output frame.

@param localIndex the index of the output frame local variable that must be set.
@param abstractType the value that must be set.

Replaces the abstract type stored at the given local variable index in the output frame .


private void push(final int abstractType) {
    // Create and/or resize the output stack array if necessary.
    if (outputStack == null) {
      outputStack = new int[10];
    }
    int outputStackLength = outputStack.length;
    if (outputStackTop >= outputStackLength) {
      int[] newOutputStack = new int[Math.max(outputStackTop + 1, 2 * outputStackLength)];
      System.arraycopy(outputStack, 0, newOutputStack, 0, outputStackLength);
      outputStack = newOutputStack;
    }
    // Pushes the abstract type on the output stack.
    outputStack[outputStackTop++] = abstractType;
    // Updates the maximum size reached by the output stack, if needed (note that this size is
    // relative to the input stack size, which is not known yet).
    short outputStackSize = (short) (outputStackStart + outputStackTop);
    if (outputStackSize > owner.outputStackMax) {
      owner.outputStackMax = outputStackSize;
    }
  }

Pushes the given abstract type on the output frame stack.

@param abstractType an abstract type.

Pushes the given abstract type on the output frame stack .


private void push(final SymbolTable symbolTable, final String descriptor) {
    int typeDescriptorOffset = descriptor.charAt(0) == '(' ? descriptor.indexOf(')') + 1 : 0;
    int abstractType = getAbstractTypeFromDescriptor(symbolTable, descriptor, typeDescriptorOffset);
    if (abstractType != 0) {
      push(abstractType);
      if (abstractType == LONG || abstractType == DOUBLE) {
        push(TOP);
      }
    }
  }

private void push ( final SymbolTable symbolTable , final String descriptor ) { int typeDescriptorOffset = descriptor . charAt ( 0 ) == ' ' ? descriptor . indexOf ( ' ' ) + 1 : 0 ; int abstractType = getAbstractTypeFromDescriptor ( symbolTable , descriptor , typeDescriptorOffset ) ; if ( abstractType != 0 ) { push ( abstractType ) ; if ( abstractType == LONG || abstractType == DOUBLE ) { push ( TOP ) ; } } }

Pushes the abstract type corresponding to the given descriptor on the output frame stack.

@param symbolTable the type table to use to lookup and store type {@link Symbol}.
@param descriptor a type or method descriptor (in which case its return type is pushed).

Pushes the abstract type corresponding to the given descriptor on the output frame stack .


private void pop(final int elements) {
    if (outputStackTop >= elements) {
      outputStackTop -= elements;
    } else {
      // If the number of elements to be popped is greater than the number of elements in the output
      // stack, clear it, and pop the remaining elements from the input stack.
      outputStackStart -= elements - outputStackTop;
      outputStackTop = 0;
    }
  }

Pops the given number of abstract types from the output frame stack.

@param elements the number of abstract types that must be popped.

Pops the given number of abstract types from the output frame stack .


private void pop(final String descriptor) {
    char firstDescriptorChar = descriptor.charAt(0);
    if (firstDescriptorChar == '(') {
      pop((Type.getArgumentsAndReturnSizes(descriptor) >> 2) - 1);
    } else if (firstDescriptorChar == 'J' || firstDescriptorChar == 'D') {
      pop(2);
    } else {
      pop(1);
    }
  }

private void pop ( final String descriptor ) { char firstDescriptorChar = descriptor . charAt ( 0 ) ; if ( firstDescriptorChar == ' ' ) { pop ( ( Type . getArgumentsAndReturnSizes ( descriptor ) >> 2 ) - 1 ) ; } else if ( firstDescriptorChar == ' ' || firstDescriptorChar == ' ' ) { pop ( 2 ) ; } else { pop ( 1 ) ; } }

Pops as many abstract types from the output frame stack as described by the given descriptor.

@param descriptor a type or method descriptor (in which case its argument types are popped).

Pops as many abstract types from the output frame stack as described by the given descriptor .


private void addInitializedType(final int abstractType) {
    // Create and/or resize the initializations array if necessary.
    if (initializations == null) {
      initializations = new int[2];
    }
    int initializationsLength = initializations.length;
    if (initializationCount >= initializationsLength) {
      int[] newInitializations =
          new int[Math.max(initializationCount + 1, 2 * initializationsLength)];
      System.arraycopy(initializations, 0, newInitializations, 0, initializationsLength);
      initializations = newInitializations;
    }
    // Store the abstract type.
    initializations[initializationCount++] = abstractType;
  }

Adds an abstract type to the list of types on which a constructor is invoked in the basic
block.

@param abstractType an abstract type on a which a constructor is invoked.

Adds an abstract type to the list of types on which a constructor is invoked in the basic block .