Package org.eclipse.jdt.internal.compiler.ast

Examples of org.eclipse.jdt.internal.compiler.ast.Annotation


    addNewUnits(logger, units);
  }

  private Object createAnnotationInstance(TreeLogger logger,
      Expression expression) {
    Annotation annotation = (Annotation) expression;

    // Determine the annotation class
    TypeBinding resolvedType = annotation.resolvedType;
    Class<?> classLiteral = getClassLiteral(logger, resolvedType);
    if (classLiteral == null) {
      return null;
    }

    Class<? extends java.lang.annotation.Annotation> clazz = classLiteral.asSubclass(java.lang.annotation.Annotation.class);

    // Build the map of identifiers to values.
    Map<String, Object> identifierToValue = new HashMap<String, Object>();
    for (MemberValuePair mvp : annotation.memberValuePairs()) {
      // Method name
      String identifier = String.valueOf(mvp.name);

      // Value
      Expression expressionValue = mvp.value;
View Full Code Here


    final int length = annotations.length;
    int visibleAnnotationsCounter = 0;
    int invisibleAnnotationsCounter = 0;

    for (int i = 0; i < length; i++) {
      Annotation annotation = annotations[i];
      if (annotation.isRuntimeInvisible()) {
        invisibleAnnotationsCounter++;
      } else if (annotation.isRuntimeVisible()) {
        visibleAnnotationsCounter++;
      }
    }

    int annotationAttributeOffset = this.contentsOffset;
    int constantPOffset = this.constantPool.currentOffset;
    int constantPoolIndex = this.constantPool.currentIndex;
    if (invisibleAnnotationsCounter != 0) {
      if (this.contentsOffset + 10 >= this.contents.length) {
        resizeContents(10);
      }
      int runtimeInvisibleAnnotationsAttributeNameIndex =
        this.constantPool.literalIndex(AttributeNamesConstants.RuntimeInvisibleAnnotationsName);
      this.contents[this.contentsOffset++] = (byte) (runtimeInvisibleAnnotationsAttributeNameIndex >> 8);
      this.contents[this.contentsOffset++] = (byte) runtimeInvisibleAnnotationsAttributeNameIndex;
      int attributeLengthOffset = this.contentsOffset;
      this.contentsOffset += 4; // leave space for the attribute length

      int annotationsLengthOffset = this.contentsOffset;
      this.contentsOffset += 2; // leave space for the annotations length

      int counter = 0;
      loop: for (int i = 0; i < length; i++) {
        if (invisibleAnnotationsCounter == 0) break loop;
        Annotation annotation = annotations[i];
        if (annotation.isRuntimeInvisible()) {
          int currentAnnotationOffset = this.contentsOffset;
          generateAnnotation(annotation, currentAnnotationOffset);
          invisibleAnnotationsCounter--;
          if (this.contentsOffset != currentAnnotationOffset) {
            counter++;
          }
        }
      }
      if (counter != 0) {
        this.contents[annotationsLengthOffset++] = (byte) (counter >> 8);
        this.contents[annotationsLengthOffset++] = (byte) counter;

        int attributeLength = this.contentsOffset - attributeLengthOffset - 4;
        this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 24);
        this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 16);
        this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 8);
        this.contents[attributeLengthOffset++] = (byte) attributeLength;
        attributesNumber++;
      } else {
        this.contentsOffset = annotationAttributeOffset;
        // reset the constant pool to its state before the clinit
        this.constantPool.resetForAttributeName(AttributeNamesConstants.RuntimeInvisibleAnnotationsName, constantPoolIndex, constantPOffset);
      }
    }

    annotationAttributeOffset = this.contentsOffset;
    constantPOffset = this.constantPool.currentOffset;
    constantPoolIndex = this.constantPool.currentIndex;
    if (visibleAnnotationsCounter != 0) {
      if (this.contentsOffset + 10 >= this.contents.length) {
        resizeContents(10);
      }
      int runtimeVisibleAnnotationsAttributeNameIndex =
        this.constantPool.literalIndex(AttributeNamesConstants.RuntimeVisibleAnnotationsName);
      this.contents[this.contentsOffset++] = (byte) (runtimeVisibleAnnotationsAttributeNameIndex >> 8);
      this.contents[this.contentsOffset++] = (byte) runtimeVisibleAnnotationsAttributeNameIndex;
      int attributeLengthOffset = this.contentsOffset;
      this.contentsOffset += 4; // leave space for the attribute length

      int annotationsLengthOffset = this.contentsOffset;
      this.contentsOffset += 2; // leave space for the annotations length

      int counter = 0;
      loop: for (int i = 0; i < length; i++) {
        if (visibleAnnotationsCounter == 0) break loop;
        Annotation annotation = annotations[i];
        if (annotation.isRuntimeVisible()) {
          visibleAnnotationsCounter--;
          int currentAnnotationOffset = this.contentsOffset;
          generateAnnotation(annotation, currentAnnotationOffset);
          if (this.contentsOffset != currentAnnotationOffset) {
            counter++;
View Full Code Here

    for (int i = 0; i < argumentsLength; i++) {
      Argument argument = arguments[i];
      Annotation[] annotations = argument.annotations;
      if (annotations != null) {
        for (int j = 0, max2 = annotations.length; j < max2; j++) {
          Annotation annotation = annotations[j];
          if (annotation.isRuntimeInvisible()) {
            annotationsCounters[i][INVISIBLE_INDEX]++;
            invisibleParametersAnnotationsCounter++;
          } else if (annotation.isRuntimeVisible()) {
            annotationsCounters[i][VISIBLE_INDEX]++;
            visibleParametersAnnotationsCounter++;
          }
        }
      }
    }
    int attributesNumber = 0;
    int annotationAttributeOffset = this.contentsOffset;
    if (invisibleParametersAnnotationsCounter != 0) {
      int globalCounter = 0;
      if (this.contentsOffset + 7 >= this.contents.length) {
        resizeContents(7);
      }
      int attributeNameIndex =
        this.constantPool.literalIndex(AttributeNamesConstants.RuntimeInvisibleParameterAnnotationsName);
      this.contents[this.contentsOffset++] = (byte) (attributeNameIndex >> 8);
      this.contents[this.contentsOffset++] = (byte) attributeNameIndex;
      int attributeLengthOffset = this.contentsOffset;
      this.contentsOffset += 4; // leave space for the attribute length

      this.contents[this.contentsOffset++] = (byte) argumentsLength;
      for (int i = 0; i < argumentsLength; i++) {
        if (this.contentsOffset + 2 >= this.contents.length) {
          resizeContents(2);
        }
        if (invisibleParametersAnnotationsCounter == 0) {
          this.contents[this.contentsOffset++] = (byte) 0;
          this.contents[this.contentsOffset++] = (byte) 0;
        } else {
          final int numberOfInvisibleAnnotations = annotationsCounters[i][INVISIBLE_INDEX];
          int invisibleAnnotationsOffset = this.contentsOffset;
          // leave space for number of annotations
          this.contentsOffset += 2;
          int counter = 0;
          if (numberOfInvisibleAnnotations != 0) {
            Argument argument = arguments[i];
            Annotation[] annotations = argument.annotations;
            for (int j = 0, max = annotations.length; j < max; j++) {
              Annotation annotation = annotations[j];
              if (annotation.isRuntimeInvisible()) {
                int currentAnnotationOffset = this.contentsOffset;
                generateAnnotation(annotation, currentAnnotationOffset);
                if (this.contentsOffset != currentAnnotationOffset) {
                  counter++;
                  globalCounter++;
                }
                invisibleParametersAnnotationsCounter--;
              }
            }
          }
          this.contents[invisibleAnnotationsOffset++] = (byte) (counter >> 8);
          this.contents[invisibleAnnotationsOffset] = (byte) counter;
        }
      }
      if (globalCounter != 0) {
        int attributeLength = this.contentsOffset - attributeLengthOffset - 4;
        this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 24);
        this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 16);
        this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 8);
        this.contents[attributeLengthOffset++] = (byte) attributeLength;
        attributesNumber++;
      } else {
        // if globalCounter is 0, this means that the code generation for all visible annotations failed
        this.contentsOffset = annotationAttributeOffset;
      }
    }
    if (visibleParametersAnnotationsCounter != 0) {
      int globalCounter = 0;
      if (this.contentsOffset + 7 >= this.contents.length) {
        resizeContents(7);
      }
      int attributeNameIndex =
        this.constantPool.literalIndex(AttributeNamesConstants.RuntimeVisibleParameterAnnotationsName);
      this.contents[this.contentsOffset++] = (byte) (attributeNameIndex >> 8);
      this.contents[this.contentsOffset++] = (byte) attributeNameIndex;
      int attributeLengthOffset = this.contentsOffset;
      this.contentsOffset += 4; // leave space for the attribute length

      this.contents[this.contentsOffset++] = (byte) argumentsLength;
      for (int i = 0; i < argumentsLength; i++) {
        if (this.contentsOffset + 2 >= this.contents.length) {
          resizeContents(2);
        }
        if (visibleParametersAnnotationsCounter == 0) {
          this.contents[this.contentsOffset++] = (byte) 0;
          this.contents[this.contentsOffset++] = (byte) 0;
        } else {
          final int numberOfVisibleAnnotations = annotationsCounters[i][VISIBLE_INDEX];
          int visibleAnnotationsOffset = this.contentsOffset;
          // leave space for number of annotations
          this.contentsOffset += 2;
          int counter = 0;
          if (numberOfVisibleAnnotations != 0) {
            Argument argument = arguments[i];
            Annotation[] annotations = argument.annotations;
            for (int j = 0, max = annotations.length; j < max; j++) {
              Annotation annotation = annotations[j];
              if (annotation.isRuntimeVisible()) {
                int currentAnnotationOffset = this.contentsOffset;
                generateAnnotation(annotation, currentAnnotationOffset);
                if (this.contentsOffset != currentAnnotationOffset) {
                  counter++;
                  globalCounter++;
View Full Code Here

* (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=89807)
*/
private boolean hasDeprecatedAnnotation(Annotation[] annotations) {
  if (annotations != null) {
    for (int i = 0, length = annotations.length; i < length; i++) {
      Annotation annotation = annotations[i];
      if (CharOperation.equals(annotation.type.getLastToken(), TypeConstants.JAVA_LANG_DEPRECATED[2])) {
        return true;
      }
    }
  }
View Full Code Here

    unresolvedTypes.clear();
  }

  private Object createAnnotationInstance(TreeLogger logger,
      Expression expression) {
    Annotation annotation = (Annotation) expression;

    // Determine the annotation class
    TypeBinding resolvedType = annotation.resolvedType;
    Class<?> classLiteral = getClassLiteral(logger, resolvedType);
    if (classLiteral == null) {
      return null;
    }

    Class<? extends java.lang.annotation.Annotation> clazz = classLiteral.asSubclass(java.lang.annotation.Annotation.class);

    // Build the map of identifiers to values.
    Map<String, Object> identifierToValue = new HashMap<String, Object>();
    for (MemberValuePair mvp : annotation.memberValuePairs()) {
      // Method name
      String identifier = String.valueOf(mvp.name);

      // Value
      Expression expressionValue = mvp.value;
View Full Code Here

    addNewUnits(logger, units);
  }

  private Object createAnnotationInstance(TreeLogger logger,
      Expression expression) {
    Annotation annotation = (Annotation) expression;

    // Determine the annotation class
    TypeBinding resolvedType = annotation.resolvedType;
    Class<?> classLiteral = getClassLiteral(logger, resolvedType);
    if (classLiteral == null) {
      return null;
    }

    Class<? extends java.lang.annotation.Annotation> clazz = classLiteral.asSubclass(java.lang.annotation.Annotation.class);

    // Build the map of identifiers to values.
    Map<String, Object> identifierToValue = new HashMap<String, Object>();
    for (MemberValuePair mvp : annotation.memberValuePairs()) {
      // Method name
      String identifier = String.valueOf(mvp.name);

      // Value
      Expression expressionValue = mvp.value;
View Full Code Here

    int attributesNumber = 0;
    final int length = annotations.length;
    int visibleAnnotationsCounter = 0;
    int invisibleAnnotationsCounter = 0;
    for (int i = 0; i < length; i++) {
      Annotation annotation;
      if ((annotation = annotations[i].getPersistibleAnnotation()) == null) continue; // already packaged into container.
      long annotationMask = annotation.resolvedType != null ? annotation.resolvedType.getAnnotationTagBits() & TagBits.AnnotationTargetMASK : 0;
      if (annotationMask != 0 && (annotationMask & targetMask) == 0) continue;
      if (annotation.isRuntimeInvisible() || annotation.isRuntimeTypeInvisible()) {
        invisibleAnnotationsCounter++;
      } else if (annotation.isRuntimeVisible() || annotation.isRuntimeTypeVisible()) {
        visibleAnnotationsCounter++;
      }
    }

    int annotationAttributeOffset = this.contentsOffset;
    int constantPOffset = this.constantPool.currentOffset;
    int constantPoolIndex = this.constantPool.currentIndex;
    if (invisibleAnnotationsCounter != 0) {
      if (this.contentsOffset + 10 >= this.contents.length) {
        resizeContents(10);
      }
      int runtimeInvisibleAnnotationsAttributeNameIndex =
        this.constantPool.literalIndex(AttributeNamesConstants.RuntimeInvisibleAnnotationsName);
      this.contents[this.contentsOffset++] = (byte) (runtimeInvisibleAnnotationsAttributeNameIndex >> 8);
      this.contents[this.contentsOffset++] = (byte) runtimeInvisibleAnnotationsAttributeNameIndex;
      int attributeLengthOffset = this.contentsOffset;
      this.contentsOffset += 4; // leave space for the attribute length

      int annotationsLengthOffset = this.contentsOffset;
      this.contentsOffset += 2; // leave space for the annotations length

      int counter = 0;
      loop: for (int i = 0; i < length; i++) {
        if (invisibleAnnotationsCounter == 0) break loop;
        Annotation annotation;
        if ((annotation = annotations[i].getPersistibleAnnotation()) == null) continue; // already packaged into container.
        long annotationMask = annotation.resolvedType != null ? annotation.resolvedType.getAnnotationTagBits() & TagBits.AnnotationTargetMASK : 0;
        if (annotationMask != 0 && (annotationMask & targetMask) == 0) continue;
        if (annotation.isRuntimeInvisible() || annotation.isRuntimeTypeInvisible()) {
          int currentAnnotationOffset = this.contentsOffset;
          generateAnnotation(annotation, currentAnnotationOffset);
          invisibleAnnotationsCounter--;
          if (this.contentsOffset != currentAnnotationOffset) {
            counter++;
          }
        }
      }
      if (counter != 0) {
        this.contents[annotationsLengthOffset++] = (byte) (counter >> 8);
        this.contents[annotationsLengthOffset++] = (byte) counter;

        int attributeLength = this.contentsOffset - attributeLengthOffset - 4;
        this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 24);
        this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 16);
        this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 8);
        this.contents[attributeLengthOffset++] = (byte) attributeLength;
        attributesNumber++;
      } else {
        this.contentsOffset = annotationAttributeOffset;
        // reset the constant pool to its state before the clinit
        this.constantPool.resetForAttributeName(AttributeNamesConstants.RuntimeInvisibleAnnotationsName, constantPoolIndex, constantPOffset);
      }
    }

    annotationAttributeOffset = this.contentsOffset;
    constantPOffset = this.constantPool.currentOffset;
    constantPoolIndex = this.constantPool.currentIndex;
    if (visibleAnnotationsCounter != 0) {
      if (this.contentsOffset + 10 >= this.contents.length) {
        resizeContents(10);
      }
      int runtimeVisibleAnnotationsAttributeNameIndex =
        this.constantPool.literalIndex(AttributeNamesConstants.RuntimeVisibleAnnotationsName);
      this.contents[this.contentsOffset++] = (byte) (runtimeVisibleAnnotationsAttributeNameIndex >> 8);
      this.contents[this.contentsOffset++] = (byte) runtimeVisibleAnnotationsAttributeNameIndex;
      int attributeLengthOffset = this.contentsOffset;
      this.contentsOffset += 4; // leave space for the attribute length

      int annotationsLengthOffset = this.contentsOffset;
      this.contentsOffset += 2; // leave space for the annotations length

      int counter = 0;
      loop: for (int i = 0; i < length; i++) {
        if (visibleAnnotationsCounter == 0) break loop;
        Annotation annotation;
        if ((annotation = annotations[i].getPersistibleAnnotation()) == null) continue; // already packaged into container.
        long annotationMask = annotation.resolvedType != null ? annotation.resolvedType.getAnnotationTagBits() & TagBits.AnnotationTargetMASK : 0;
        if (annotationMask != 0 && (annotationMask & targetMask) == 0) continue;
        if (annotation.isRuntimeVisible() || annotation.isRuntimeTypeVisible()) {
          visibleAnnotationsCounter--;
          int currentAnnotationOffset = this.contentsOffset;
          generateAnnotation(annotation, currentAnnotationOffset);
          if (this.contentsOffset != currentAnnotationOffset) {
            counter++;
View Full Code Here

    for (int i = 0; i < argumentsLength; i++) {
      Argument argument = arguments[i];
      Annotation[] annotations = argument.annotations;
      if (annotations != null) {
        for (int j = 0, max2 = annotations.length; j < max2; j++) {
          Annotation annotation;
          if ((annotation = annotations[j].getPersistibleAnnotation()) == null) continue; // already packaged into container.
          long annotationMask = annotation.resolvedType != null ? annotation.resolvedType.getAnnotationTagBits() & TagBits.AnnotationTargetMASK : 0;
          if (annotationMask != 0 && (annotationMask & TagBits.AnnotationForParameter) == 0) continue;
          if (annotation.isRuntimeInvisible()) {
            annotationsCounters[i][INVISIBLE_INDEX]++;
            invisibleParametersAnnotationsCounter++;
          } else if (annotation.isRuntimeVisible()) {
            annotationsCounters[i][VISIBLE_INDEX]++;
            visibleParametersAnnotationsCounter++;
          }
        }
      }
    }
    int attributesNumber = 0;
    int annotationAttributeOffset = this.contentsOffset;
    if (invisibleParametersAnnotationsCounter != 0) {
      int globalCounter = 0;
      if (this.contentsOffset + 7 >= this.contents.length) {
        resizeContents(7);
      }
      int attributeNameIndex =
        this.constantPool.literalIndex(AttributeNamesConstants.RuntimeInvisibleParameterAnnotationsName);
      this.contents[this.contentsOffset++] = (byte) (attributeNameIndex >> 8);
      this.contents[this.contentsOffset++] = (byte) attributeNameIndex;
      int attributeLengthOffset = this.contentsOffset;
      this.contentsOffset += 4; // leave space for the attribute length

      this.contents[this.contentsOffset++] = (byte) argumentsLength;
      for (int i = 0; i < argumentsLength; i++) {
        if (this.contentsOffset + 2 >= this.contents.length) {
          resizeContents(2);
        }
        if (invisibleParametersAnnotationsCounter == 0) {
          this.contents[this.contentsOffset++] = (byte) 0;
          this.contents[this.contentsOffset++] = (byte) 0;
        } else {
          final int numberOfInvisibleAnnotations = annotationsCounters[i][INVISIBLE_INDEX];
          int invisibleAnnotationsOffset = this.contentsOffset;
          // leave space for number of annotations
          this.contentsOffset += 2;
          int counter = 0;
          if (numberOfInvisibleAnnotations != 0) {
            Argument argument = arguments[i];
            Annotation[] annotations = argument.annotations;
            for (int j = 0, max = annotations.length; j < max; j++) {
              Annotation annotation;
              if ((annotation = annotations[j].getPersistibleAnnotation()) == null) continue; // already packaged into container.
              long annotationMask = annotation.resolvedType != null ? annotation.resolvedType.getAnnotationTagBits() & TagBits.AnnotationTargetMASK : 0;
              if (annotationMask != 0 && (annotationMask & TagBits.AnnotationForParameter) == 0) continue;
              if (annotation.isRuntimeInvisible()) {
                int currentAnnotationOffset = this.contentsOffset;
                generateAnnotation(annotation, currentAnnotationOffset);
                if (this.contentsOffset != currentAnnotationOffset) {
                  counter++;
                  globalCounter++;
                }
                invisibleParametersAnnotationsCounter--;
              }
            }
          }
          this.contents[invisibleAnnotationsOffset++] = (byte) (counter >> 8);
          this.contents[invisibleAnnotationsOffset] = (byte) counter;
        }
      }
      if (globalCounter != 0) {
        int attributeLength = this.contentsOffset - attributeLengthOffset - 4;
        this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 24);
        this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 16);
        this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 8);
        this.contents[attributeLengthOffset++] = (byte) attributeLength;
        attributesNumber++;
      } else {
        // if globalCounter is 0, this means that the code generation for all visible annotations failed
        this.contentsOffset = annotationAttributeOffset;
      }
    }
    if (visibleParametersAnnotationsCounter != 0) {
      int globalCounter = 0;
      if (this.contentsOffset + 7 >= this.contents.length) {
        resizeContents(7);
      }
      int attributeNameIndex =
        this.constantPool.literalIndex(AttributeNamesConstants.RuntimeVisibleParameterAnnotationsName);
      this.contents[this.contentsOffset++] = (byte) (attributeNameIndex >> 8);
      this.contents[this.contentsOffset++] = (byte) attributeNameIndex;
      int attributeLengthOffset = this.contentsOffset;
      this.contentsOffset += 4; // leave space for the attribute length

      this.contents[this.contentsOffset++] = (byte) argumentsLength;
      for (int i = 0; i < argumentsLength; i++) {
        if (this.contentsOffset + 2 >= this.contents.length) {
          resizeContents(2);
        }
        if (visibleParametersAnnotationsCounter == 0) {
          this.contents[this.contentsOffset++] = (byte) 0;
          this.contents[this.contentsOffset++] = (byte) 0;
        } else {
          final int numberOfVisibleAnnotations = annotationsCounters[i][VISIBLE_INDEX];
          int visibleAnnotationsOffset = this.contentsOffset;
          // leave space for number of annotations
          this.contentsOffset += 2;
          int counter = 0;
          if (numberOfVisibleAnnotations != 0) {
            Argument argument = arguments[i];
            Annotation[] annotations = argument.annotations;
            for (int j = 0, max = annotations.length; j < max; j++) {
              Annotation annotation;
              if ((annotation = annotations[j].getPersistibleAnnotation()) == null) continue; // already packaged into container.
              long annotationMask = annotation.resolvedType != null ? annotation.resolvedType.getAnnotationTagBits() & TagBits.AnnotationTargetMASK : 0;
              if (annotationMask != 0 && (annotationMask & TagBits.AnnotationForParameter) == 0) continue;
              if (annotation.isRuntimeVisible()) {
                int currentAnnotationOffset = this.contentsOffset;
                generateAnnotation(annotation, currentAnnotationOffset);
                if (this.contentsOffset != currentAnnotationOffset) {
                  counter++;
                  globalCounter++;
View Full Code Here

    this.contentsOffset = localContentsOffset;
    return 1;
  }
 
  private void generateTypeAnnotation(AnnotationContext annotationContext, int currentOffset) {
    Annotation annotation = annotationContext.annotation.getPersistibleAnnotation();
    if (annotation == null || annotation.resolvedType == null)
      return;
   
    int targetType = annotationContext.targetType;
View Full Code Here

* (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=89807)
*/
private boolean hasDeprecatedAnnotation(Annotation[] annotations) {
  if (annotations != null) {
    for (int i = 0, length = annotations.length; i < length; i++) {
      Annotation annotation = annotations[i];
      if (CharOperation.equals(annotation.type.getLastToken(), TypeConstants.JAVA_LANG_DEPRECATED[2])) {
        return true;
      }
    }
  }
View Full Code Here

TOP

Related Classes of org.eclipse.jdt.internal.compiler.ast.Annotation

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.