private ModelReference<?> mapSubject(ModelReference<?> subject, ModelPath targetPath) {
   if (subject.getPath() == null) {
     return subject.inScope(targetPath);
   } else {
     return subject.withPath(targetPath.descendant(subject.getPath()));
   }
 }
 private void mapInputs(List<ModelReference<?>> inputs, ModelPath targetPath) {
   for (int i = 0; i < inputs.size(); i++) {
     ModelReference<?> input = inputs.get(i);
     if (input.getPath() != null) {
       inputs.set(i, input.withPath(targetPath.descendant(input.getPath())));
     } else {
       inputs.set(i, input.inScope(ModelPath.ROOT));
     }
   }
 }
 public RegistrationAction(
     ModelType<? extends ComponentSpec> publicType,
     ModelType<? extends BaseComponentSpec> implementationType,
     Set<Class<?>> internalViews,
     ModelRuleDescriptor descriptor) {
   super(
       ModelReference.of(ComponentSpecFactory.class),
       descriptor,
       ModelReference.of("serviceRegistry", ServiceRegistry.class),
       ModelReference.of("projectIdentifier", ProjectIdentifier.class),
       ModelReference.of("sources", ProjectSourceSet.class));
   this.publicType = publicType;
   this.implementationType = implementationType;
   this.internalViews = internalViews;
 }
 @Override
 public List<ModelReference<?>> getInputs() {
   return ImmutableList.<ModelReference<?>>builder()
       .add(ModelReference.of(ITaskFactory.class))
       .addAll(super.getInputs())
       .build();
 }
  private <R, S extends BinarySpec> ExtractedModelRule createRegistration(
      MethodRuleDefinition<R, ?> ruleDefinition) {
    try {
      RuleMethodDataCollector dataCollector = new RuleMethodDataCollector();
      verifyMethodSignature(dataCollector, ruleDefinition);

      final Class<S> binaryType = dataCollector.getParameterType(BinarySpec.class);
      final BinaryTaskRule<R, S> binaryTaskRule =
          new BinaryTaskRule<R, S>(binaryType, ruleDefinition);
      return new ExtractedModelAction(
          ModelActionRole.Defaults,
          ImmutableList.of(ComponentModelBasePlugin.class),
          DirectNodeNoInputsModelAction.of(
              ModelReference.of("binaries"),
              new SimpleModelRuleDescriptor("binaries*.create()"),
              new Action<MutableModelNode>() {
                @Override
                public void execute(MutableModelNode modelNode) {
                  modelNode.applyToAllLinks(ModelActionRole.Finalize, binaryTaskRule);
                }
              }));
    } catch (InvalidModelException e) {
      throw invalidModelRule(ruleDefinition, e);
    }
  }
  @Override
  public Multimap<ModelActionRole, ModelAction> getActions(
      ModelReference<?> subject, ModelRuleDescriptor descriptor) {
    return ImmutableSetMultimap.<ModelActionRole, ModelAction>builder()
        .put(
            ModelActionRole.Discover,
            DirectNodeInputUsingModelAction.of(
                subject,
                descriptor,
                Arrays.<ModelReference<?>>asList(
                    ModelReference.of(ManagedProxyFactory.class),
                    ModelReference.of(TypeConverter.class)),
                new BiAction<MutableModelNode, List<ModelView<?>>>() {
                  @Override
                  public void execute(MutableModelNode modelNode, List<ModelView<?>> modelViews) {
                    ManagedProxyFactory proxyFactory =
                        getInstance(modelViews.get(0), ManagedProxyFactory.class);
                    TypeConverter typeConverter = getInstance(modelViews, 1, TypeConverter.class);
                    for (StructSchema<?> viewSchema : bindings.getAllViewSchemas()) {
                      addProjection(modelNode, viewSchema, proxyFactory, typeConverter);
                    }
                  }
                }))
        .put(
            ModelActionRole.Create,
            DirectNodeInputUsingModelAction.of(
                subject,
                descriptor,
                Arrays.<ModelReference<?>>asList(
                    ModelReference.of(ModelSchemaStore.class),
                    ModelReference.of(NodeInitializerRegistry.class)),
                new BiAction<MutableModelNode, List<ModelView<?>>>() {
                  @Override
                  public void execute(MutableModelNode modelNode, List<ModelView<?>> modelViews) {
                    ModelSchemaStore schemaStore =
                        getInstance(modelViews, 0, ModelSchemaStore.class);
                    NodeInitializerRegistry nodeInitializerRegistry =
                        getInstance(modelViews, 1, NodeInitializerRegistry.class);

                    addPropertyLinks(modelNode, schemaStore, nodeInitializerRegistry);
                    initializePrivateData(modelNode);
                  }
                }))
        .build();
  }
 @Override
 protected List<ModelReference<?>> withImplicitInputs(List<? extends ModelReference<?>> inputs) {
   List<ModelReference<?>> allInputs =
       new ArrayList<ModelReference<?>>(inputs.size() + implicitInputs.size());
   allInputs.addAll(inputs);
   for (ModelProperty<?> property : implicitInputs) {
     ManagedInstance value = (ManagedInstance) values.get(property.getName());
     allInputs.add(ModelReference.of(value.getBackingNode().getPath()));
   }
   return allInputs;
 }
  private <T> void registerAction(
      final ModelPath modelPath,
      final Class<T> viewType,
      final ModelRuleDescriptor descriptor,
      final ModelActionRole role,
      final Closure<?> closure) {
    final ModelReference<T> reference = ModelReference.of(modelPath, viewType);
    modelRegistry.configure(
        ModelActionRole.DefineRules,
        DirectNodeNoInputsModelAction.of(
            reference,
            descriptor,
            new Action<MutableModelNode>() {
              @Override
              public void execute(MutableModelNode mutableModelNode) {
                InputReferences inputs = inputPathsExtractor.transform(closure);
                List<String> absolutePaths = inputs.getAbsolutePaths();
                List<Integer> absolutePathLineNumbers = inputs.getAbsolutePathLineNumbers();
                final List<PotentialInput> potentialInputs =
                    Lists.newArrayListWithCapacity(absolutePaths.size());
                List<ModelReference<?>> actualInputs =
                    Lists.newArrayListWithCapacity(potentialInputs.size());

                for (int i = 0; i < absolutePaths.size(); i++) {
                  String description = String.format("@ line %d", absolutePathLineNumbers.get(i));
                  String path = absolutePaths.get(i);
                  potentialInputs.add(PotentialInput.absoluteInput(path, actualInputs.size()));
                  actualInputs.add(ModelReference.untyped(ModelPath.path(path), description));
                }
                mutableModelNode.applyToSelf(
                    role,
                    InputUsingModelAction.of(
                        reference,
                        descriptor,
                        actualInputs,
                        new BiAction<T, List<ModelView<?>>>() {
                          @Override
                          public void execute(final T t, List<ModelView<?>> modelViews) {
                            ((TransformedClosure) closure)
                                .applyRuleInputs(new PotentialInputs(modelViews, potentialInputs));
                            ClosureBackedAction.execute(
                                t,
                                closure.rehydrate(
                                    null, closure.getThisObject(), closure.getThisObject()));
                          }
                        }));
              }
            }));
  }
  private void validateRuleMethod(
      MethodRuleDefinition<?, ?> ruleDefinition,
      Method ruleMethod,
      ValidationProblemCollector problems) {
    if (Modifier.isPrivate(ruleMethod.getModifiers())) {
      problems.add(ruleMethod, "A rule method cannot be private");
    }
    if (Modifier.isAbstract(ruleMethod.getModifiers())) {
      problems.add(ruleMethod, "A rule method cannot be abstract");
    }

    if (ruleMethod.getTypeParameters().length > 0) {
      problems.add(ruleMethod, "Cannot have type variables (i.e. cannot be a generic method)");
    }

    // TODO validations on method: synthetic, bridge methods, varargs, abstract, native
    ModelType<?> returnType = ModelType.returnType(ruleMethod);
    if (returnType.isRawClassOfParameterizedType()) {
      problems.add(
          ruleMethod,
          "Raw type "
              + returnType
              + " used for return type (all type parameters must be specified of parameterized type)");
    }

    for (int i = 0; i < ruleDefinition.getReferences().size(); i++) {
      ModelReference<?> reference = ruleDefinition.getReferences().get(i);
      if (reference.getType().isRawClassOfParameterizedType()) {
        problems.add(
            ruleMethod,
            "Raw type "
                + reference.getType()
                + " used for parameter "
                + (i + 1)
                + " (all type parameters must be specified of parameterized type)");
      }
      if (reference.getPath() != null) {
        try {
          ModelPath.validatePath(reference.getPath().toString());
        } catch (Exception e) {
          problems.add(
              ruleDefinition,
              "The declared model element path '"
                  + reference.getPath()
                  + "' used for parameter "
                  + (i + 1)
                  + " is not a valid path",
              e);
        }
      }
    }
  }
 @Override
 public List<? extends ModelReference<?>> getInputs() {
   return Collections.singletonList(ModelReference.of(NodeInitializerRegistry.class));
 }
  protected List<SimulinkSignal> getSignals(String rootName) {
    List<SimulinkSignal> signals = new ArrayList<SimulinkSignal>();

    // find all (top-level) connectors in the model or block
    Object[] foundConnectors =
        matlab.returningFeval(
            1, find_system, rootName, SearchDepth, 1, FindAll, "on", LineType, SimulinkType.signal);

    if ((foundConnectors != null) && (foundConnectors.length == 1)) {
      // handles (ids) of the connectors
      double[] connHandles = (double[]) foundConnectors[0];

      for (int i = 0; i < connHandles.length; i++) {
        double connHandle = connHandles[i];
        double srcConnHandle = connHandle;

        double[] lineChildren =
            ((double[]) (matlab.returningFeval(1, get_param, connHandle, "LineChildren"))[0]);

        // Signals with children are not handled (directly). This is the case when a
        // block has more than one outgoing signal.
        if (lineChildren.length > 0) {
          continue;
        }

        double lineParent =
            ((double[]) (matlab.returningFeval(1, get_param, connHandle, "LineParent"))[0])[0];

        // If lineParent has another value than -1.0 the source block has more than one outgoing
        // signal.
        // The id of the source block can now only be get by the root line parent...
        if (lineParent != -1.0) {
          // ...Started by the source block every signal fork creates line children for the current
          // signal.
          // These children can also have children of their own (if they have a fork).
          // So to get the source block we need to get the source block of the root line parent.
          double rootLineParent = lineParent;
          do {
            srcConnHandle = rootLineParent;
            rootLineParent =
                ((double[]) (matlab.returningFeval(1, get_param, rootLineParent, "LineParent"))[0])
                    [0];
          } while (rootLineParent != -1.0);
        }

        String srcBlockName = (String) matlab.returningFeval(get_param, srcConnHandle, SrcBlock);
        String srcQualifiedBlockName = rootName + "/" + srcBlockName;
        String srcBlockType =
            (String) matlab.returningFeval(get_param, srcQualifiedBlockName, BlockType);
        String srcPortNumber = (String) matlab.returningFeval(get_param, srcConnHandle, SrcPort);

        String dstBlockName = (String) matlab.returningFeval(get_param, connHandle, DstBlock);
        String dstQualifiedBlockName = rootName + "/" + dstBlockName;
        String dstBlockType =
            (String) matlab.returningFeval(get_param, dstQualifiedBlockName, BlockType);
        String dstPortNumber = (String) matlab.returningFeval(get_param, connHandle, DstPort);

        SimulinkSignal signal =
            new SimulinkSignal(
                srcQualifiedBlockName,
                Integer.valueOf(srcPortNumber),
                dstQualifiedBlockName,
                Integer.valueOf(dstPortNumber),
                srcConnHandle);

        // ====== Handle Source ======= //

        if (srcBlockType.equals(SubSystem.toString())) {
          // src block is a sub system
          String srcPortName = getPortNameByNumber(srcQualifiedBlockName, srcPortNumber, false);
          signal.setSrcPortName(srcPortName);
        } else if (srcBlockType.equals(ModelReference.toString())) {
          // src block is a model reference
          String referencedModelName =
              (String) matlab.returningFeval(get_param, srcQualifiedBlockName, ModelName);
          matlab.loadModel(referencedModelName);

          String srcPortName = getPortNameByNumber(referencedModelName, srcPortNumber, false);
          signal.setSrcPortName(srcPortName);
        }

        // ====== Handle Destination ======= //

        if (dstBlockType.equals(SubSystem.toString())) {
          // dst block is a sub system
          String dstPortName = getPortNameByNumber(dstQualifiedBlockName, dstPortNumber, true);
          signal.setDstPortName(dstPortName);
        } else if (dstBlockType.equals(ModelReference.toString())) {
          // dst block is a model reference
          String referencedModelName =
              (String) matlab.returningFeval(get_param, dstQualifiedBlockName, ModelName);
          matlab.loadModel(referencedModelName);

          String dstPortName = getPortNameByNumber(referencedModelName, dstPortNumber, true);
          signal.setDstPortName(dstPortName);
        }

        signals.add(signal);
      }
    }

    return signals;
  }
public class DefaultNodeInitializerRegistry implements NodeInitializerRegistry {
  public static final ModelReference<NodeInitializerRegistry> DEFAULT_REFERENCE =
      ModelReference.of("nodeInitializerRegistry", NodeInitializerRegistry.class);

  private final LoadingCache<NodeInitializerContext<?>, NodeInitializer> cache =
      CacheBuilder.newBuilder()
          .weakValues()
          .build(
              new CacheLoader<NodeInitializerContext<?>, NodeInitializer>() {
                @Override
                public NodeInitializer load(NodeInitializerContext<?> context) throws Exception {
                  return extractNodeInitializer(context);
                }
              });

  private final List<NodeInitializerExtractionStrategy> allStrategies;
  private final List<NodeInitializerExtractionStrategy> additionalStrategies;
  private final ModelSchemaStore schemaStore;

  public DefaultNodeInitializerRegistry(
      ModelSchemaStore schemaStore, StructBindingsStore structBindingsStore) {
    this.schemaStore = schemaStore;
    this.allStrategies =
        Lists.newArrayList(
            new ModelSetNodeInitializerExtractionStrategy(),
            new SpecializedMapNodeInitializerExtractionStrategy(),
            new ModelMapNodeInitializerExtractionStrategy(),
            new ScalarCollectionNodeInitializerExtractionStrategy(),
            new ManagedImplStructNodeInitializerExtractionStrategy(structBindingsStore));
    additionalStrategies = Lists.newArrayList();
  }

  private ModelTypeInitializationException canNotConstructTypeException(
      NodeInitializerContext<?> context) {
    ImmutableSortedSet.Builder<ModelType<?>> constructibleTypes =
        ImmutableSortedSet.orderedBy(ModelTypes.displayOrder());
    for (NodeInitializerExtractionStrategy extractor : additionalStrategies) {
      for (ModelType<?> constructibleType : extractor.supportedTypes()) {
        if (context.getConstraints().isSatisfiedBy(constructibleType)) {
          constructibleTypes.add(constructibleType);
        }
      }
    }
    return new ModelTypeInitializationException(
        context, schemaStore, ScalarTypes.TYPES, constructibleTypes.build());
  }

  @Override
  public NodeInitializer getNodeInitializer(NodeInitializerContext<?> nodeInitializerContext) {
    try {
      return cache.get(nodeInitializerContext);
    } catch (ExecutionException e) {
      throw UncheckedException.throwAsUncheckedException(e);
    } catch (UncheckedExecutionException e) {
      throw UncheckedException.throwAsUncheckedException(e.getCause());
    }
  }

  private <T> NodeInitializer extractNodeInitializer(NodeInitializerContext<T> context) {
    ModelSchema<T> schema = schemaStore.getSchema(context.getModelType());
    for (NodeInitializerExtractionStrategy extractor : allStrategies) {
      NodeInitializer nodeInitializer = extractor.extractNodeInitializer(schema, context);
      if (nodeInitializer != null) {
        return nodeInitializer;
      }
    }
    throw canNotConstructTypeException(context);
  }

  @Override
  public void ensureHasInitializer(NodeInitializerContext<?> nodeInitializer) {
    getNodeInitializer(nodeInitializer);
  }

  @Override
  public void registerStrategy(NodeInitializerExtractionStrategy strategy) {
    allStrategies.add(0, strategy);
    additionalStrategies.add(0, strategy);
  }
}
 public BinaryTaskRule(Class<T> binaryType, MethodRuleDefinition<R, ?> ruleDefinition) {
   super(ModelReference.of(binaryType), binaryType, ruleDefinition);
 }