void ContextBuilder::addBaseType( KDevelop::BaseClassInstance base, BaseSpecifierAST *node ) {
  DUChainWriteLocker lock(DUChain::lock());

  addImportedContexts(); //Make sure the template-contexts are imported first, before any parent-class contexts.

  Q_ASSERT(currentContext()->type() == DUContext::Class);
  AbstractType::Ptr baseClass = base.baseClass.abstractType();
  IdentifiedType* idType = dynamic_cast<IdentifiedType*>(baseClass.unsafeData());
  Declaration* idDecl = 0;
  if( idType && (idDecl = idType->declaration(currentContext()->topContext())) ) {
    DUContext* ctx = idDecl->logicalInternalContext(currentContext()->topContext());
    if(ctx) {
      currentContext()->addImportedParentContext( ctx );
    }else{
      currentContext()->addIndirectImport( DUContext::Import(idType->declarationId()) );
      QString text = i18n("Could not resolve base class, adding it indirectly: %1", (base.baseClass ? base.baseClass.abstractType()->toString() : QString()));
      lock.unlock();
      createUserProblem(node, text);
    }
  } else if( !baseClass.cast<DelayedType>() ) {
    QString text = i18n("Invalid base class: %1", (base.baseClass ? base.baseClass.abstractType()->toString() : QString()));
    lock.unlock();
    createUserProblem(node, text);
  }
}
AbstractType::Ptr binaryOperatorReturnType(AbstractType::Ptr left, AbstractType::Ptr right, int tokenKind) {

  if(!left || !right)
    return AbstractType::Ptr();

  IntegralType* leftIntegral = dynamic_cast<IntegralType*>(left.unsafeData());
  IntegralType* rightIntegral = dynamic_cast<IntegralType*>(right.unsafeData());
  PointerType* leftPointer = dynamic_cast<PointerType*>(right.unsafeData());

  AbstractType::Ptr ret;

  //Constantly evaluate integral expressions
  ConstantIntegralType* leftConstantIntegral = dynamic_cast<ConstantIntegralType*>(left.unsafeData());
  ConstantIntegralType* rightConstantIntegral = dynamic_cast<ConstantIntegralType*>(right.unsafeData());

  if(leftIntegral && rightIntegral) {
    if(tokenKind == '+' || tokenKind == '-' || tokenKind == '*' || tokenKind == '/' || tokenKind == '%' || tokenKind == '^' || tokenKind == '&' || tokenKind == '|' || tokenKind == '~' || tokenKind == Token_shift) {
      if(moreExpressiveThan(leftIntegral, rightIntegral))
        ret = left;
      else
        ret = right;
    }

    if(tokenKind == '<' || tokenKind == '>' || tokenKind == Token_eq || tokenKind == Token_not_eq || tokenKind == Token_leq || tokenKind == Token_geq || tokenKind == Token_not_eq || tokenKind == Token_and || tokenKind == Token_or)
      ret = AbstractType::Ptr(new IntegralType(IntegralType::TypeBoolean));
  }

  if(leftPointer && rightIntegral && (tokenKind == '+' || tokenKind == '-'))
    ret = left;

  IntegralType* retIntegral = dynamic_cast<IntegralType*>(ret.unsafeData());

  ///We have determined the resulting type now. If both sides are constant, also evaluate the resulting value.
  if(ret && retIntegral && leftConstantIntegral && rightConstantIntegral) {
    switch( retIntegral->dataType() ) {
      case IntegralType::TypeFloat:
      {
        ConstantBinaryExpressionEvaluator<float> evaluator( retIntegral->dataType(), retIntegral->modifiers(), tokenKind, leftConstantIntegral, rightConstantIntegral );
        return evaluator.createType();
      }
      case IntegralType::TypeDouble:
      {
        ConstantBinaryExpressionEvaluator<double> evaluator( retIntegral->dataType(), retIntegral->modifiers(), tokenKind, leftConstantIntegral, rightConstantIntegral );
        return evaluator.createType();
      }
      default:
        if( leftConstantIntegral->modifiers() & AbstractType::UnsignedModifier ) {
          ConstantBinaryExpressionEvaluator<quint64> evaluator( retIntegral->dataType(), retIntegral->modifiers(), tokenKind, leftConstantIntegral, rightConstantIntegral);
          return evaluator.createType();
        } else {
          ConstantBinaryExpressionEvaluator<qint64> evaluator( retIntegral->dataType(), retIntegral->modifiers(), tokenKind, leftConstantIntegral, rightConstantIntegral);
          return evaluator.createType();
        }
        break;
    }
  }
  return ret;
}