text:
/**
 *    Copyright 2009-2017 the original author or authors.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */
package org.apache.ibatis.builder.xml;

import java.io.InputStream;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.apache.ibatis.builder.BaseBuilder;
import org.apache.ibatis.builder.BuilderException;
import org.apache.ibatis.builder.CacheRefResolver;
import org.apache.ibatis.builder.IncompleteElementException;
import org.apache.ibatis.builder.MapperBuilderAssistant;
import org.apache.ibatis.builder.ResultMapResolver;
import org.apache.ibatis.cache.Cache;
import org.apache.ibatis.executor.ErrorContext;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.mapping.Discriminator;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.mapping.ParameterMode;
import org.apache.ibatis.mapping.ResultFlag;
import org.apache.ibatis.mapping.ResultMap;
import org.apache.ibatis.mapping.ResultMapping;
import org.apache.ibatis.parsing.XNode;
import org.apache.ibatis.parsing.XPathParser;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.TypeHandler;

/**
 * @author Clinton Begin
 */
public class XMLMapperBuilder extends BaseBuilder {

  private final XPathParser parser;
  private final MapperBuilderAssistant builderAssistant;
  private final Map<String, XNode> sqlFragments;
  private final String resource;

  @Deprecated
  public XMLMapperBuilder(Reader reader, Configuration configuration, String resource, Map<String, XNode> sqlFragments, String namespace) {
    this(reader, configuration, resource, sqlFragments);
    this.builderAssistant.setCurrentNamespace(namespace);
  }

  @Deprecated
  public XMLMapperBuilder(Reader reader, Configuration configuration, String resource, Map<String, XNode> sqlFragments) {
    this(new XPathParser(reader, true, configuration.getVariables(), new XMLMapperEntityResolver()),
        configuration, resource, sqlFragments);
  }

  public XMLMapperBuilder(InputStream inputStream, Configuration configuration, String resource, Map<String, XNode> sqlFragments, String namespace) {
    this(inputStream, configuration, resource, sqlFragments);
    this.builderAssistant.setCurrentNamespace(namespace);
  }

  public XMLMapperBuilder(InputStream inputStream, Configuration configuration, String resource, Map<String, XNode> sqlFragments) {
    this(new XPathParser(inputStream, true, configuration.getVariables(), new XMLMapperEntityResolver()),
        configuration, resource, sqlFragments);
  }

  private XMLMapperBuilder(XPathParser parser, Configuration configuration, String resource, Map<String, XNode> sqlFragments) {
    super(configuration);
    this.builderAssistant = new MapperBuilderAssistant(configuration, resource);
    this.parser = parser;
    this.sqlFragments = sqlFragments;
    this.resource = resource;
  }

  public void parse() {
    if (!configuration.isResourceLoaded(resource)) {
      configurationElement(parser.evalNode("/mapper"));
      configuration.addLoadedResource(resource);
      bindMapperForNamespace();
    }

    parsePendingResultMaps();
    parsePendingCacheRefs();
    parsePendingStatements();
  }

  public XNode getSqlFragment(String refid) {
    return sqlFragments.get(refid);
  }

  private void configurationElement(XNode context) {
    try {
      String namespace = context.getStringAttribute("namespace");
      if (namespace == null || namespace.equals("")) {
        throw new BuilderException("Mapper's namespace cannot be empty");
      }
      builderAssistant.setCurrentNamespace(namespace);
      cacheRefElement(context.evalNode("cache-ref"));
      cacheElement(context.evalNode("cache"));
      parameterMapElement(context.evalNodes("/mapper/parameterMap"));
      resultMapElements(context.evalNodes("/mapper/resultMap"));
      sqlElement(context.evalNodes("/mapper/sql"));
      buildStatementFromContext(context.evalNodes("select|insert|update|delete"));
    } catch (Exception e) {
      throw new BuilderException("Error parsing Mapper XML. Cause: " + e, e);
    }
  }

  private void buildStatementFromContext(List<XNode> list) {
    if (configuration.getDatabaseId() != null) {
      buildStatementFromContext(list, configuration.getDatabaseId());
    }
    buildStatementFromContext(list, null);
  }

  private void buildStatementFromContext(List<XNode> list, String requiredDatabaseId) {
    for (XNode context : list) {
      final XMLStatementBuilder statementParser = new XMLStatementBuilder(configuration, builderAssistant, context, requiredDatabaseId);
      try {
        statementParser.parseStatementNode();
      } catch (IncompleteElementException e) {
        configuration.addIncompleteStatement(statementParser);
      }
    }
  }

  private void parsePendingResultMaps() {
    Collection<ResultMapResolver> incompleteResultMaps = configuration.getIncompleteResultMaps();
    synchronized (incompleteResultMaps) {
      Iterator<ResultMapResolver> iter = incompleteResultMaps.iterator();
      while (iter.hasNext()) {
        try {
          iter.next().resolve();
          iter.remove();
        } catch (IncompleteElementException e) {
          // ResultMap is still missing a resource...
        }
      }
    }
  }

  private void parsePendingCacheRefs() {
    Collection<CacheRefResolver> incompleteCacheRefs = configuration.getIncompleteCacheRefs();
    synchronized (incompleteCacheRefs) {
      Iterator<CacheRefResolver> iter = incompleteCacheRefs.iterator();
      while (iter.hasNext()) {
        try {
          iter.next().resolveCacheRef();
          iter.remove();
        } catch (IncompleteElementException e) {
          // Cache ref is still missing a resource...
        }
      }
    }
  }

  private void parsePendingStatements() {
    Collection<XMLStatementBuilder> incompleteStatements = configuration.getIncompleteStatements();
    synchronized (incompleteStatements) {
      Iterator<XMLStatementBuilder> iter = incompleteStatements.iterator();
      while (iter.hasNext()) {
        try {
          iter.next().parseStatementNode();
          iter.remove();
        } catch (IncompleteElementException e) {
          // Statement is still missing a resource...
        }
      }
    }
  }

  private void cacheRefElement(XNode context) {
    if (context != null) {
      configuration.addCacheRef(builderAssistant.getCurrentNamespace(), context.getStringAttribute("namespace"));
      CacheRefResolver cacheRefResolver = new CacheRefResolver(builderAssistant, context.getStringAttribute("namespace"));
      try {
        cacheRefResolver.resolveCacheRef();
      } catch (IncompleteElementException e) {
        configuration.addIncompleteCacheRef(cacheRefResolver);
      }
    }
  }

  private void cacheElement(XNode context) throws Exception {
    if (context != null) {
      String type = context.getStringAttribute("type", "PERPETUAL");
      Class<? extends Cache> typeClass = typeAliasRegistry.resolveAlias(type);
      String eviction = context.getStringAttribute("eviction", "LRU");
      Class<? extends Cache> evictionClass = typeAliasRegistry.resolveAlias(eviction);
      Long flushInterval = context.getLongAttribute("flushInterval");
      Integer size = context.getIntAttribute("size");
      boolean readWrite = !context.getBooleanAttribute("readOnly", false);
      boolean blocking = context.getBooleanAttribute("blocking", false);
      Properties props = context.getChildrenAsProperties();
      builderAssistant.useNewCache(typeClass, evictionClass, flushInterval, size, readWrite, blocking, props);
    }
  }

  private void parameterMapElement(List<XNode> list) throws Exception {
    for (XNode parameterMapNode : list) {
      String id = parameterMapNode.getStringAttribute("id");
      String type = parameterMapNode.getStringAttribute("type");
      Class<?> parameterClass = resolveClass(type);
      List<XNode> parameterNodes = parameterMapNode.evalNodes("parameter");
      List<ParameterMapping> parameterMappings = new ArrayList<ParameterMapping>();
      for (XNode parameterNode : parameterNodes) {
        String property = parameterNode.getStringAttribute("property");
        String javaType = parameterNode.getStringAttribute("javaType");
        String jdbcType = parameterNode.getStringAttribute("jdbcType");
        String resultMap = parameterNode.getStringAttribute("resultMap");
        String mode = parameterNode.getStringAttribute("mode");
        String typeHandler = parameterNode.getStringAttribute("typeHandler");
        Integer numericScale = parameterNode.getIntAttribute("numericScale");
        ParameterMode modeEnum = resolveParameterMode(mode);
        Class<?> javaTypeClass = resolveClass(javaType);
        JdbcType jdbcTypeEnum = resolveJdbcType(jdbcType);
        @SuppressWarnings("unchecked")
        Class<? extends TypeHandler<?>> typeHandlerClass = (Class<? extends TypeHandler<?>>) resolveClass(typeHandler);
        ParameterMapping parameterMapping = builderAssistant.buildParameterMapping(parameterClass, property, javaTypeClass, jdbcTypeEnum, resultMap, modeEnum, typeHandlerClass, numericScale);
        parameterMappings.add(parameterMapping);
      }
      builderAssistant.addParameterMap(id, parameterClass, parameterMappings);
    }
  }

  private void resultMapElements(List<XNode> list) throws Exception {
    for (XNode resultMapNode : list) {
      try {
        resultMapElement(resultMapNode);
      } catch (IncompleteElementException e) {
        // ignore, it will be retried
      }
    }
  }

  private ResultMap resultMapElement(XNode resultMapNode) throws Exception {
    return resultMapElement(resultMapNode, Collections.<ResultMapping> emptyList());
  }

  private ResultMap resultMapElement(XNode resultMapNode, List<ResultMapping> additionalResultMappings) throws Exception {
    ErrorContext.instance().activity("processing " + resultMapNode.getValueBasedIdentifier());
    String id = resultMapNode.getStringAttribute("id",
        resultMapNode.getValueBasedIdentifier());
    String type = resultMapNode.getStringAttribute("type",
        resultMapNode.getStringAttribute("ofType",
            resultMapNode.getStringAttribute("resultType",
                resultMapNode.getStringAttribute("javaType"))));
    String extend = resultMapNode.getStringAttribute("extends");
    Boolean autoMapping = resultMapNode.getBooleanAttribute("autoMapping");
    Class<?> typeClass = resolveClass(type);
    Discriminator discriminator = null;
    List<ResultMapping> resultMappings = new ArrayList<ResultMapping>();
    resultMappings.addAll(additionalResultMappings);
    List<XNode> resultChildren = resultMapNode.getChildren();
    for (XNode resultChild : resultChildren) {
      if ("constructor".equals(resultChild.getName())) {
        processConstructorElement(resultChild, typeClass, resultMappings);
      } else if ("discriminator".equals(resultChild.getName())) {
        discriminator = processDiscriminatorElement(resultChild, typeClass, resultMappings);
      } else {
        List<ResultFlag> flags = new ArrayList<ResultFlag>();
        if ("id".equals(resultChild.getName())) {
          flags.add(ResultFlag.ID);
        }
        resultMappings.add(buildResultMappingFromContext(resultChild, typeClass, flags));
      }
    }
    ResultMapResolver resultMapResolver = new ResultMapResolver(builderAssistant, id, typeClass, extend, discriminator, resultMappings, autoMapping);
    try {
      return resultMapResolver.resolve();
    } catch (IncompleteElementException  e) {
      configuration.addIncompleteResultMap(resultMapResolver);
      throw e;
    }
  }

  private void processConstructorElement(XNode resultChild, Class<?> resultType, List<ResultMapping> resultMappings) throws Exception {
    List<XNode> argChildren = resultChild.getChildren();
    for (XNode argChild : argChildren) {
      List<ResultFlag> flags = new ArrayList<ResultFlag>();
      flags.add(ResultFlag.CONSTRUCTOR);
      if ("idArg".equals(argChild.getName())) {
        flags.add(ResultFlag.ID);
      }
      resultMappings.add(buildResultMappingFromContext(argChild, resultType, flags));
    }
  }

  private Discriminator processDiscriminatorElement(XNode context, Class<?> resultType, List<ResultMapping> resultMappings) throws Exception {
    String column = context.getStringAttribute("column");
    String javaType = context.getStringAttribute("javaType");
    String jdbcType = context.getStringAttribute("jdbcType");
    String typeHandler = context.getStringAttribute("typeHandler");
    Class<?> javaTypeClass = resolveClass(javaType);
    @SuppressWarnings("unchecked")
    Class<? extends TypeHandler<?>> typeHandlerClass = (Class<? extends TypeHandler<?>>) resolveClass(typeHandler);
    JdbcType jdbcTypeEnum = resolveJdbcType(jdbcType);
    Map<String, String> discriminatorMap = new HashMap<String, String>();
    for (XNode caseChild : context.getChildren()) {
      String value = caseChild.getStringAttribute("value");
      String resultMap = caseChild.getStringAttribute("resultMap", processNestedResultMappings(caseChild, resultMappings));
      discriminatorMap.put(value, resultMap);
    }
    return builderAssistant.buildDiscriminator(resultType, column, javaTypeClass, jdbcTypeEnum, typeHandlerClass, discriminatorMap);
  }

  private void sqlElement(List<XNode> list) throws Exception {
    if (configuration.getDatabaseId() != null) {
      sqlElement(list, configuration.getDatabaseId());
    }
    sqlElement(list, null);
  }

  private void sqlElement(List<XNode> list, String requiredDatabaseId) throws Exception {
    for (XNode context : list) {
      String databaseId = context.getStringAttribute("databaseId");
      String id = context.getStringAttribute("id");
      id = builderAssistant.applyCurrentNamespace(id, false);
      if (databaseIdMatchesCurrent(id, databaseId, requiredDatabaseId)) {
        sqlFragments.put(id, context);
      }
    }
  }

  private boolean databaseIdMatchesCurrent(String id, String databaseId, String requiredDatabaseId) {
    if (requiredDatabaseId != null) {
      if (!requiredDatabaseId.equals(databaseId)) {
        return false;
      }
    } else {
      if (databaseId != null) {
        return false;
      }
      // skip this fragment if there is a previous one with a not null databaseId
      if (this.sqlFragments.containsKey(id)) {
        XNode context = this.sqlFragments.get(id);
        if (context.getStringAttribute("databaseId") != null) {
          return false;
        }
      }
    }
    return true;
  }

  private ResultMapping buildResultMappingFromContext(XNode context, Class<?> resultType, List<ResultFlag> flags) throws Exception {
    String property;
    if (flags.contains(ResultFlag.CONSTRUCTOR)) {
      property = context.getStringAttribute("name");
    } else {
      property = context.getStringAttribute("property");
    }
    String column = context.getStringAttribute("column");
    String javaType = context.getStringAttribute("javaType");
    String jdbcType = context.getStringAttribute("jdbcType");
    String nestedSelect = context.getStringAttribute("select");
    String nestedResultMap = context.getStringAttribute("resultMap",
        processNestedResultMappings(context, Collections.<ResultMapping> emptyList()));
    String notNullColumn = context.getStringAttribute("notNullColumn");
    String columnPrefix = context.getStringAttribute("columnPrefix");
    String typeHandler = context.getStringAttribute("typeHandler");
    String resultSet = context.getStringAttribute("resultSet");
    String foreignColumn = context.getStringAttribute("foreignColumn");
    boolean lazy = "lazy".equals(context.getStringAttribute("fetchType", configuration.isLazyLoadingEnabled() ? "lazy" : "eager"));
    Class<?> javaTypeClass = resolveClass(javaType);
    @SuppressWarnings("unchecked")
    Class<? extends TypeHandler<?>> typeHandlerClass = (Class<? extends TypeHandler<?>>) resolveClass(typeHandler);
    JdbcType jdbcTypeEnum = resolveJdbcType(jdbcType);
    return builderAssistant.buildResultMapping(resultType, property, column, javaTypeClass, jdbcTypeEnum, nestedSelect, nestedResultMap, notNullColumn, columnPrefix, typeHandlerClass, flags, resultSet, foreignColumn, lazy);
  }

  private String processNestedResultMappings(XNode context, List<ResultMapping> resultMappings) throws Exception {
    if ("association".equals(context.getName())
        || "collection".equals(context.getName())
        || "case".equals(context.getName())) {
      if (context.getStringAttribute("select") == null) {
        ResultMap resultMap = resultMapElement(context, resultMappings);
        return resultMap.getId();
      }
    }
    return null;
  }

  private void bindMapperForNamespace() {
    String namespace = builderAssistant.getCurrentNamespace();
    if (namespace != null) {
      Class<?> boundType = null;
      try {
        boundType = Resources.classForName(namespace);
      } catch (ClassNotFoundException e) {
        //ignore, bound type is not required
      }
      if (boundType != null) {
        if (!configuration.hasMapper(boundType)) {
          // Spring may not know the real resource name so we set a flag
          // to prevent loading again this resource from the mapper interface
          // look at MapperAnnotationBuilder#loadXmlResource
          configuration.addLoadedResource("namespace:" + namespace);
          configuration.addMapper(boundType);
        }
      }
    }
  }

}


text:
package jp.mzw.ajaxmutator;

import jp.mzw.ajaxmutator.detector.AbstractDetector;
import jp.mzw.ajaxmutator.detector.EventAttacherDetector;
import jp.mzw.ajaxmutator.detector.event.TimerEventDetector;
import jp.mzw.ajaxmutator.mutatable.*;
import jp.mzw.ajaxmutator.mutatable.generic.*;
import jp.mzw.ajaxmutator.mutatable.genprog.*;

import java.util.Collections;
import java.util.Set;

public class MutateVisitorBuilder {
	private Set<EventAttacherDetector> eventAttacherDetectors
	= Collections.emptySet();
	private Set<TimerEventDetector> timerEventDetectors
	= Collections.emptySet();
	private Set<? extends AbstractDetector<DOMCreation>> domCreationDetectors
			= Collections.emptySet();
	private Set<? extends AbstractDetector<AttributeModification>> attributeModificationDetectors
			= Collections.emptySet();
	private Set<? extends AbstractDetector<DOMAppending>> domAppendingDetectors
			= Collections.emptySet();
	private Set<? extends AbstractDetector<DOMCloning>> domCloningDetectors
			= Collections.emptySet();
	private Set<? extends AbstractDetector<DOMNormalization>> domNormalizationDetectors
			= Collections.emptySet();
	private Set<? extends AbstractDetector<DOMReplacement>> domReplacementDetectors
			= Collections.emptySet();
	private Set<? extends AbstractDetector<DOMRemoval>> domRemovalDetectors
			= Collections.emptySet();
	private Set<? extends AbstractDetector<DOMSelection>> domSelectionDetectors
			= Collections.emptySet();
	private Set<? extends AbstractDetector<Request>> requestDetectors
			= Collections.emptySet();
	private Set<? extends AbstractDetector<Statement>> statementDetectors
			= Collections.emptySet();
	private Set<? extends AbstractDetector<AssignmentExpression>> assignmentDetectors
			= Collections.emptySet();
	private Set<? extends AbstractDetector<Break>> breakDetectors
			= Collections.emptySet();
	private Set<? extends AbstractDetector<Continue>> continueDetectors
			= Collections.emptySet();
	private Set<? extends AbstractDetector<For>> forDetectors
			= Collections.emptySet();
	private Set<? extends AbstractDetector<FuncNode>> funcNodeDetectors
			= Collections.emptySet();
	private Set<? extends AbstractDetector<If>> ifDetectors
			= Collections.emptySet();
	private Set<? extends AbstractDetector<Return>> returnDetectors
			= Collections.emptySet();
	private Set<? extends AbstractDetector<Switch>> switchDetectors
			= Collections.emptySet();
	private Set<? extends AbstractDetector<VariableDec>> variableDeclarationDetectors
			= Collections.emptySet();
	private Set<? extends AbstractDetector<While>> whileDetectors
			= Collections.emptySet();

	protected MutateVisitorBuilder() {

	}

	public MutateVisitor build() {
		return new MutateVisitor(eventAttacherDetectors, timerEventDetectors,
				domCreationDetectors, attributeModificationDetectors, domAppendingDetectors,
				domCloningDetectors, domNormalizationDetectors, domReplacementDetectors,
				domRemovalDetectors, domSelectionDetectors, requestDetectors,
				statementDetectors,
				assignmentDetectors,breakDetectors,continueDetectors,
				forDetectors,funcNodeDetectors,ifDetectors,
				returnDetectors,switchDetectors,variableDeclarationDetectors,
				whileDetectors
				);
	}

	public void setEventAttacherDetectors(
			Set<EventAttacherDetector> eventAttacherDetectors) {
		this.eventAttacherDetectors = eventAttacherDetectors;
	}

	public void setTimerEventDetectors(
			Set<TimerEventDetector> timerEventDetectors) {
		this.timerEventDetectors = timerEventDetectors;
	}

	public void setDomCreationDetectors(
			Set<? extends AbstractDetector<DOMCreation>> domCreationDetectors) {
		this.domCreationDetectors = domCreationDetectors;
	}

	public void setAttributeModificationDetectors(
			Set<? extends AbstractDetector<AttributeModification>> attributeModificationDetectors) {
		this.attributeModificationDetectors = attributeModificationDetectors;
	}

	public void setDomAppendingDetectors(
			Set<? extends AbstractDetector<DOMAppending>> domAppendingDetectors) {
		this.domAppendingDetectors = domAppendingDetectors;
	}

	public void setDomCloningDetectors(
			Set<? extends AbstractDetector<DOMCloning>> domCloningDetectors) {
		this.domCloningDetectors = domCloningDetectors;
	}

	public void setDomNormalizationDetectors(
			Set<? extends AbstractDetector<DOMNormalization>> domNormalizationDetectors) {
		this.domNormalizationDetectors = domNormalizationDetectors;
	}

	public void setDomReplacementDetectors(
			Set<? extends AbstractDetector<DOMReplacement>> domReplacementDetectors) {
		this.domReplacementDetectors = domReplacementDetectors;
	}

	public void setDomRemovalDetectors(
			Set<? extends AbstractDetector<DOMRemoval>> domRemovalDetectors) {
		this.domRemovalDetectors = domRemovalDetectors;
	}

	public void setDomSelectionDetectors(
			Set<? extends AbstractDetector<DOMSelection>> domSelectionDetectors) {
		this.domSelectionDetectors = domSelectionDetectors;
	}

	public void setRequestDetectors(
			Set<? extends AbstractDetector<Request>> requestDetectors) {
		this.requestDetectors = requestDetectors;
	}

	public void setStatementDetectors(
			Set<? extends AbstractDetector<Statement>> statementDetectors) {
		this.statementDetectors = statementDetectors;
	}

	public void setAssignmentDetectors(Set<? extends AbstractDetector<AssignmentExpression>> assignmentDetectors){
		this.assignmentDetectors = assignmentDetectors;
	}

	public void setBreakDetectors(Set<? extends AbstractDetector<Break>> breakDetectors){
		this.breakDetectors = breakDetectors;
	}

	public void setContinueDetectors(Set<? extends AbstractDetector<Continue>> continueDetectors){
		this.continueDetectors  = continueDetectors;
	}

	public void setForDetectors(Set<? extends AbstractDetector<For>> forDetectors){
		this.forDetectors  = forDetectors;
	}

	public void setFuncNodeDetectors(Set<? extends AbstractDetector<FuncNode>> funcNodeDetectors){
		this.funcNodeDetectors  = funcNodeDetectors;
	}

	public void setIfDetectors(Set<? extends AbstractDetector<If>> ifDetectors){
		this.ifDetectors  = ifDetectors;
	}

	public void setReturnDetectors(Set<? extends AbstractDetector<Return>> returnDetectors){
		this.returnDetectors  = returnDetectors;
	}

	public void setSwitchDetectors(Set<? extends AbstractDetector<Switch>> switchDetectors){
		this.switchDetectors  = switchDetectors;
	}

	public void setVariableDeclarationDetectors(Set<? extends AbstractDetector<VariableDec>> variableDeclarationDetectors){
		this.variableDeclarationDetectors  = variableDeclarationDetectors;
	}

	public void setWhileDetectors(Set<? extends AbstractDetector<While>> whileDetectors){
		this.whileDetectors  = whileDetectors;
	}

}

domain: java


text:
/*
 * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 2019, Arm Limited and affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */

package org.graalvm.compiler.core.test;

import org.junit.Test;

public class IntegerDivRemConstantTest extends GraalCompilerTest {
    public static int intDivPositiveConstant(int val) {
        return val / 5;
    }

    @Test
    public void testIntDivPositiveConstant() {
        test("intDivPositiveConstant", -10);
        test("intDivPositiveConstant", 0);
        test("intDivPositiveConstant", 4256);
        test("intDivPositiveConstant", Integer.MAX_VALUE);
        test("intDivPositiveConstant", Integer.MIN_VALUE);
    }

    public static int intDivIntegerMax(int val) {
        return val / Integer.MAX_VALUE;
    }

    @Test
    public void testIntDivIntegerMax() {
        test("intDivIntegerMax", -10);
        test("intDivIntegerMax", 0);
        test("intDivIntegerMax", 4256);
        test("intDivIntegerMax", Integer.MAX_VALUE);
        test("intDivIntegerMax", Integer.MIN_VALUE);
    }

    public static int intDivNegativeConstant(int val) {
        return val / -1234;
    }

    @Test
    public void testIntDivNegativeConstant() {
        test("intDivNegativeConstant", -123);
        test("intDivNegativeConstant", 0);
        test("intDivNegativeConstant", 123);
        test("intDivNegativeConstant", Integer.MAX_VALUE);
        test("intDivNegativeConstant", Integer.MIN_VALUE);
    }

    public static int intDivIntegerMinOdd(int val) {
        return val / (Integer.MIN_VALUE + 1);
    }

    @Test
    public void testIntDivIntegerMinOdd() {
        test("intDivIntegerMinOdd", -123);
        test("intDivIntegerMinOdd", 0);
        test("intDivIntegerMinOdd", 123);
        test("intDivIntegerMinOdd", Integer.MAX_VALUE);
        test("intDivIntegerMinOdd", Integer.MIN_VALUE);
    }

    public static long longDivPositiveConstant(long val) {
        return val / 35170432;
    }

    @Test
    public void testLongDivPositiveConstant() {
        test("longDivPositiveConstant", -1234L);
        test("longDivPositiveConstant", 0L);
        test("longDivPositiveConstant", 214423L);
        test("longDivPositiveConstant", Long.MAX_VALUE);
        test("longDivPositiveConstant", Long.MIN_VALUE);
    }

    public static long longDivLongMax(long val) {
        return val / Long.MAX_VALUE;
    }

    @Test
    public void testLongDivLongMax() {
        test("longDivLongMax", -1234L);
        test("longDivLongMax", 0L);
        test("longDivLongMax", 214423L);
        test("longDivLongMax", Long.MAX_VALUE);
        test("longDivLongMax", Long.MIN_VALUE);
    }

    public static long longDivNegativeConstant(long val) {
        return val / -413;
    }

    @Test
    public void testLongDivNegativeConstant() {
        test("longDivNegativeConstant", -43L);
        test("longDivNegativeConstant", 0L);
        test("longDivNegativeConstant", 147065L);
        test("longDivNegativeConstant", Long.MAX_VALUE);
        test("longDivNegativeConstant", Long.MIN_VALUE);
    }

    public static long longDivLongMinOdd(long val) {
        return val / (Long.MIN_VALUE + 1);
    }

    @Test
    public void testLongDivLongMinOdd() {
        test("longDivLongMinOdd", -1234L);
        test("longDivLongMinOdd", 0L);
        test("longDivLongMinOdd", 214423L);
        test("longDivLongMinOdd", Long.MAX_VALUE);
        test("longDivLongMinOdd", Long.MIN_VALUE);
    }

    public static int intRemPositiveConstant(int val) {
        return val % 139968;
    }

    @Test
    public void testIntRemPositiveConstant() {
        test("intRemPositiveConstant", -10);
        test("intRemPositiveConstant", 0);
        test("intRemPositiveConstant", 4256);
        test("intRemPositiveConstant", Integer.MAX_VALUE);
        test("intRemPositiveConstant", Integer.MIN_VALUE);
    }

    public static int intRemNegativeConstant(int val) {
        return val % -139968;
    }

    @Test
    public void testIntRemNegativeConstant() {
        test("intRemNegativeConstant", -10);
        test("intRemNegativeConstant", 0);
        test("intRemNegativeConstant", 4256);
        test("intRemNegativeConstant", Integer.MAX_VALUE);
        test("intRemNegativeConstant", Integer.MIN_VALUE);
    }

    @SuppressWarnings("divzero")
    public static int intRemZero(int val) {
        return val % 0;
    }

    @Test
    public void testIntRemZero() {
        test("intRemZero", -10);
        test("intRemZero", 0);
        test("intRemZero", 4256);
        test("intRemZero", Integer.MAX_VALUE);
        test("intRemZero", Integer.MIN_VALUE);
    }

    public static int intRemMax(int val) {
        return val % Integer.MAX_VALUE;
    }

    @Test
    public void testIntRemMax() {
        test("intRemMax", -10);
        test("intRemMax", 0);
        test("intRemMax", 4256);
        test("intRemMax", Integer.MAX_VALUE);
        test("intRemMax", Integer.MIN_VALUE);
    }

    public static int intRemMin(int val) {
        return val % Integer.MIN_VALUE;
    }

    @Test
    public void testIntRemMin() {
        test("intRemMin", -10);
        test("intRemMin", 0);
        test("intRemMin", 4256);
        test("intRemMin", Integer.MAX_VALUE);
        test("intRemMin", Integer.MIN_VALUE);
    }

    public static long longRemPositiveConstant(long val) {
        return val % 35170432;
    }

    public static int intRemPowerOf2(int val) {
        return val % 4;
    }

    @Test
    public void testIntRemPowerOf2() {
        test("intRemPowerOf2", -10);
        test("intRemPowerOf2", 0);
        test("intRemPowerOf2", 4256);
        test("intRemPowerOf2", Integer.MAX_VALUE);
        test("intRemPowerOf2", Integer.MIN_VALUE);
    }

    @Test
    public void testLongRemPositiveConstant() {
        test("longRemPositiveConstant", -1234L);
        test("longRemPositiveConstant", 0L);
        test("longRemPositiveConstant", 214423L);
        test("longRemPositiveConstant", Long.MAX_VALUE);
        test("longRemPositiveConstant", Long.MIN_VALUE);
    }

    public static long longRemNegativeConstant(long val) {
        return val % -413;
    }

    @Test
    public void testLongRemNegativeConstant() {
        test("longRemNegativeConstant", -43L);
        test("longRemNegativeConstant", 0L);
        test("longRemNegativeConstant", 147065L);
        test("longRemNegativeConstant", Long.MAX_VALUE);
        test("longRemNegativeConstant", Long.MIN_VALUE);
    }

    @SuppressWarnings("divzero")
    public static long longRemZero(long val) {
        return val % 0;
    }

    @Test
    public void testLongRemZero() {
        test("longRemZero", -43L);
        test("longRemZero", 0L);
        test("longRemZero", 147065L);
        test("longRemZero", Long.MAX_VALUE);
        test("longRemZero", Long.MIN_VALUE);
    }

    public static long longRemMax(long val) {
        return val % Long.MAX_VALUE;
    }

    @Test
    public void testLongRemMax() {
        test("longRemMax", -43L);
        test("longRemMax", 0L);
        test("longRemMax", 147065L);
        test("longRemMax", Long.MAX_VALUE);
        test("longRemMax", Long.MIN_VALUE);
    }

    public static long longRemMin(long val) {
        return val % Long.MIN_VALUE;
    }

    @Test
    public void testLongRemMin() {
        test("longRemMin", -43L);
        test("longRemMin", 0L);
        test("longRemMin", 147065L);
        test("longRemMin", Long.MAX_VALUE);
        test("longRemMin", Long.MIN_VALUE);
    }

    public static long longRemPowerOf2(long val) {
        return val % 4L;
    }

    @Test
    public void testLongRemPowerOf2() {
        test("longRemPowerOf2", -43L);
        test("longRemPowerOf2", 0L);
        test("longRemPowerOf2", 147065L);
        test("longRemPowerOf2", Long.MAX_VALUE);
        test("longRemPowerOf2", Long.MIN_VALUE);
    }
}


text:
// -----BEGIN DISCLAIMER-----
/*******************************************************************************
 * Copyright (c) 2017 JCrypTool Team and Contributors
 *
 * All rights reserved. This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *******************************************************************************/
// -----END DISCLAIMER-----
package org.jcryptool.visual.zeroknowledge.ui.graphenisomorphie;

import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.jcryptool.core.util.fonts.FontService;
import org.jcryptool.visual.zeroknowledge.algorithm.graphenisomorphie.GBob;
import org.jcryptool.visual.zeroknowledge.ui.ParamsPerson;

/**
 * Group, auf der die Parameter von Bob dargestellt werden.
 *
 * @author Mareike Paul
 *@version 1.0.0
 */
public class GParamsBob extends ParamsPerson {

    private GCombiLabel b;

    private GBob bob;

    private Label verifiziert;

    /**
     * Konstruktor, der die graphischen Komponenten erstellt und eingefügt. Die Group besteht aus
     * einem Label, das den Namen enthält und je einem CombiLabel für den Wert vom Attribut b
     * darstellen.
     */
    public GParamsBob(GBob bob, Composite parent) {
        super(parent);
        this.bob = bob;
        group.setText(Messages.GParamsBob_0);

        b = new GCombiLabel(Messages.GParamsBob_1, false, group);

        verifiziert = new Label(group, SWT.None);
        verifiziert.setFont(FontService.getNormalBoldFont());
        verifiziert.setText(Messages.GParamsBob_2);
        verifiziert.setVisible(false);
        verifiziert.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
        setVisible(true);
    }

    /**
     * Methode zum Erhalten des Labels, auf dem ausgegeben wird, ob das Verifizieren erfolgreich war
     * oder nicht
     *
     * @return JLabel, das ausgibt, ob die Verifikation erfolgreich war
     */
    public Label getVerifiziert() {
        return verifiziert;
    }

    public void setBob(GBob bob) {
        this.bob = bob;
    }

    /**
     * setzt den Text des Verifiziert-Labels in Abhängigkeit von b: wenn b true ist, wird der Text
     * in grün ausgegeben, ansonsten in rot
     *
     * @param b gibt an, ob Bob das Ergebnis verifiziert hat oder nicht
     */
    public void setVerifiziert(boolean b) {
        if (b) {
            verifiziert.setText(Messages.GParamsBob_3);
            verifiziert.setForeground(group.getDisplay().getSystemColor(SWT.COLOR_DARK_GREEN));
        } else {
            verifiziert.setText(Messages.GParamsBob_4);
            verifiziert.setForeground(group.getDisplay().getSystemColor(SWT.COLOR_RED));
        }
        verifiziert.setVisible(true);
    }

    /**
     * Methode zum updaten des Panels
     *
     * @see ParamsPerson#update()
     */
    @Override
	public void update() {
        b.update(bob.getB());
    }

    /**
     * Setzt den Text der einzelnen Labels, die nur sichtbar werden, wenn Bob verifiziert.
     *
     * @param on true, wenn die Labels sichtbar werden sollen
     */
    public void verifizieren(boolean on) {
        if (!on) {
            verifiziert.setVisible(false);
        }
    }
}


text:
package org.myrobotlab.serial;

import java.io.IOException;
import java.util.TooManyListenersException;

public interface SerialDevice {

	public static final int DATABITS_5 = 5;
	public static final int DATABITS_6 = 6;
	public static final int DATABITS_7 = 7;
	public static final int DATABITS_8 = 8;
	public static final int PARITY_NONE = 0;
	public static final int PARITY_ODD = 1;
	public static final int PARITY_EVEN = 2;
	public static final int PARITY_MARK = 3;
	public static final int PARITY_SPACE = 4;
	public static final int STOPBITS_1 = 1;
	public static final int STOPBITS_2 = 2;
	public static final int STOPBITS_1_5 = 3;
	public static final int FLOWCONTROL_NONE = 0;
	public static final int FLOWCONTROL_RTSCTS_IN = 1;
	public static final int FLOWCONTROL_RTSCTS_OUT = 2;
	public static final int FLOWCONTROL_XONXOFF_IN = 4;
	public static final int FLOWCONTROL_XONXOFF_OUT = 8;
	public static final int PORTTYPE_SERIAL = 1;

	// identification
	public String getName();

	// public String getCurrentOwner();
	// public int getPortType();
	// public boolean isCurrentlyOwned();
	public int available() throws IOException;

	// open / close
	public void open() throws SerialDeviceException;

	// public SerialDevice open(FileDescriptor f) throws
	// SerialDeviceException;
	// public SerialDevice open(String TheOwner, int i) throws
	// SerialDeviceException;
	public boolean isOpen();

	public void close();

	// input/output
	// public InputStream getInputStream() throws IOException;
	// public OutputStream getOutputStream() throws IOException;

	// serial parameters
	public void setParams(int b, int d, int s, int p) throws SerialDeviceException;

	// special serial methods/states
	// public boolean isDTR();
	public void setDTR(boolean state);

	public void setRTS(boolean state);

	// public boolean isCTS();
	// public boolean isDSR();
	// public boolean isCD();
	// public boolean isRI();
	// public boolean isRTS();

	// reading/listening events
	public void addEventListener(SerialDeviceEventListener lsnr) throws TooManyListenersException;

	public void notifyOnDataAvailable(boolean enable);

	// write methods
	public void write(int data) throws IOException;

	public void write(int[] data) throws IOException;

	/*
	 * public void write(byte data) throws IOException;
	 *
	 * public void write(char data) throws IOException;
	 *
	 * public void write(byte[] data) throws IOException;
	 *
	 * public void write(String data) throws IOException;
	 */

	public int read() throws IOException;

	// LAME - but Java goes both ways with InputStream
	// it returns a single "int" / byte form 0/255
	// in addition it returns your byte array - as java bytes - which no one uses :P
	public int read(byte[] data) throws IOException;
}


text:
/**
 * Copyright (C) 2015 The Gravitee team (http://gravitee.io)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.gravitee.am.gateway.handler.root.resources.handler.login;

import io.gravitee.am.common.exception.oauth2.InvalidRequestException;
import io.gravitee.am.gateway.handler.common.auth.idp.IdentityProviderManager;
import io.gravitee.am.gateway.handler.common.vertx.utils.UriBuilderRequest;
import io.gravitee.am.identityprovider.api.common.Request;
import io.gravitee.am.identityprovider.api.social.SocialAuthenticationProvider;
import io.gravitee.am.model.Client;
import io.gravitee.am.model.Domain;
import io.gravitee.am.model.IdentityProvider;
import io.gravitee.common.http.HttpMethod;
import io.reactivex.Maybe;
import io.reactivex.Observable;
import io.vertx.core.AsyncResult;
import io.vertx.core.Future;
import io.vertx.core.Handler;
import io.vertx.reactivex.core.http.HttpServerRequest;
import io.vertx.reactivex.ext.web.RoutingContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.URISyntaxException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Fetch social providers information if client using one of them
 *
 * @author Titouan COMPIEGNE (titouan.compiegne at graviteesource.com)
 * @author GraviteeSource Team
 */
public class LoginSocialAuthenticationHandler implements Handler<RoutingContext> {

    private static final Logger logger = LoggerFactory.getLogger(LoginSocialAuthenticationHandler.class);
    private static final List<String> socialProviders = Arrays.asList("github", "google", "twitter", "facebook", "bitbucket");
    private static final String OAUTH2_PROVIDER_CONTEXT_KEY = "oauth2Providers";
    private static final String SOCIAL_PROVIDER_CONTEXT_KEY = "socialProviders";
    private static final String SOCIAL_AUTHORIZE_URL_CONTEXT_KEY = "authorizeUrls";
    private static final String CLIENT_CONTEXT_KEY = "client";
    private IdentityProviderManager identityProviderManager;
    private Domain domain;

    public LoginSocialAuthenticationHandler(IdentityProviderManager identityProviderManager, Domain domain) {
        this.identityProviderManager = identityProviderManager;
        this.domain = domain;
    }

    @Override
    public void handle(RoutingContext routingContext) {
        final Client client = routingContext.get(CLIENT_CONTEXT_KEY);

        // fetch client identity providers
        getIdentityProviders(client.getIdentities(), identityProvidersResultHandler -> {
            if (identityProvidersResultHandler.failed()) {
                logger.error("Unable to fetch client identity providers", identityProvidersResultHandler.cause());
                routingContext.fail(new InvalidRequestException("Unable to fetch client identity providers"));
            }

            List<IdentityProvider> identityProviders = identityProvidersResultHandler.result();
            List<IdentityProvider> socialIdentityProviders = identityProviders.stream().filter(IdentityProvider::isExternal).collect(Collectors.toList());

            // no social provider, continue
            if (socialIdentityProviders == null || socialIdentityProviders.isEmpty()) {
                routingContext.next();
                return;
            }

            // client enable social connect
            // get social identity providers information to correctly build the login page
            enhanceSocialIdentityProviders(socialIdentityProviders, routingContext.request(), resultHandler -> {
                if (resultHandler.failed()) {
                    logger.error("Unable to enhance client social identity providers", resultHandler.cause());
                    routingContext.fail(new InvalidRequestException("Unable to enhance client social identity providers"));
                }

                // put social providers in context data
                final List<SocialProviderData> socialProviderData = resultHandler.result();
                if (socialProviderData != null) {
                    List<SocialProviderData> filteredSocialProviderData = socialProviderData.stream().filter(providerData -> providerData.getIdentityProvider() != null && providerData.getAuthorizeUrl() != null).collect(Collectors.toList());
                    List<IdentityProvider> providers = filteredSocialProviderData.stream().map(SocialProviderData::getIdentityProvider).collect(Collectors.toList());
                    Map<String, String> authorizeUrls = filteredSocialProviderData.stream().collect(Collectors.toMap(o -> o.getIdentityProvider().getId(), o -> o.getAuthorizeUrl()));

                    // backwards compatibility
                    routingContext.put(OAUTH2_PROVIDER_CONTEXT_KEY, providers);
                    routingContext.put(SOCIAL_PROVIDER_CONTEXT_KEY, providers);
                    routingContext.put(SOCIAL_AUTHORIZE_URL_CONTEXT_KEY, authorizeUrls);
                }

                // continue
                routingContext.next();
            });
        });

    }

    private void getIdentityProviders(Set<String> identities, Handler<AsyncResult<List<IdentityProvider>>> resultHandler) {
        if (identities == null) {
            resultHandler.handle(Future.succeededFuture(Collections.emptyList()));
        } else {
            Observable.fromIterable(identities)
                    .flatMapMaybe(identity -> identityProviderManager.getIdentityProvider(identity))
                    .toList()
                    .subscribe(
                            identityProviders -> resultHandler.handle(Future.succeededFuture(identityProviders)),
                            error -> resultHandler.handle(Future.failedFuture(error)));
        }
    }

    private void enhanceSocialIdentityProviders(List<IdentityProvider> identityProviders, HttpServerRequest request, Handler<AsyncResult<List<SocialProviderData>>> resultHandler) {
        Observable.fromIterable(identityProviders)
                .flatMapMaybe(identityProvider -> {
                    // get social identity provider type (currently use for display purpose (logo, description, ...)
                    String identityProviderType = identityProvider.getType();
                    Optional<String> identityProviderSocialType = socialProviders.stream().filter(socialProvider -> identityProviderType.toLowerCase().contains(socialProvider)).findFirst();
                    if (identityProviderSocialType.isPresent()) {
                        identityProvider.setType(identityProviderSocialType.get());
                    }
                    // get social sign in url
                    return getAuthorizeUrl(identityProvider.getId(), request)
                            .map(authorizeUrl -> new SocialProviderData(identityProvider, authorizeUrl))
                            .defaultIfEmpty(new SocialProviderData(identityProvider,null));
                })
                .toList()
                .subscribe(socialProviderData -> resultHandler.handle(Future.succeededFuture(socialProviderData)),
                        error -> resultHandler.handle(Future.failedFuture(error)));
    }

    private Maybe<String> getAuthorizeUrl(String identityProviderId, HttpServerRequest request) {
        return identityProviderManager.get(identityProviderId)
                .flatMap(authenticationProvider -> {
                    Map<String, String> parameters = Collections.singletonMap("provider", identityProviderId);
                    String redirectUri = buildUri(request, "/" + domain.getPath() + "/login/callback", parameters);
                    Request signInURL = ((SocialAuthenticationProvider) authenticationProvider).signInUrl(redirectUri);
                    if (signInURL == null) {
                        return Maybe.empty();
                    }
                    return Maybe.just(HttpMethod.GET.equals(signInURL.getMethod()) ? signInURL.getUri() : buildUri(request, "/" + domain.getPath() + "/login/SSO/POST", parameters));
                });
    }

    private String buildUri(HttpServerRequest request, String path, Map<String, String> parameters) throws URISyntaxException {
        return UriBuilderRequest.resolveProxyRequest(request, path, parameters);
    }

    private class SocialProviderData {
        private IdentityProvider identityProvider;
        private String authorizeUrl;

        public SocialProviderData(IdentityProvider identityProvider, String authorizeUrl) {
            this.identityProvider = identityProvider;
            this.authorizeUrl = authorizeUrl;
        }

        public IdentityProvider getIdentityProvider() {
            return identityProvider;
        }

        public void setIdentityProvider(IdentityProvider identityProvider) {
            this.identityProvider = identityProvider;
        }

        public String getAuthorizeUrl() {
            return authorizeUrl;
        }

        public void setAuthorizeUrl(String authorizeUrl) {
            this.authorizeUrl = authorizeUrl;
        }
    }
}


text:
package com.jaquadro.minecraft.storagedrawers.network;

import com.jaquadro.minecraft.storagedrawers.StorageDrawers;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.network.NetworkRegistry;
import net.minecraftforge.fml.network.simple.SimpleChannel;

public class MessageHandler
{
    private static final String PROTOCOL_VERSION = "1";
    public static final SimpleChannel INSTANCE = NetworkRegistry.ChannelBuilder
        .named(new ResourceLocation(StorageDrawers.MOD_ID, "main_channel"))
        .networkProtocolVersion(() -> PROTOCOL_VERSION)
        .clientAcceptedVersions(PROTOCOL_VERSION::equals)
        .serverAcceptedVersions(PROTOCOL_VERSION::equals)
        .simpleChannel();

    public static void init() {
        INSTANCE.registerMessage(0, CountUpdateMessage.class, CountUpdateMessage::encode, CountUpdateMessage::decode, CountUpdateMessage::handle);
    }
}


text:
import java.util.ArrayList;

/**
 * Implmentation of a Quadtree. Find more information about this data structure that helps with spacial indexing here:
 * https://medium.com/@waleoyediran/spatial-indexing-with-quadtrees-b998ae49336
 *
 * Data searched for, inserted, or deleted must have location within original quadrant's size
 *
 * @author alexrich
 */

public class Quadtree {
    private final int BUCKET_SIZE;   // amount of data that can be held in a leaf
    private final int WIDTH;         // width of starting quadrant
    private final int HEIGHT;        // height of final quadrant
    private Node root;               // root of tree

    public Quadtree(int bucketSize, int width, int height) {
        BUCKET_SIZE = bucketSize;
        WIDTH = width;
        HEIGHT = height;
        root = null;
    }

    /**
     * Inserts data into tree
     * @param name      String, Name of data
     * @param x         double, x position of data
     * @param y         double, y position of data
     */
    public void insert(String name, double x, double y) {
        insert(new Tuple(name, x, y));
    }

    /**
     * Inserts data to tree
     * @param data  Tuple to insert
     */
    public void insert(Tuple data) {
        if (root == null) {
            root = new Node(BUCKET_SIZE, 0, WIDTH, 0, HEIGHT);
            root.addData(data);
        } else {
            recursiveInsert(root, data);
        }
    }

    /**
     * Recursively calls children of given node until finds one (or creates a new child) that isn't full where it inserts
     * data
     * @param node      Node, node to consider inserting data into or calling a child
     * @param data      Tuple, data to insert
     */
    private void recursiveInsert(Node node, Tuple data) {
        if (!node.isLeaf() || node.isFull()) {
            int depth = 0;
            int breadth = 0;
            if (data.getX() >= (node.getMaxX() + node.getMinX()) / 2)
                breadth = 1;
            if (data.getY() >= (node.getMaxY() + node.getMinY()) / 2)
                depth = 1;

            if (node.isLeaf()) {
                node.addChildren();
            }
            Node child = node.getChild(depth, breadth);
            if (child == null) {
                child = node.createNewChild(depth, breadth);
                node.setChild(child, depth, breadth);
            }
            recursiveInsert(child, data);
        } else {
            node.addData(data);
        }
    }

    /**
     * Finds data with parameters given in quadtree and deletes it
     * @param name      String, name of data
     * @param x         double, x location of data
     * @param y         double, y location of data
     * @return          true if data found and deleted, false otherwise
     */
    public boolean delete(String name, double x, double y) {
        return delete(new Tuple(name, x, y));
    }

    /**
     * Finds given data in quadtree and deletes it
     * @param data      Tuple with data to be matched and deleted
     * @return          true if data found and deleted, false otherwise
     */
    public boolean delete(Tuple data) {
        if (root == null)
            return false;
        else if (root.isLeaf())
            return root.deleteData(data);
        else
            return recursiveDelete(root, data);
    }

    /**
     * Recursive function that keeps calls with children of node that represents quadrant where data would lie unless it
     * finds a leaf. If data is in leaf it deletes data. Also deletes any empty branch that occurs because of this deletion.
     *
     * @param node      Node to check child for data
     * @param data      Tuple with data looking to delete
     * @return          true if data is found and deleted, false otherwise
     */
    private boolean recursiveDelete(Node node, Tuple data) {
        int vertical = 0;   // 0 if data is upper quadrant of children, 1 if in lower
        int horizontal = 0; // 0 if data is left quadrant of children, 1 if in right
        if (data.getX() >= (node.getMaxX() + node.getMinX()) / 2)
            horizontal = 1;
        if (data.getY() >= (node.getMaxY() + node.getMinY()) / 2)
            vertical = 1;
        Node child = node.getChild(vertical, horizontal);
        if (child == null)
            return false;
        else if (!child.isLeaf()) {
            boolean toReturn = recursiveDelete(child, data);
            // deletes node if there is no data beneath it
            if (toReturn) {
                Node[][] children = node.getChildren();
                boolean allNull = true;
                for (int i = 0; i < children.length; i++) {
                    for (int j = 0; j < children[i].length; j++) {
                        if (children[i][j] != null)
                            allNull = false;
                    }
                }
                if (allNull)
                    node = null;
            }
            return toReturn;
        } else {
            boolean toReturn = child.deleteData(data);
            if (toReturn) {
                if (child.isEmpty())
                    node.setChild(null, vertical, horizontal);
                // deletes node if it no longer has any children beneath it
                if (node.getChildren() == null)
                    node = null;
            }
            return toReturn;
        }
    }

    /**
     * Finds data name with location in quadtree.
     * @param x     double of x loc
     * @param y     double of y loc
     * @return      String - name of data at loc or empty string if no data found
     */
    public String search(double x, double y) {
        return recursiveSearch(root, x, y);
    }

    /**
     * Calls child with the correct quadrant unless given node is null or a leaf. If node is leaf, looks for data with given
     * location and returns its string and empty string if not found.
     * @param node      Node to look for data
     * @param x         double x of loc
     * @param y
     * @return
     */
    private String recursiveSearch(Node node, double x, double y) {
        if (node == null)
            return "";
        if (node.isLeaf()) {
            ArrayList<Tuple> data = node.getBucket();
            for (int i = 0; i < data.size(); i++) {
                if (Double.compare(x, data.get(i).getX()) == 0 && Double.compare(y,data.get(i).getY()) == 0)
                    return data.get(i).getName();
            }
            return "";
        }
        int vertical = 0;   // 0 if data is upper quadrant of children, 1 if in lower
        int horizontal = 0; // 0 if data is left quadrant of children, 1 if in right
        if (x >= (node.getMaxX() + node.getMinX()) / 2)
            horizontal = 1;
        if (y >= (node.getMaxY() + node.getMinY()) / 2)
            vertical = 1;
        return recursiveSearch(node.getChild(vertical, horizontal), x, y);
    }
}


text:
/*
 * Copyright 2010-2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License").
 * You may not use this file except in compliance with the License.
 * A copy of the License is located at
 *
 *  http://aws.amazon.com/apache2.0
 *
 * or in the "license" file accompanying this file. This file is distributed
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

package com.amazonaws.services.simpleemail.model.transform;

import java.util.Map;
import java.util.Map.Entry;

import org.xmlpull.v1.XmlPullParser;

import com.amazonaws.services.simpleemail.model.*;
import com.amazonaws.transform.Unmarshaller;
import com.amazonaws.transform.MapEntry;
import com.amazonaws.transform.StaxUnmarshallerContext;
import com.amazonaws.transform.SimpleTypeStaxUnmarshallers.*;

/**
 * StAX unmarshaller for response SendEmailResult
 */
public class SendEmailResultStaxUnmarshaller implements
        Unmarshaller<SendEmailResult, StaxUnmarshallerContext> {

    public SendEmailResult unmarshall(StaxUnmarshallerContext context) throws Exception {
        SendEmailResult sendEmailResult = new SendEmailResult();

        int originalDepth = context.getCurrentDepth();
        int targetDepth = originalDepth + 1;

        if (context.isStartOfDocument())
            targetDepth += 2;

        while (true) {
            int xmlEvent = context.nextEvent();
            if (xmlEvent == XmlPullParser.END_DOCUMENT)
                break;

            if (xmlEvent == XmlPullParser.START_TAG) {
                if (context.testExpression("MessageId", targetDepth)) {
                    sendEmailResult.setMessageId(StringStaxUnmarshaller.getInstance().unmarshall(
                            context));
                    continue;
                }
            } else if (xmlEvent == XmlPullParser.END_TAG) {
                if (context.getCurrentDepth() < originalDepth) {
                    break;
                }
            }
        }
        return sendEmailResult;
    }

    private static SendEmailResultStaxUnmarshaller instance;

    public static SendEmailResultStaxUnmarshaller getInstance() {
        if (instance == null)
            instance = new SendEmailResultStaxUnmarshaller();
        return instance;
    }
}


text:
// Copyright 2018 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * FeedAttributeOperand.java
 *
 * This file was auto-generated from WSDL
 * by the Apache Axis 1.4 Mar 02, 2009 (07:08:06 PST) WSDL2Java emitter.
 */

package com.google.api.ads.adwords.axis.v201802.cm;

/**
 * Represents a feed attribute reference to use in a function.
 */
public class FeedAttributeOperand  extends com.google.api.ads.adwords.axis.v201802.cm.FunctionArgumentOperand  implements java.io.Serializable {
    /* Id of associated feed.
     *                     This field is
     * required and should not be {@code null}. */
    private java.lang.Long feedId;

    /* Id of the referenced feed attribute.
     *                     This field is
     * required and should not be {@code null}. */
    private java.lang.Long feedAttributeId;

    public FeedAttributeOperand() {
    }

    public FeedAttributeOperand(
           java.lang.String functionArgumentOperandType,
           java.lang.Long feedId,
           java.lang.Long feedAttributeId) {
        super(
            functionArgumentOperandType);
        this.feedId = feedId;
        this.feedAttributeId = feedAttributeId;
    }

    @Override
    public String toString() {
        return com.google.common.base.MoreObjects.toStringHelper(this.getClass())
            .omitNullValues()
            .add("feedAttributeId", getFeedAttributeId())
            .add("feedId", getFeedId())
            .add("functionArgumentOperandType", getFunctionArgumentOperandType())
            .toString();
    }

    /**
     * Gets the feedId value for this FeedAttributeOperand.
     *
     * @return feedId   * Id of associated feed.
     *                     This field is
     * required and should not be {@code null}.
     */
    public java.lang.Long getFeedId() {
        return feedId;
    }

    /**
     * Sets the feedId value for this FeedAttributeOperand.
     *
     * @param feedId   * Id of associated feed.
     *                     This field is
     * required and should not be {@code null}.
     */
    public void setFeedId(java.lang.Long feedId) {
        this.feedId = feedId;
    }

    /**
     * Gets the feedAttributeId value for this FeedAttributeOperand.
     *
     * @return feedAttributeId   * Id of the referenced feed attribute.
     *                     This field is
     * required and should not be {@code null}.
     */
    public java.lang.Long getFeedAttributeId() {
        return feedAttributeId;
    }

    /**
     * Sets the feedAttributeId value for this FeedAttributeOperand.
     *
     * @param feedAttributeId   * Id of the referenced feed attribute.
     *                     This field is
     * required and should not be {@code null}.
     */
    public void setFeedAttributeId(java.lang.Long feedAttributeId) {
        this.feedAttributeId = feedAttributeId;
    }

    private java.lang.Object __equalsCalc = null;
    public synchronized boolean equals(java.lang.Object obj) {
        if (!(obj instanceof FeedAttributeOperand)) return false;
        FeedAttributeOperand other = (FeedAttributeOperand) obj;
        if (obj == null) return false;
        if (this == obj) return true;
        if (__equalsCalc != null) {
            return (__equalsCalc == obj);
        }
        __equalsCalc = obj;
        boolean _equals;
        _equals = super.equals(obj) &&
            ((this.feedId==null && other.getFeedId()==null) ||
             (this.feedId!=null &&
              this.feedId.equals(other.getFeedId()))) &&
            ((this.feedAttributeId==null && other.getFeedAttributeId()==null) ||
             (this.feedAttributeId!=null &&
              this.feedAttributeId.equals(other.getFeedAttributeId())));
        __equalsCalc = null;
        return _equals;
    }

    private boolean __hashCodeCalc = false;
    public synchronized int hashCode() {
        if (__hashCodeCalc) {
            return 0;
        }
        __hashCodeCalc = true;
        int _hashCode = super.hashCode();
        if (getFeedId() != null) {
            _hashCode += getFeedId().hashCode();
        }
        if (getFeedAttributeId() != null) {
            _hashCode += getFeedAttributeId().hashCode();
        }
        __hashCodeCalc = false;
        return _hashCode;
    }

    // Type metadata
    private static org.apache.axis.description.TypeDesc typeDesc =
        new org.apache.axis.description.TypeDesc(FeedAttributeOperand.class, true);

    static {
        typeDesc.setXmlType(new javax.xml.namespace.QName("https://adwords.google.com/api/adwords/cm/v201802", "FeedAttributeOperand"));
        org.apache.axis.description.ElementDesc elemField = new org.apache.axis.description.ElementDesc();
        elemField.setFieldName("feedId");
        elemField.setXmlName(new javax.xml.namespace.QName("https://adwords.google.com/api/adwords/cm/v201802", "feedId"));
        elemField.setXmlType(new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "long"));
        elemField.setMinOccurs(0);
        elemField.setNillable(false);
        typeDesc.addFieldDesc(elemField);
        elemField = new org.apache.axis.description.ElementDesc();
        elemField.setFieldName("feedAttributeId");
        elemField.setXmlName(new javax.xml.namespace.QName("https://adwords.google.com/api/adwords/cm/v201802", "feedAttributeId"));
        elemField.setXmlType(new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "long"));
        elemField.setMinOccurs(0);
        elemField.setNillable(false);
        typeDesc.addFieldDesc(elemField);
    }

    /**
     * Return type metadata object
     */
    public static org.apache.axis.description.TypeDesc getTypeDesc() {
        return typeDesc;
    }

    /**
     * Get Custom Serializer
     */
    public static org.apache.axis.encoding.Serializer getSerializer(
           java.lang.String mechType,
           java.lang.Class _javaType,
           javax.xml.namespace.QName _xmlType) {
        return
          new  org.apache.axis.encoding.ser.BeanSerializer(
            _javaType, _xmlType, typeDesc);
    }

    /**
     * Get Custom Deserializer
     */
    public static org.apache.axis.encoding.Deserializer getDeserializer(
           java.lang.String mechType,
           java.lang.Class _javaType,
           javax.xml.namespace.QName _xmlType) {
        return
          new  org.apache.axis.encoding.ser.BeanDeserializer(
            _javaType, _xmlType, typeDesc);
    }

}


text:
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.hudi;

import org.apache.hudi.common.HoodieClientTestUtils;
import org.apache.hudi.common.HoodieTestDataGenerator;
import org.apache.hudi.common.model.HoodieCommitMetadata;
import org.apache.hudi.common.model.HoodieDataFile;
import org.apache.hudi.common.model.HoodieKey;
import org.apache.hudi.common.model.HoodieRecord;
import org.apache.hudi.common.model.HoodieRollingStat;
import org.apache.hudi.common.model.HoodieRollingStatMetadata;
import org.apache.hudi.common.model.HoodieTestUtils;
import org.apache.hudi.common.table.HoodieTableMetaClient;
import org.apache.hudi.common.table.HoodieTimeline;
import org.apache.hudi.common.table.TableFileSystemView.ReadOptimizedView;
import org.apache.hudi.common.table.timeline.HoodieInstant;
import org.apache.hudi.common.util.ConsistencyGuardConfig;
import org.apache.hudi.common.util.FSUtils;
import org.apache.hudi.common.util.FileIOUtils;
import org.apache.hudi.common.util.Option;
import org.apache.hudi.common.util.ParquetUtils;
import org.apache.hudi.common.util.collection.Pair;
import org.apache.hudi.config.HoodieCompactionConfig;
import org.apache.hudi.config.HoodieStorageConfig;
import org.apache.hudi.config.HoodieWriteConfig;
import org.apache.hudi.exception.HoodieCommitException;
import org.apache.hudi.exception.HoodieIOException;
import org.apache.hudi.index.HoodieIndex;
import org.apache.hudi.table.HoodieTable;

import org.apache.avro.generic.GenericRecord;
import org.apache.hadoop.fs.Path;
import org.apache.spark.api.java.JavaRDD;
import org.junit.Assert;
import org.junit.Test;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;

import static org.apache.hudi.common.HoodieTestDataGenerator.NULL_SCHEMA;
import static org.apache.hudi.common.HoodieTestDataGenerator.TRIP_EXAMPLE_SCHEMA;
import static org.apache.hudi.common.util.ParquetUtils.readRowKeysFromParquet;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

@SuppressWarnings("unchecked")
public class TestHoodieClientOnCopyOnWriteStorage extends TestHoodieClientBase {

  /**
   * Test Auto Commit behavior for HoodieWriteClient insert API
   */
  @Test
  public void testAutoCommitOnInsert() throws Exception {
    testAutoCommit(HoodieWriteClient::insert, false);
  }

  /**
   * Test Auto Commit behavior for HoodieWriteClient insertPrepped API
   */
  @Test
  public void testAutoCommitOnInsertPrepped() throws Exception {
    testAutoCommit(HoodieWriteClient::insertPreppedRecords, true);
  }

  /**
   * Test Auto Commit behavior for HoodieWriteClient upsert API
   */
  @Test
  public void testAutoCommitOnUpsert() throws Exception {
    testAutoCommit(HoodieWriteClient::upsert, false);
  }

  /**
   * Test Auto Commit behavior for HoodieWriteClient upsert Prepped API
   */
  @Test
  public void testAutoCommitOnUpsertPrepped() throws Exception {
    testAutoCommit(HoodieWriteClient::upsertPreppedRecords, true);
  }

  /**
   * Test Auto Commit behavior for HoodieWriteClient bulk-insert API
   */
  @Test
  public void testAutoCommitOnBulkInsert() throws Exception {
    testAutoCommit(HoodieWriteClient::bulkInsert, false);
  }

  /**
   * Test Auto Commit behavior for HoodieWriteClient bulk-insert prepped API
   */
  @Test
  public void testAutoCommitOnBulkInsertPrepped() throws Exception {
    testAutoCommit((writeClient, recordRDD, commitTime) -> writeClient.bulkInsertPreppedRecords(recordRDD, commitTime,
        Option.empty()), true);
  }

  /**
   * Test auto-commit by applying write function
   *
   * @param writeFn One of HoodieWriteClient Write API
   * @throws Exception in case of failure
   */
  private void testAutoCommit(Function3<JavaRDD<WriteStatus>, HoodieWriteClient, JavaRDD<HoodieRecord>, String> writeFn,
      boolean isPrepped) throws Exception {
    // Set autoCommit false
    HoodieWriteConfig cfg = getConfigBuilder().withAutoCommit(false).build();
    try (HoodieWriteClient client = getHoodieWriteClient(cfg);) {

      String prevCommitTime = "000";
      String newCommitTime = "001";
      int numRecords = 200;
      JavaRDD<WriteStatus> result = insertFirstBatch(cfg, client, newCommitTime, prevCommitTime, numRecords, writeFn,
          isPrepped, false, numRecords);

      assertFalse("If Autocommit is false, then commit should not be made automatically",
          HoodieTestUtils.doesCommitExist(basePath, newCommitTime));
      assertTrue("Commit should succeed", client.commit(newCommitTime, result));
      assertTrue("After explicit commit, commit file should be created",
          HoodieTestUtils.doesCommitExist(basePath, newCommitTime));
    }
  }

  /**
   * Test De-duplication behavior for HoodieWriteClient insert API
   */
  @Test
  public void testDeduplicationOnInsert() throws Exception {
    testDeduplication(HoodieWriteClient::insert);
  }

  /**
   * Test De-duplication behavior for HoodieWriteClient bulk-insert API
   */
  @Test
  public void testDeduplicationOnBulkInsert() throws Exception {
    testDeduplication(HoodieWriteClient::bulkInsert);
  }

  /**
   * Test De-duplication behavior for HoodieWriteClient upsert API
   */
  @Test
  public void testDeduplicationOnUpsert() throws Exception {
    testDeduplication(HoodieWriteClient::upsert);
  }

  /**
   * Test Deduplication Logic for write function
   *
   * @param writeFn One of HoddieWriteClient non-prepped write APIs
   * @throws Exception in case of failure
   */
  private void testDeduplication(
      Function3<JavaRDD<WriteStatus>, HoodieWriteClient, JavaRDD<HoodieRecord>, String> writeFn) throws Exception {
    String newCommitTime = "001";

    String recordKey = UUID.randomUUID().toString();
    HoodieKey keyOne = new HoodieKey(recordKey, "2018-01-01");
    HoodieRecord recordOne =
        new HoodieRecord(keyOne, HoodieTestDataGenerator.generateRandomValue(keyOne, newCommitTime));

    HoodieKey keyTwo = new HoodieKey(recordKey, "2018-02-01");
    HoodieRecord recordTwo =
        new HoodieRecord(keyTwo, HoodieTestDataGenerator.generateRandomValue(keyTwo, newCommitTime));

    // Same key and partition as keyTwo
    HoodieRecord recordThree =
        new HoodieRecord(keyTwo, HoodieTestDataGenerator.generateRandomValue(keyTwo, newCommitTime));

    JavaRDD<HoodieRecord> records = jsc.parallelize(Arrays.asList(recordOne, recordTwo, recordThree), 1);

    // dedup should be done based on recordKey only
    HoodieWriteClient clientWithDummyGlobalIndex = getWriteClientWithDummyIndex(true);
    List<HoodieRecord> dedupedRecs = clientWithDummyGlobalIndex.deduplicateRecords(records, 1).collect();
    assertEquals(1, dedupedRecs.size());
    assertNodupesWithinPartition(dedupedRecs);

    // dedup should be done based on both recordKey and partitionPath
    HoodieWriteClient clientWithDummyNonGlobalIndex = getWriteClientWithDummyIndex(false);
    dedupedRecs = clientWithDummyNonGlobalIndex.deduplicateRecords(records, 1).collect();
    assertEquals(2, dedupedRecs.size());
    assertNodupesWithinPartition(dedupedRecs);

    // Perform write-action and check
    try (HoodieWriteClient client = getHoodieWriteClient(getConfigBuilder().combineInput(true, true).build(), false);) {
      client.startCommitWithTime(newCommitTime);
      List<WriteStatus> statuses = writeFn.apply(client, records, newCommitTime).collect();
      assertNoWriteErrors(statuses);
      assertEquals(2, statuses.size());
      assertNodupesWithinPartition(statuses.stream().map(WriteStatus::getWrittenRecords).flatMap(Collection::stream)
          .collect(Collectors.toList()));
    }
  }

  /**
   * Build a test Hoodie WriteClient with dummy index to configure isGlobal flag
   *
   * @param isGlobal Flag to control HoodieIndex.isGlobal
   * @return Hoodie Write Client
   * @throws Exception in case of error
   */
  private HoodieWriteClient getWriteClientWithDummyIndex(final boolean isGlobal) throws Exception {
    HoodieIndex index = mock(HoodieIndex.class);
    when(index.isGlobal()).thenReturn(isGlobal);
    return getHoodieWriteClient(getConfigBuilder().build(), false, index);
  }

  /**
   * Test Upsert API
   */
  @Test
  public void testUpserts() throws Exception {
    testUpsertsInternal(getConfig(), HoodieWriteClient::upsert, false);
  }

  /**
   * Test UpsertPrepped API
   */
  @Test
  public void testUpsertsPrepped() throws Exception {
    testUpsertsInternal(getConfig(), HoodieWriteClient::upsertPreppedRecords, true);
  }

  /**
   * Test one of HoodieWriteClient upsert(Prepped) APIs
   *
   * @param hoodieWriteConfig Write Config
   * @param writeFn One of Hoodie Write Function API
   * @throws Exception in case of error
   */
  private void testUpsertsInternal(HoodieWriteConfig hoodieWriteConfig,
      Function3<JavaRDD<WriteStatus>, HoodieWriteClient, JavaRDD<HoodieRecord>, String> writeFn, boolean isPrepped)
      throws Exception {
    HoodieWriteClient client = getHoodieWriteClient(hoodieWriteConfig, false);

    // Write 1 (only inserts)
    String newCommitTime = "001";
    String initCommitTime = "000";
    int numRecords = 200;
    insertFirstBatch(hoodieWriteConfig, client, newCommitTime, initCommitTime, numRecords, HoodieWriteClient::insert,
        isPrepped, true, numRecords);

    // Write 2 (updates)
    String prevCommitTime = newCommitTime;
    newCommitTime = "004";
    numRecords = 100;
    String commitTimeBetweenPrevAndNew = "002";
    updateBatch(hoodieWriteConfig, client, newCommitTime, prevCommitTime,
        Option.of(Arrays.asList(commitTimeBetweenPrevAndNew)), initCommitTime, numRecords, writeFn, isPrepped, true,
        numRecords, 200, 2);

    // Delete 1
    prevCommitTime = newCommitTime;
    newCommitTime = "005";
    numRecords = 50;

    deleteBatch(hoodieWriteConfig, client, newCommitTime, prevCommitTime,
        initCommitTime, numRecords, HoodieWriteClient::delete, isPrepped, true,
        0, 150);
  }

  /**
   * Tesst deletion of records
   */
  @Test
  public void testDeletes() throws Exception {
    HoodieWriteClient client = getHoodieWriteClient(getConfig(), false);

    /**
     * Write 1 (inserts and deletes) Write actual 200 insert records and ignore 100 delete records
     */
    String initCommitTime = "000";
    String newCommitTime = "001";

    final List<HoodieRecord> recordsInFirstBatch = new ArrayList<>();
    Function2<List<HoodieRecord>, String, Integer> recordGenFunction =
        (String commitTime, Integer numRecordsInThisCommit) -> {
          List<HoodieRecord> fewRecordsForInsert = dataGen.generateInserts(commitTime, 200);
          List<HoodieRecord> fewRecordsForDelete = dataGen.generateDeletes(commitTime, 100);

          recordsInFirstBatch.addAll(fewRecordsForInsert);
          recordsInFirstBatch.addAll(fewRecordsForDelete);
          return recordsInFirstBatch;
        };
    writeBatch(client, newCommitTime, initCommitTime, Option.empty(), initCommitTime,
        // unused as genFn uses hard-coded number of inserts/updates/deletes
        -1, recordGenFunction, HoodieWriteClient::upsert, true, 200, 200, 1);

    /**
     * Write 2 (deletes+writes)
     */
    String prevCommitTime = newCommitTime;
    newCommitTime = "004";
    final List<HoodieRecord> recordsInSecondBatch = new ArrayList<>();

    recordGenFunction = (String commitTime, Integer numRecordsInThisCommit) -> {
      List<HoodieRecord> fewRecordsForDelete = recordsInFirstBatch.subList(0, 50);
      List<HoodieRecord> fewRecordsForUpdate = recordsInFirstBatch.subList(50, 100);
      recordsInSecondBatch.addAll(dataGen.generateDeletesFromExistingRecords(fewRecordsForDelete));
      recordsInSecondBatch.addAll(fewRecordsForUpdate);
      return recordsInSecondBatch;
    };
    writeBatch(client, newCommitTime, prevCommitTime, Option.empty(), initCommitTime, 100, recordGenFunction,
        HoodieWriteClient::upsert, true, 50, 150, 2);
  }

  /**
   * Test scenario of new file-group getting added during upsert()
   */
  @Test
  public void testSmallInsertHandlingForUpserts() throws Exception {
    final String testPartitionPath = "2016/09/26";
    final int insertSplitLimit = 100;
    // setup the small file handling params
    HoodieWriteConfig config = getSmallInsertWriteConfig(insertSplitLimit); // hold upto 200 records max
    dataGen = new HoodieTestDataGenerator(new String[]{testPartitionPath});

    HoodieWriteClient client = getHoodieWriteClient(config, false);

    // Inserts => will write file1
    String commitTime1 = "001";
    client.startCommitWithTime(commitTime1);
    List<HoodieRecord> inserts1 = dataGen.generateInserts(commitTime1, insertSplitLimit); // this writes ~500kb
    Set<String> keys1 = HoodieClientTestUtils.getRecordKeys(inserts1);

    JavaRDD<HoodieRecord> insertRecordsRDD1 = jsc.parallelize(inserts1, 1);
    List<WriteStatus> statuses = client.upsert(insertRecordsRDD1, commitTime1).collect();

    assertNoWriteErrors(statuses);

    assertEquals("Just 1 file needs to be added.", 1, statuses.size());
    String file1 = statuses.get(0).getFileId();
    Assert.assertEquals("file should contain 100 records",
        readRowKeysFromParquet(jsc.hadoopConfiguration(), new Path(basePath, statuses.get(0).getStat().getPath()))
            .size(),
        100);

    // Update + Inserts such that they just expand file1
    String commitTime2 = "002";
    client.startCommitWithTime(commitTime2);
    List<HoodieRecord> inserts2 = dataGen.generateInserts(commitTime2, 40);
    Set<String> keys2 = HoodieClientTestUtils.getRecordKeys(inserts2);
    List<HoodieRecord> insertsAndUpdates2 = new ArrayList<>();
    insertsAndUpdates2.addAll(inserts2);
    insertsAndUpdates2.addAll(dataGen.generateUpdates(commitTime2, inserts1));

    JavaRDD<HoodieRecord> insertAndUpdatesRDD2 = jsc.parallelize(insertsAndUpdates2, 1);
    statuses = client.upsert(insertAndUpdatesRDD2, commitTime2).collect();
    assertNoWriteErrors(statuses);

    assertEquals("Just 1 file needs to be updated.", 1, statuses.size());
    assertEquals("Existing file should be expanded", file1, statuses.get(0).getFileId());
    assertEquals("Existing file should be expanded", commitTime1, statuses.get(0).getStat().getPrevCommit());
    Path newFile = new Path(basePath, statuses.get(0).getStat().getPath());
    assertEquals("file should contain 140 records", readRowKeysFromParquet(jsc.hadoopConfiguration(), newFile).size(),
        140);

    List<GenericRecord> records = ParquetUtils.readAvroRecords(jsc.hadoopConfiguration(), newFile);
    for (GenericRecord record : records) {
      String recordKey = record.get(HoodieRecord.RECORD_KEY_METADATA_FIELD).toString();
      assertEquals("only expect commit2", commitTime2, record.get(HoodieRecord.COMMIT_TIME_METADATA_FIELD).toString());
      assertTrue("key expected to be part of commit2", keys2.contains(recordKey) || keys1.contains(recordKey));
    }

    // update + inserts such that file1 is updated and expanded, a new file2 is created.
    String commitTime3 = "003";
    client.startCommitWithTime(commitTime3);
    List<HoodieRecord> insertsAndUpdates3 = dataGen.generateInserts(commitTime3, 200);
    Set<String> keys3 = HoodieClientTestUtils.getRecordKeys(insertsAndUpdates3);
    List<HoodieRecord> updates3 = dataGen.generateUpdates(commitTime3, inserts2);
    insertsAndUpdates3.addAll(updates3);

    JavaRDD<HoodieRecord> insertAndUpdatesRDD3 = jsc.parallelize(insertsAndUpdates3, 1);
    statuses = client.upsert(insertAndUpdatesRDD3, commitTime3).collect();
    assertNoWriteErrors(statuses);

    assertEquals("2 files needs to be committed.", 2, statuses.size());
    HoodieTableMetaClient metadata = new HoodieTableMetaClient(jsc.hadoopConfiguration(), basePath);

    HoodieTable table = getHoodieTable(metadata, config);
    ReadOptimizedView fileSystemView = table.getROFileSystemView();
    List<HoodieDataFile> files =
        fileSystemView.getLatestDataFilesBeforeOrOn(testPartitionPath, commitTime3).collect(Collectors.toList());
    int numTotalInsertsInCommit3 = 0;
    int numTotalUpdatesInCommit3 = 0;
    for (HoodieDataFile file : files) {
      if (file.getFileName().contains(file1)) {
        assertEquals("Existing file should be expanded", commitTime3, file.getCommitTime());
        records = ParquetUtils.readAvroRecords(jsc.hadoopConfiguration(), new Path(file.getPath()));
        for (GenericRecord record : records) {
          String recordKey = record.get(HoodieRecord.RECORD_KEY_METADATA_FIELD).toString();
          String recordCommitTime = record.get(HoodieRecord.COMMIT_TIME_METADATA_FIELD).toString();
          if (recordCommitTime.equals(commitTime3)) {
            if (keys2.contains(recordKey)) {
              keys2.remove(recordKey);
              numTotalUpdatesInCommit3++;
            } else {
              numTotalInsertsInCommit3++;
            }
          }
        }
        assertEquals("All keys added in commit 2 must be updated in commit3 correctly", 0, keys2.size());
      } else {
        assertEquals("New file must be written for commit 3", commitTime3, file.getCommitTime());
        records = ParquetUtils.readAvroRecords(jsc.hadoopConfiguration(), new Path(file.getPath()));
        for (GenericRecord record : records) {
          String recordKey = record.get(HoodieRecord.RECORD_KEY_METADATA_FIELD).toString();
          assertEquals("only expect commit3", commitTime3,
              record.get(HoodieRecord.COMMIT_TIME_METADATA_FIELD).toString());
          assertTrue("key expected to be part of commit3", keys3.contains(recordKey));
        }
        numTotalInsertsInCommit3 += records.size();
      }
    }
    assertEquals("Total updates in commit3 must add up", inserts2.size(), numTotalUpdatesInCommit3);
    assertEquals("Total inserts in commit3 must add up", keys3.size(), numTotalInsertsInCommit3);
  }

  /**
   * Test scenario of new file-group getting added during insert()
   */
  @Test
  public void testSmallInsertHandlingForInserts() throws Exception {

    final String testPartitionPath = "2016/09/26";
    final int insertSplitLimit = 100;
    // setup the small file handling params
    HoodieWriteConfig config = getSmallInsertWriteConfig(insertSplitLimit); // hold upto 200 records max
    dataGen = new HoodieTestDataGenerator(new String[]{testPartitionPath});
    HoodieWriteClient client = getHoodieWriteClient(config, false);

    // Inserts => will write file1
    String commitTime1 = "001";
    client.startCommitWithTime(commitTime1);
    List<HoodieRecord> inserts1 = dataGen.generateInserts(commitTime1, insertSplitLimit); // this writes ~500kb
    Set<String> keys1 = HoodieClientTestUtils.getRecordKeys(inserts1);
    JavaRDD<HoodieRecord> insertRecordsRDD1 = jsc.parallelize(inserts1, 1);
    List<WriteStatus> statuses = client.insert(insertRecordsRDD1, commitTime1).collect();

    assertNoWriteErrors(statuses);
    assertPartitionMetadata(new String[]{testPartitionPath}, fs);


text:
/*
 * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/*
 *
 *
 * Unit test for Attach API. Attaches to the given VM and performs a number
 * unit tests.
 */
import com.sun.tools.attach.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.io.IOException;
import java.util.Properties;
import java.util.List;

public class BasicTests {
    public static void main(String args[]) throws Exception {
        String pid = args[0];
        String agent = args[1];
        String badagent = args[2];
        String redefineagent = args[3];

        System.out.println(" - Attaching to application ...");
        VirtualMachine vm = VirtualMachine.attach(pid);

        // Test 1 - read the system properties from the target VM and
        // check that property is set
        System.out.println(" - Test: system properties in target VM");
        Properties props = vm.getSystemProperties();
        String value = props.getProperty("attach.test");
        if (value == null || !value.equals("true")) {
            throw new RuntimeException("attach.test property not set");
        }
        System.out.println(" - attach.test property set as expected");

        // Test 1a - read the agent properties from the target VM.
        // By default, the agent property contains "sun.java.command",
        // "sun.jvm.flags", and "sun.jvm.args".
        // Just sanity check - make sure not empty.
        System.out.println(" - Test: agent properties in target VM");
        props = vm.getAgentProperties();
        if (props == null || props.size() == 0) {
            throw new RuntimeException("Agent properties is empty");
        }
        System.out.println(" - agent properties non-empty as expected");

        // Test 2 - attempt to load an agent that does not exist
        System.out.println(" - Test: Load an agent that does not exist");
        try {
            vm.loadAgent("SilverBullet.jar");
        } catch (AgentLoadException x) {
            System.out.println(" - AgentLoadException thrown as expected!");
        }

        // Test 3 - load an "bad" agent (agentmain throws an exception)
        System.out.println(" - Test: Load a bad agent");
        System.out.println("INFO: This test will cause error messages "
            + "to appear in the application log about SilverBullet.jar "
            + "not being found and an agent failing to start.");
        try {
            vm.loadAgent(badagent);
            throw new RuntimeException(
                "AgentInitializationException not thrown as expected!");
        } catch (AgentInitializationException x) {
            System.out.println(
                " - AgentInitializationException thrown as expected!");
        }

        // Test 4 - detach from the VM and attempt a load (should throw IOE)
        System.out.println(" - Test: Detach from VM");
        System.out.println("INFO: This test will cause error messages "
            + "to appear in the application log about a BadAgent including "
            + "a RuntimeException and an InvocationTargetException.");
        vm.detach();
        try {
            vm.loadAgent(agent);
            throw new RuntimeException("loadAgent did not throw an exception!!");
        } catch (IOException ioe) {
            System.out.println(" - IOException as expected");
        }

        // Test 5 - functional "end-to-end" test.
        // Create a listener socket. Load Agent.jar into the target VM passing
        // it the port number of our listener. When agent loads it should connect
        // back to the tool.

        System.out.println(" - Re-attaching to application ...");
        vm = VirtualMachine.attach(pid);

        System.out.println(" - Test: End-to-end connection with agent");

        ServerSocket ss = new ServerSocket(0);
        int port = ss.getLocalPort();

        System.out.println(" - Loading Agent.jar into target VM ...");
        vm.loadAgent(agent, Integer.toString(port));

        System.out.println(" - Waiting for agent to connect back to tool ...");
        Socket s = ss.accept();
        System.out.println(" - Connected to agent.");

        // Test 5b - functional "end-to-end" test.
        // Now with an agent that does redefine.

        System.out.println(" - Re-attaching to application ...");
        vm = VirtualMachine.attach(pid);

        System.out.println(" - Test: End-to-end connection with RedefineAgent");

        ServerSocket ss2 = new ServerSocket(0);
        int port2 = ss2.getLocalPort();

        System.out.println(" - Loading RedefineAgent.jar into target VM ...");
        vm.loadAgent(redefineagent, Integer.toString(port2));

        System.out.println(" - Waiting for RedefineAgent to connect back to tool ...");
        Socket s2 = ss2.accept();
        System.out.println(" - Connected to RedefineAgent.");

        // Test 6 - list method should list the target VM
        System.out.println(" - Test: VirtualMachine.list");
        List<VirtualMachineDescriptor> l = VirtualMachine.list();
        if (!l.isEmpty()) {
            boolean found = false;
            for (VirtualMachineDescriptor vmd: l) {
                if (vmd.id().equals(pid)) {
                    found = true;
                    break;
                }
            }
            if (found) {
                System.out.println(" - " + pid + " found.");
            } else {
                throw new RuntimeException(pid + " not found in VM list");
            }
        }

        // test 7 - basic hashCode/equals tests
        System.out.println(" - Test: hashCode/equals");

        VirtualMachine vm1 = VirtualMachine.attach(pid);
        VirtualMachine vm2 = VirtualMachine.attach(pid);
        if (!vm1.equals(vm2)) {
            throw new RuntimeException("virtual machines are not equal");
        }
        if (vm.hashCode() != vm.hashCode()) {
            throw new RuntimeException("virtual machine hashCodes not equal");
        }
        System.out.println(" - hashCode/equals okay");

        // ---
        System.out.println(" - Cleaning up...");
        s.close();
        ss.close();
        s2.close();
        ss2.close();
    }
}